From b5c828fe4ee3f0942b2eda1dc5753e4ad6d38ea9 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 30 Nov 2021 23:01:22 +0100 Subject: [PATCH 001/245] [xml] Initial implementation of `core:encoding/xml`. A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). Features: - Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage. - Simple to understand and use. Small. Caveats: - We do NOT support HTML in this package, as that may or may not be valid XML. If it works, great. If it doesn't, that's not considered a bug. - We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences. - <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options. TODO: - Optional CDATA unboxing. - Optional `>`, ` `, ` ` and other escape substitution in tag bodies. - Test suite MAYBE: - XML writer? - Serialize/deserialize Odin types? --- core/encoding/xml/debug_print.odin | 73 ++ core/encoding/xml/example/xml_example.odin | 55 ++ core/encoding/xml/tokenizer.odin | 339 +++++++++ core/encoding/xml/xml_reader.odin | 651 ++++++++++++++++++ tests/core/Makefile | 17 +- tests/core/assets/xml/nl_NL-qt-ts.ts | 35 + tests/core/assets/xml/nl_NL-xliff-1.0.xliff | 38 + tests/core/assets/xml/nl_NL-xliff-2.0.xliff | 52 ++ tests/core/assets/xml/utf8.xml | 8 + tests/core/build.bat | 15 +- .../encoding/{ => json}/test_core_json.odin | 36 +- tests/core/encoding/xml/test_core_xml.odin | 264 +++++++ 12 files changed, 1553 insertions(+), 30 deletions(-) create mode 100644 core/encoding/xml/debug_print.odin create mode 100644 core/encoding/xml/example/xml_example.odin create mode 100644 core/encoding/xml/tokenizer.odin create mode 100644 core/encoding/xml/xml_reader.odin create mode 100644 tests/core/assets/xml/nl_NL-qt-ts.ts create mode 100644 tests/core/assets/xml/nl_NL-xliff-1.0.xliff create mode 100644 tests/core/assets/xml/nl_NL-xliff-2.0.xliff create mode 100644 tests/core/assets/xml/utf8.xml rename tests/core/encoding/{ => json}/test_core_json.odin (63%) create mode 100644 tests/core/encoding/xml/test_core_xml.odin diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin new file mode 100644 index 000000000..0b7ffa822 --- /dev/null +++ b/core/encoding/xml/debug_print.odin @@ -0,0 +1,73 @@ +package xml +/* + An XML 1.0 / 1.1 parser + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ +import "core:fmt" + +/* + Just for debug purposes. +*/ +print :: proc(doc: ^Document) { + assert(doc != nil) + + using fmt + println("[XML Prolog]") + + for attr in doc.prolog { + printf("\t%v: %v\n", attr.key, attr.val) + } + + printf("[Encoding] %v\n", doc.encoding) + printf("[DOCTYPE] %v\n", doc.doctype.ident) + + if len(doc.doctype.rest) > 0 { + printf("\t%v\n", doc.doctype.rest) + } + + if doc.root != nil { + println(" --- ") + print_element(0, doc.root) + println(" --- ") + } +} + +print_element :: proc(indent: int, element: ^Element) { + if element == nil { return } + using fmt + + tab :: proc(indent: int) { + tabs := "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" + + i := max(0, min(indent, len(tabs))) + printf("%v", tabs[:i]) + } + + tab(indent) + + if element.kind == .Element { + printf("<%v>\n", element.ident) + if len(element.value) > 0 { + tab(indent + 1) + printf("[Value] %v\n", element.value) + } + + for attr in element.attribs { + tab(indent + 1) + printf("[Attr] %v: %v\n", attr.key, attr.val) + } + + for child in element.children { + print_element(indent + 1, child) + } + } else if element.kind == .Comment { + printf("[COMMENT] %v\n", element.value) + } +} \ No newline at end of file diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin new file mode 100644 index 000000000..24a277de6 --- /dev/null +++ b/core/encoding/xml/example/xml_example.odin @@ -0,0 +1,55 @@ +package xml_example + +import "core:encoding/xml" +import "core:mem" +import "core:fmt" + +Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) { + +} + +FILENAME :: "../../../../tests/core/assets/xml/nl_NL-xliff-1.0.xliff" +DOC :: #load(FILENAME) + +OPTIONS :: xml.Options{ + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "", +} + +_main :: proc() { + using fmt + + println("--- DOCUMENT TO PARSE ---") + println(string(DOC)) + println("--- /DOCUMENT TO PARSE ---\n") + + doc, err := xml.parse(DOC, OPTIONS, FILENAME, Error_Handler) + defer xml.destroy(doc) + + xml.print(doc) + + if err != .None { + printf("Parse error: %v\n", err) + } else { + println("DONE!") + } +} + +main :: proc() { + using fmt + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + _main() + + if len(track.allocation_map) > 0 { + println() + for _, v in track.allocation_map { + printf("%v Leaked %v bytes.\n", v.location, v.size) + } + } +} \ No newline at end of file diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin new file mode 100644 index 000000000..a63dca5bd --- /dev/null +++ b/core/encoding/xml/tokenizer.odin @@ -0,0 +1,339 @@ +package xml + +import "core:fmt" +import "core:unicode" +import "core:unicode/utf8" + +Error_Handler :: #type proc(pos: Pos, fmt: string, args: ..any) + +Token :: struct { + kind: Token_Kind, + text: string, + pos: Pos, +} + +Pos :: struct { + file: string, + offset: int, // starting at 0 + line: int, // starting at 1 + column: int, // starting at 1 +} + +Token_Kind :: enum { + Invalid, + + Ident, + Literal, + Rune, + String, + + Double_Quote, // " + Single_Quote, // ' + Colon, // : + + Eq, // = + Lt, // < + Gt, // > + Exclaim, // ! + Question, // ? + Hash, // # + Slash, // / + Dash, // - + + Open_Bracket, // [ + Close_Bracket, // ] + + EOF, +} + +CDATA_START :: "" + +Tokenizer :: struct { + // Immutable data + path: string, + src: string, + err: Error_Handler, + + // Tokenizing state + ch: rune, + offset: int, + read_offset: int, + line_offset: int, + line_count: int, + + // Mutable data + error_count: int, +} + +init :: proc(t: ^Tokenizer, src: string, path: string, err: Error_Handler = default_error_handler) { + t.src = src + t.err = err + t.ch = ' ' + t.offset = 0 + t.read_offset = 0 + t.line_offset = 0 + t.line_count = len(src) > 0 ? 1 : 0 + t.error_count = 0 + t.path = path + + advance_rune(t) + if t.ch == utf8.RUNE_BOM { + advance_rune(t) + } +} + +@(private) +offset_to_pos :: proc(t: ^Tokenizer, offset: int) -> Pos { + line := t.line_count + column := offset - t.line_offset + 1 + + return Pos { + file = t.path, + offset = offset, + line = line, + column = column, + } +} + +default_error_handler :: proc(pos: Pos, msg: string, args: ..any) { + fmt.eprintf("%s(%d:%d) ", pos.file, pos.line, pos.column) + fmt.eprintf(msg, ..args) + fmt.eprintf("\n") +} + +error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) { + pos := offset_to_pos(t, offset) + if t.err != nil { + t.err(pos, msg, ..args) + } + t.error_count += 1 +} + +advance_rune :: proc(using t: ^Tokenizer) { + if read_offset < len(src) { + offset = read_offset + if ch == '\n' { + line_offset = offset + line_count += 1 + } + r, w := rune(src[read_offset]), 1 + switch { + case r == 0: + error(t, t.offset, "illegal character NUL") + case r >= utf8.RUNE_SELF: + r, w = utf8.decode_rune_in_string(src[read_offset:]) + if r == utf8.RUNE_ERROR && w == 1 { + error(t, t.offset, "illegal UTF-8 encoding") + } else if r == utf8.RUNE_BOM && offset > 0 { + error(t, t.offset, "illegal byte order mark") + } + } + read_offset += w + ch = r + } else { + offset = len(src) + if ch == '\n' { + line_offset = offset + line_count += 1 + } + ch = -1 + } +} + +peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte { + if t.read_offset+offset < len(t.src) { + return t.src[t.read_offset+offset] + } + return 0 +} + +skip_whitespace :: proc(t: ^Tokenizer) { + for { + switch t.ch { + case ' ', '\t', '\r', '\n': + advance_rune(t) + case: + return + } + } +} + +is_letter :: proc(r: rune) -> bool { + if r < utf8.RUNE_SELF { + switch r { + case '_': + return true + case 'A'..='Z', 'a'..='z': + return true + } + } + return unicode.is_letter(r) +} + +is_valid_identifier_rune :: proc(r: rune) -> bool { + if r < utf8.RUNE_SELF { + switch r { + case '_', '-', ':': return true + case 'A'..='Z', 'a'..='z': return true + case '0'..'9': return true + } + } + + if unicode.is_digit(r) || unicode.is_letter(r) { + return true + } + return false +} + +scan_identifier :: proc(t: ^Tokenizer) -> string { + offset := t.offset + namespaced := false + + for is_valid_identifier_rune(t.ch) { + advance_rune(t) + if t.ch == ':' { + /* + A namespaced attr can have at most two parts, `namespace:ident`. + */ + if namespaced { + break + } + namespaced = true + } + } + return string(t.src[offset : t.offset]) +} + +scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false) -> (value: string, err: Error) { + err = .None + in_cdata := false + + loop: for { + ch := t.ch + + switch ch { + case -1: + error(t, t.offset, "[scan_string] Premature end of file.\n") + return "", .Premature_EOF + + case '<': + /* + Might be the start of a CDATA tag. + */ + if t.read_offset + len(CDATA_START) < len(t.src) { + if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START { + in_cdata = true + } + } + + case ']': + /* + Might be the end of a CDATA tag. + */ + if t.read_offset + len(CDATA_END) < len(t.src) { + if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END { + in_cdata = false + } + } + + case '\n': + if !in_cdata { + error(t, offset, string(t.src[offset : t.offset])) + error(t, offset, "[scan_string] Not terminated\n") + err = .Invalid_Tag_Value + break loop + } + } + + if ch == close && !in_cdata { + /* + If it's not a CDATA tag, it's the end of this body. + */ + break loop + } + + advance_rune(t) + } + + lit := string(t.src[offset : t.offset]) + if consume_close { + advance_rune(t) + } + + /* + TODO: Handle decoding escape characters and unboxing CDATA. + */ + + return lit, err +} + +peek :: proc(t: ^Tokenizer) -> (token: Token) { + old := t^ + token = scan(t) + t^ = old + return token +} + +scan :: proc(t: ^Tokenizer) -> Token { + skip_whitespace(t) + + offset := t.offset + + kind: Token_Kind + err: Error + lit: string + pos := offset_to_pos(t, offset) + + switch ch := t.ch; true { + case is_letter(ch): + lit = scan_identifier(t) + kind = .Ident + + case: + advance_rune(t) + switch ch { + case -1: + kind = .EOF + + case '<': kind = .Lt + case '>': kind = .Gt + case '!': kind = .Exclaim + case '?': kind = .Question + case '=': kind = .Eq + case '#': kind = .Hash + case '/': kind = .Slash + case '-': kind = .Dash + case ':': kind = .Colon + + case '"', '\'': + lit, err = scan_string(t, t.offset, ch, true) + if err == .None { + kind = .String + } else { + kind = .Invalid + } + + case '\n': + lit = "\n" + + case '\\': + token := scan(t) + if token.pos.line == pos.line { + error(t, token.pos.offset, "expected a newline after \\") + } + return token + + case: + if ch != utf8.RUNE_BOM { + // error(t, t.offset, "illegal character '%r': %d", ch, ch) + } + kind = .Invalid + } + } + + if lit == "" { + lit = string(t.src[offset : t.offset]) + } + return Token{kind, lit, pos} +} \ No newline at end of file diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin new file mode 100644 index 000000000..526be5856 --- /dev/null +++ b/core/encoding/xml/xml_reader.odin @@ -0,0 +1,651 @@ +package xml +/* + An XML 1.0 / 1.1 parser + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + A from-scratch XML implementation, loosely modelled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). + + Features: + - Supports enough of the XML 1.0/1.1 spec to handle the 99.9% of XML documents in common current usage. + - Simple to understand and use. Small. + + Caveats: + - We do NOT support HTML in this package, as that may or may not be valid XML. + If it works, great. If it doesn't, that's not considered a bug. + + - We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences. + - <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options. + + TODO: + - Optional CDATA unboxing. + - Optional `>`, ` `, ` ` and other escape substitution in tag bodies. + + MAYBE: + - XML writer? + - Serialize/deserialize Odin types? + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + +import "core:strings" +import "core:mem" +import "core:os" + +DEFAULT_Options :: Options{ + flags = { + .Ignore_Unsupported, + }, + expected_doctype = "", +} + +Option_Flag :: enum { + /* + Document MUST start with ` (doc: ^Document, err: Error) { + context.allocator = allocator + + opts := validate_options(options) or_return + + t := &Tokenizer{} + init(t, string(data), path, error_handler) + + doc = new(Document) + doc.allocator = allocator + doc.tokenizer = t + + strings.intern_init(&doc.intern, allocator, allocator) + + err = .Unexpected_Token + element, parent: ^Element + + /* + If a DOCTYPE is present, the root tag has to match. + If an expected DOCTYPE is given in options (i.e. it's non-empty), the DOCTYPE (if present) and root tag have to match. + */ + expected_doctype := options.expected_doctype + + loop: for { + tok := scan(t) + #partial switch tok.kind { + + case .Lt: + open := scan(t) + #partial switch open.kind { + + case .Question: + /* + 0 { + /* + We've already seen a prolog. + */ + return doc, .Too_Many_Prologs + } else { + error(t, t.offset, "Expected \" 0 { + return doc, .Too_Many_DocTypes + } + if doc.root != nil { + return doc, .DocType_Must_Proceed_Elements + } + parse_doctype(doc) or_return + + if len(expected_doctype) > 0 && expected_doctype != doc.doctype.ident { + error(t, t.offset, "Invalid DOCTYPE. Expected: %v, got: %v\n", expected_doctype, doc.doctype.ident) + return doc, .Invalid_DocType + } + expected_doctype = doc.doctype.ident + + case: + if .Error_on_Unsupported in opts.flags { + error(t, t.offset, "Unhandled: . + The grammar does not allow a comment to end in ---> + */ + if doc.root == nil { + return doc, .Comment_Before_Root_Element + } + + expect(t, .Dash) + offset := t.offset + + for { + advance_rune(t) + ch := t.ch + + /* + A comment ends when we see -->, preceded by a character that's not a dash. + "For compatibility, the string "--" (double-hyphen) must not occur within comments." + + See: https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-comment + + Thanks to the length (4) of the comment start, we also have enough lookback, + and the peek at the next byte asserts that there's at least one more character + that's a `>`. + */ + if ch < 0 { + error(t, offset, "[parse] Comment was not terminated\n") + return doc, .Unclosed_Comment + } + + if string(t.src[t.offset - 1:][:2]) == "--" { + if peek_byte(t) == '>' { + break + } else { + error(t, t.offset - 1, "Invalid -- sequence in comment.\n") + return doc, .Invalid_Sequence_In_Comment + } + } + } + + if .Intern_Comments in opts.flags { + el := new(Element) + + el.parent = element + el.kind = .Comment + el.value = strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) + append(&element.children, el) + } + + expect(t, .Dash) + expect(t, .Gt) + + case: + error(t, t.offset, "Invalid Token after 0 && expected_doctype != open.text { + error(t, t.offset, "Root Tag doesn't match DOCTYPE. Expected: %v, got: %v\n", expected_doctype, open.text) + return doc, .Invalid_DocType + } + } + + /* + One of these should follow: + - `>`, which means we've just opened this tag and expect a later element to close it. + - `/>`, which means this is an 'empty' or self-closing tag. + */ + end_token := scan(t) + + #partial switch end_token.kind { + case .Gt: + /* + We're now the new parent. + */ + parent = element + + case .Slash: + /* + Empty tag? + */ + expect(t, .Gt) or_return + + case: + error(t, t.offset, "Expected close tag, got: %#v\n", end_token) + return + } + + case .Slash: + /* + Close tag. + */ + ident := expect(t, .Ident) or_return + _ = expect(t, .Gt) or_return + + if element.ident != ident.text { + error(t, t.offset, "Mismatched Closing Tag: %v\n", ident.text) + return doc, .Mismatched_Closing_Tag + } + parent = element.parent + element = parent + + case: + error(t, t.offset, "Invalid Token after <: %#v\n", open) + return + } + + case .EOF: + break loop + + case: + /* + This should be a tag's body text. + */ + element.value = scan_string(t, tok.pos.offset) or_return + } + } + + if .Must_Have_Prolog in opts.flags && len(doc.prolog) == 0 { + return doc, .No_Prolog + } + + if .Must_Have_DocType in opts.flags && len(doc.doctype.ident) == 0 { + return doc, .No_DocType + } + + return doc, .None +} + +parse_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { + context.allocator = allocator + + data, data_ok := os.read_entire_file(filename) + defer delete(data) + + if !data_ok { return {}, .File_Error } + + return parse_from_slice(data, options, filename, error_handler, allocator) +} + +parse :: proc { parse_from_file, parse_from_slice } + +free_element :: proc(element: ^Element) { + if element == nil { return } + + for child in element.children { + /* + NOTE: Recursive. + + Could be rewritten so it adds them to a list of pointers to free. + */ + free_element(child) + } + delete(element.attribs) + delete(element.children) + free(element) +} + +destroy :: proc(doc: ^Document) { + if doc == nil { return } + + free_element(doc.root) + strings.intern_destroy(&doc.intern) + + delete(doc.prolog) + free(doc) +} + +/* + Helpers. +*/ + +validate_options :: proc(options: Options) -> (validated: Options, err: Error) { + validated = options + + if .Error_on_Unsupported in validated.flags && .Ignore_Unsupported in validated.flags { + return options, .Conflicting_Options + } + + if .Unbox_CDATA in validated.flags { + return options, .Unhandled_CDATA_Unboxing + } + + if .Decode_SGML_Entities in validated.flags { + return options, .Unhandled_SGML_Entity_Decoding + } + + return validated, .None +} + +expect :: proc(t: ^Tokenizer, kind: Token_Kind) -> (tok: Token, err: Error) { + tok = scan(t) + if tok.kind == kind { return tok, .None } + + error(t, t.offset, "Expected \"%v\", got \"%v\".", kind, tok.kind) + return tok, .Unexpected_Token +} + +parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) { + assert(doc != nil) + context.allocator = doc.allocator + t := doc.tokenizer + + key := expect(t, .Ident) or_return + offset = t.offset - len(key.text) + + _ = expect(t, .Eq) or_return + value := expect(t, .String) or_return + + attr.key = strings.intern_get(&doc.intern, key.text) + attr.val = strings.intern_get(&doc.intern, value.text) + + err = .None + return +} + +check_duplicate_attributes :: proc(t: ^Tokenizer, attribs: Attributes, attr: Attr, offset: int) -> (err: Error) { + for a in attribs { + if attr.key == a.key { + error(t, offset, "Duplicate attribute: %v\n", attr.key) + return .Duplicate_Attribute + } + } + return .None +} + +parse_attributes :: proc(doc: ^Document, attribs: ^Attributes) -> (err: Error) { + assert(doc != nil) + context.allocator = doc.allocator + t := doc.tokenizer + + for peek(t).kind == .Ident { + attr, offset := parse_attribute(doc) or_return + check_duplicate_attributes(t, attribs^, attr, offset) or_return + append(attribs, attr) + } + skip_whitespace(t) + return .None +} + +parse_prolog :: proc(doc: ^Document) -> (err: Error) { + assert(doc != nil) + context.allocator = doc.allocator + t := doc.tokenizer + + offset := t.offset + parse_attributes(doc, &doc.prolog) or_return + + for attr in doc.prolog { + switch attr.key { + case "version": + switch attr.val { + case "1.0", "1.1": + case: + error(t, offset, "[parse_prolog] Warning: Unhandled XML version: %v\n", attr.val) + } + + case "encoding": + switch strings.to_lower(attr.val, context.temp_allocator) { + case "utf-8", "utf8": + doc.encoding = .UTF_8 + + case "latin-1", "latin1", "iso-8859-1": + doc.encoding = .LATIN_1 + + case: + /* + Unrecognized encoding, assume UTF-8. + */ + error(t, offset, "[parse_prolog] Warning: Unrecognized encoding: %v\n", attr.val) + } + + case: + // Ignored. + } + } + + _ = expect(t, .Question) or_return + _ = expect(t, .Gt) or_return + + return .None +} + +skip_element :: proc(t: ^Tokenizer) -> (err: Error) { + close := 1 + + loop: for { + tok := scan(t) + #partial switch tok.kind { + case .EOF: + error(t, t.offset, "[skip_element] Premature EOF\n") + return .Premature_EOF + + case .Lt: + close += 1 + + case .Gt: + close -= 1 + if close == 0 { + break loop + } + + case: + + } + } + return .None +} + +parse_doctype :: proc(doc: ^Document) -> (err: Error) { + /* + + + + ]> + */ + assert(doc != nil) + context.allocator = doc.allocator + t := doc.tokenizer + + tok := expect(t, .Ident) or_return + doc.doctype.ident = strings.intern_get(&doc.intern, tok.text) + + skip_whitespace(t) + offset := t.offset + skip_element(t) or_return + + /* + -1 because the current offset is that of the closing tag, so the rest of the DOCTYPE tag ends just before it. + */ + doc.doctype.rest = strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) + return .None +} \ No newline at end of file diff --git a/tests/core/Makefile b/tests/core/Makefile index 0f0ffe4d6..e17dede90 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -1,22 +1,29 @@ ODIN=../../odin PYTHON=$(shell which python3) -all: download_test_assets image_test compress_test strings_test hash_test crypto_test +all: download_test_assets image_test compress_test strings_test hash_test crypto_test encoding_test download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin + $(ODIN) run image/test_core_image.odin -out=test_image -o:speed -no-bounds-check compress_test: - $(ODIN) run compress/test_core_compress.odin + $(ODIN) run compress/test_core_compress.odin -out=test_compress -o:speed -no-bounds-check strings_test: - $(ODIN) run strings/test_core_strings.odin + $(ODIN) run strings/test_core_strings.odin -out=test_strings -o:speed -no-bounds-check + +odin_test: + $(ODIN) run odin -out=test_odin -o:speed -no-bounds-check hash_test: $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check crypto_test: - $(ODIN) run crypto -out=crypto_hash -o:speed -no-bounds-check \ No newline at end of file + $(ODIN) run crypto -out=crypto_hash -o:speed -no-bounds-check + +encoding_test: + $(ODIN) run encoding/json -out=test_encoding_json -o:speed -no-bounds-check + $(ODIN) run encoding/xml -out=test_encoding_xml -o:speed -no-bounds-check diff --git a/tests/core/assets/xml/nl_NL-qt-ts.ts b/tests/core/assets/xml/nl_NL-qt-ts.ts new file mode 100644 index 000000000..6ec3f2f47 --- /dev/null +++ b/tests/core/assets/xml/nl_NL-qt-ts.ts @@ -0,0 +1,35 @@ + + + + + Page + + Text for translation + commenting + Tekst om te vertalen + + + Also text to translate + some text + Ook tekst om te vertalen + + + + installscript + + 99 bottles of beer on the wall + some new comments here + 99 flessen bier op de muur + + + + apple_count + + %d apple(s) + + %d appel + %d appels + + + + diff --git a/tests/core/assets/xml/nl_NL-xliff-1.0.xliff b/tests/core/assets/xml/nl_NL-xliff-1.0.xliff new file mode 100644 index 000000000..7a1abcd66 --- /dev/null +++ b/tests/core/assets/xml/nl_NL-xliff-1.0.xliff @@ -0,0 +1,38 @@ + + + + + + text + tekst + Context + + + text 1 + tekst 1 + Context 1 + + + text 2 + + Context of the segment 2 + + + text 3 + translation 3 + Context 3 + + + Plurals + + %d month + %d maand + + + %d months + %d maanden + + + + + diff --git a/tests/core/assets/xml/nl_NL-xliff-2.0.xliff b/tests/core/assets/xml/nl_NL-xliff-2.0.xliff new file mode 100644 index 000000000..611ac80c4 --- /dev/null +++ b/tests/core/assets/xml/nl_NL-xliff-2.0.xliff @@ -0,0 +1,52 @@ + + + + + Note for file + + + + Note for unit + + + text + + + + + + Note for unit 2 + + + text 2 + translation 2 + + + + + Note for unit 3 + + + text 3 + approved translation 3 + + + + + + Plurals + + + %d month + %d maand + + + + + %d months + %d maanden + + + + + \ No newline at end of file diff --git a/tests/core/assets/xml/utf8.xml b/tests/core/assets/xml/utf8.xml new file mode 100644 index 000000000..c9ed3bf69 --- /dev/null +++ b/tests/core/assets/xml/utf8.xml @@ -0,0 +1,8 @@ + + +<恥ずべきフクロウ 올빼미_id="Foozle Hello, world!"]]>Barzle"> +<부끄러운:barzle> + ရှက်စရာ ဇီးကွက် + Owl of Shame + More CDATA Hello, world! Nonsense. + \ No newline at end of file diff --git a/tests/core/build.bat b/tests/core/build.bat index 176b7f175..7a214acc9 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -5,34 +5,35 @@ python3 download_assets.py echo --- echo Running core:image tests echo --- -%PATH_TO_ODIN% run image %COMMON% +%PATH_TO_ODIN% run image %COMMON% -out:test_image.exe echo --- echo Running core:compress tests echo --- -%PATH_TO_ODIN% run compress %COMMON% +%PATH_TO_ODIN% run compress %COMMON% -out:test_compress.exe echo --- echo Running core:strings tests echo --- -%PATH_TO_ODIN% run strings %COMMON% +%PATH_TO_ODIN% run strings %COMMON% -out:test_strings.exe echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size +%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_hash.exe echo --- echo Running core:odin tests echo --- -%PATH_TO_ODIN% run odin %COMMON% -o:size +%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_odin.exe echo --- echo Running core:crypto hash tests echo --- -%PATH_TO_ODIN% run crypto %COMMON% +%PATH_TO_ODIN% run crypto %COMMON% -o:speed -out:test_crypto.exe echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding %COMMON% \ No newline at end of file +%PATH_TO_ODIN% run encoding\json %COMMON% -out:test_json.exe +%PATH_TO_ODIN% run encoding\xml %COMMON% -out:test_xml.exe \ No newline at end of file diff --git a/tests/core/encoding/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin similarity index 63% rename from tests/core/encoding/test_core_json.odin rename to tests/core/encoding/json/test_core_json.odin index f536eb4c6..4f415c008 100644 --- a/tests/core/encoding/test_core_json.odin +++ b/tests/core/encoding/json/test_core_json.odin @@ -8,32 +8,32 @@ TEST_count := 0 TEST_fail := 0 when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + fmt.printf("[%v] ", loc) + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.println(message) + return + } + fmt.println(" PASS") + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } } main :: proc() { - t := testing.T{} + t := testing.T{} parse_json(&t) marshal_json(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } @test diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin new file mode 100644 index 000000000..7eefac212 --- /dev/null +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -0,0 +1,264 @@ +package test_core_xml + +import "core:encoding/xml" +import "core:testing" +import "core:mem" +import "core:fmt" + +Silent :: proc(pos: xml.Pos, fmt: string, args: ..any) { + // Custom (silent) error handler. +} + +OPTIONS :: xml.Options{ + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "", +} + +TEST_count := 0 +TEST_fail := 0 + +TEST :: struct { + filename: string, + options: xml.Options, + expected: struct { + error: xml.Error, + xml_version: string, + xml_encoding: string, + doctype: string, + }, +} + +TESTS :: []TEST{ + /* + First we test that certain files parse without error. + */ + { + filename = "assets/xml/utf8.xml", + options = OPTIONS, + expected = { + error = .None, + xml_version = "1.0", + xml_encoding = "utf-8", + doctype = "恥ずべきフクロウ", + }, + }, + { + filename = "assets/xml/nl_NL-qt-ts.ts", + options = OPTIONS, + expected = { + error = .None, + xml_version = "1.0", + xml_encoding = "utf-8", + doctype = "TS", + }, + }, + { + filename = "assets/xml/nl_NL-xliff-1.0.xliff", + options = OPTIONS, + expected = { + error = .None, + xml_version = "1.0", + xml_encoding = "UTF-8", + doctype = "", + }, + }, + { + filename = "assets/xml/nl_NL-xliff-2.0.xliff", + options = OPTIONS, + expected = { + error = .None, + xml_version = "1.0", + xml_encoding = "utf-8", + doctype = "", + }, + }, + + /* + Then we test that certain errors are returned as expected. + */ + { + filename = "assets/xml/utf8.xml", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "Odin", + }, + expected = { + error = .Invalid_DocType, + xml_version = "1.0", + xml_encoding = "utf-8", + doctype = "恥ずべきフクロウ", + }, + }, +} + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + fmt.printf("[%v] ", loc) + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.println(message) + return + } + fmt.println(" PASS") + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} + +main :: proc() { + t := testing.T{} + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + run_tests(&t) + + if len(track.allocation_map) > 0 { + for _, v in track.allocation_map { + err_msg := fmt.tprintf("%v Leaked %v bytes.", v.location, v.size) + expect(&t, false, err_msg) + } + } + + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) +} + +@test +run_tests :: proc(t: ^testing.T) { + using fmt + + count := 0 + + for test in TESTS { + printf("Trying to parse %v\n\n", test.filename) + + doc, err := xml.parse(test.filename, test.options, Silent) + defer xml.destroy(doc) + + err_msg := tprintf("Expected return value %v, got %v", test.expected.error, err) + expect(t, err == test.expected.error, err_msg) + + if len(test.expected.xml_version) > 0 { + xml_version := "" + for attr in doc.prolog { + if attr.key == "version" { + xml_version = attr.val + } + } + + err_msg = tprintf("Expected XML version %v, got %v", test.expected.xml_version, xml_version) + expect(t, xml_version == test.expected.xml_version, err_msg) + } + + if len(test.expected.xml_encoding) > 0 { + xml_encoding := "" + for attr in doc.prolog { + if attr.key == "encoding" { + xml_encoding = attr.val + } + } + + err_msg = tprintf("Expected XML encoding %v, got %v", test.expected.xml_encoding, xml_encoding) + expect(t, xml_encoding == test.expected.xml_encoding, err_msg) + } + + err_msg = tprintf("Expected DOCTYPE %v, got %v", test.expected.doctype, doc.doctype.ident) + expect(t, doc.doctype.ident == test.expected.doctype, err_msg) + + /* + File-specific tests. + */ + switch count { + case 0: + expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") + attr := doc.root.attribs[0] + + attr_key_expected := "올빼미_id" + attr_val_expected := "Foozle Hello, world!\"]]>Barzle" + + attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) + expect(t, attr.key == attr_key_expected, attr_err) + + attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) + expect(t, attr.val == attr_val_expected, attr_err) + + expect(t, len(doc.root.children) > 0, "Expected the root tag to have children.") + child := doc.root.children[0] + + first_child_ident := "부끄러운:barzle" + attr_err = tprintf("Expected first child tag's ident to be %v, got %v", first_child_ident, child.ident) + expect(t, child.ident == first_child_ident, attr_err) + + case 2: + expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") + + { + attr := doc.root.attribs[0] + + attr_key_expected := "version" + attr_val_expected := "1.2" + + attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) + expect(t, attr.key == attr_key_expected, attr_err) + + attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) + expect(t, attr.val == attr_val_expected, attr_err) + } + + { + attr := doc.root.attribs[1] + + attr_key_expected := "xmlns" + attr_val_expected := "urn:oasis:names:tc:xliff:document:1.2" + + attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) + expect(t, attr.key == attr_key_expected, attr_err) + + attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) + expect(t, attr.val == attr_val_expected, attr_err) + } + + case 3: + expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") + + { + attr := doc.root.attribs[0] + + attr_key_expected := "xmlns" + attr_val_expected := "urn:oasis:names:tc:xliff:document:2.0" + + attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) + expect(t, attr.key == attr_key_expected, attr_err) + + attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) + expect(t, attr.val == attr_val_expected, attr_err) + } + + { + attr := doc.root.attribs[1] + + attr_key_expected := "version" + attr_val_expected := "2.0" + + attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) + expect(t, attr.key == attr_key_expected, attr_err) + + attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) + expect(t, attr.val == attr_val_expected, attr_err) + } + } + + count += 1 + } +} \ No newline at end of file From 9b2e67df67b5f801687f3c48c6701daa00c38088 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 30 Nov 2021 23:43:51 +0100 Subject: [PATCH 002/245] [xml] Small cleanup. --- core/encoding/xml/tokenizer.odin | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index a63dca5bd..3dcffb0d6 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -180,7 +180,7 @@ is_valid_identifier_rune :: proc(r: rune) -> bool { } } - if unicode.is_digit(r) || unicode.is_letter(r) { + if unicode.is_letter(r) || unicode.is_digit(r) { return true } return false @@ -317,17 +317,7 @@ scan :: proc(t: ^Tokenizer) -> Token { case '\n': lit = "\n" - case '\\': - token := scan(t) - if token.pos.line == pos.line { - error(t, token.pos.offset, "expected a newline after \\") - } - return token - case: - if ch != utf8.RUNE_BOM { - // error(t, t.offset, "illegal character '%r': %d", ch, ch) - } kind = .Invalid } } From 46a4927acad674b3265969bd5bde591b480d0c73 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 1 Dec 2021 00:32:35 +0100 Subject: [PATCH 003/245] [xml] Use `io.Writer` for `xml.print(doc)`. --- core/encoding/xml/debug_print.odin | 51 ++++++++++++---------- core/encoding/xml/example/xml_example.odin | 8 +++- core/encoding/xml/xml_reader.odin | 2 +- 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index 0b7ffa822..be1175cbc 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -10,64 +10,69 @@ package xml List of contributors: Jeroen van Rijn: Initial implementation. */ +import "core:io" import "core:fmt" /* Just for debug purposes. */ -print :: proc(doc: ^Document) { - assert(doc != nil) - +print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error) { + if doc == nil { return } using fmt - println("[XML Prolog]") + + written += wprintf(writer, "[XML Prolog]\n") for attr in doc.prolog { - printf("\t%v: %v\n", attr.key, attr.val) + written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val) } - printf("[Encoding] %v\n", doc.encoding) - printf("[DOCTYPE] %v\n", doc.doctype.ident) + written += wprintf(writer, "[Encoding] %v\n", doc.encoding) + written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) if len(doc.doctype.rest) > 0 { - printf("\t%v\n", doc.doctype.rest) + wprintf(writer, "\t%v\n", doc.doctype.rest) } if doc.root != nil { - println(" --- ") - print_element(0, doc.root) - println(" --- ") - } + wprintln(writer, " --- ") + print_element(writer, doc.root) + wprintln(writer, " --- ") + } + + return written, .None } -print_element :: proc(indent: int, element: ^Element) { +print_element :: proc(writer: io.Writer, element: ^Element, indent := 0) -> (written: int, err: io.Error) { if element == nil { return } using fmt - tab :: proc(indent: int) { + tab :: proc(writer: io.Writer, indent: int) { tabs := "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" i := max(0, min(indent, len(tabs))) - printf("%v", tabs[:i]) + wprintf(writer, "%v", tabs[:i]) } - tab(indent) + tab(writer, indent) if element.kind == .Element { - printf("<%v>\n", element.ident) + wprintf(writer, "<%v>\n", element.ident) if len(element.value) > 0 { - tab(indent + 1) - printf("[Value] %v\n", element.value) + tab(writer, indent + 1) + wprintf(writer, "[Value] %v\n", element.value) } for attr in element.attribs { - tab(indent + 1) - printf("[Attr] %v: %v\n", attr.key, attr.val) + tab(writer, indent + 1) + wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val) } for child in element.children { - print_element(indent + 1, child) + print_element(writer, child, indent + 1) } } else if element.kind == .Comment { - printf("[COMMENT] %v\n", element.value) + wprintf(writer, "[COMMENT] %v\n", element.value) } + + return written, .None } \ No newline at end of file diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index 24a277de6..82938c223 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -2,6 +2,7 @@ package xml_example import "core:encoding/xml" import "core:mem" +import "core:strings" import "core:fmt" Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) { @@ -28,7 +29,12 @@ _main :: proc() { doc, err := xml.parse(DOC, OPTIONS, FILENAME, Error_Handler) defer xml.destroy(doc) - xml.print(doc) + buf: strings.Builder + defer strings.destroy_builder(&buf) + w := strings.to_writer(&buf) + + xml.print(w, doc) + println(strings.to_string(buf)) if err != .None { printf("Parse error: %v\n", err) diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 526be5856..34f6e65d0 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -75,6 +75,7 @@ Option_Flag :: enum { */ Decode_SGML_Entities, } +Option_Flags :: bit_set[Option_Flag; u8] Document :: struct { root: ^Element, @@ -122,7 +123,6 @@ Options :: struct { flags: Option_Flags, expected_doctype: string, } -Option_Flags :: bit_set[Option_Flag] Encoding :: enum { Unknown, From 682783a2aabad34e838493bb1e4c2437fd13058a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 1 Dec 2021 00:43:22 +0100 Subject: [PATCH 004/245] [xml] Tab indentation in debug printer. --- core/encoding/xml/debug_print.odin | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index be1175cbc..c4d6875cc 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -47,10 +47,9 @@ print_element :: proc(writer: io.Writer, element: ^Element, indent := 0) -> (wri using fmt tab :: proc(writer: io.Writer, indent: int) { - tabs := "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" - - i := max(0, min(indent, len(tabs))) - wprintf(writer, "%v", tabs[:i]) + for _ in 0..=indent { + wprintf(writer, "\t") + } } tab(writer, indent) From 32eab04d662b0c1128e64a4b91fb81f5f2be5a95 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 1 Dec 2021 03:15:44 +0100 Subject: [PATCH 005/245] [xml] Allow multi-line bodies w/o CDATA. Strip trailing whitespace. --- core/encoding/xml/debug_print.odin | 9 ++++++--- core/encoding/xml/tokenizer.odin | 21 ++++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index c4d6875cc..65b71e30b 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -27,10 +27,13 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error } written += wprintf(writer, "[Encoding] %v\n", doc.encoding) - written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) - if len(doc.doctype.rest) > 0 { - wprintf(writer, "\t%v\n", doc.doctype.rest) + if len(doc.doctype.ident) > 0 { + written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) + + if len(doc.doctype.rest) > 0 { + wprintf(writer, "\t%v\n", doc.doctype.rest) + } } if doc.root != nil { diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index 3dcffb0d6..e453552b8 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -205,7 +205,7 @@ scan_identifier :: proc(t: ^Tokenizer) -> string { return string(t.src[offset : t.offset]) } -scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false) -> (value: string, err: Error) { +scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) { err = .None in_cdata := false @@ -238,7 +238,7 @@ scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close } case '\n': - if !in_cdata { + if !(multiline || in_cdata) { error(t, offset, string(t.src[offset : t.offset])) error(t, offset, "[scan_string] Not terminated\n") err = .Invalid_Tag_Value @@ -256,7 +256,22 @@ scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close advance_rune(t) } + /* + Strip trailing whitespace. + */ lit := string(t.src[offset : t.offset]) + + end := len(lit) + eat: for ; end > 0; end -= 1 { + ch := lit[end - 1] + switch ch { + case ' ', '\t', '\r', '\n': + case: + break eat + } + } + lit = lit[:end] + if consume_close { advance_rune(t) } @@ -307,7 +322,7 @@ scan :: proc(t: ^Tokenizer) -> Token { case ':': kind = .Colon case '"', '\'': - lit, err = scan_string(t, t.offset, ch, true) + lit, err = scan_string(t, t.offset, ch, true, false) if err == .None { kind = .String } else { From ec63d0bbd21aa3d3f33cd762bd656ea8eb0af4a6 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 1 Dec 2021 15:30:36 +0100 Subject: [PATCH 006/245] [xml] Robustness improvement. Can now parse https://www.w3.org/2003/entities/2007xml/unicode.xml no problem. --- core/encoding/xml/debug_print.odin | 4 ++ core/encoding/xml/xml_reader.odin | 73 ++++++++++++++++++++---------- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index 65b71e30b..e6a8c9433 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -36,6 +36,10 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error } } + for comment in doc.comments { + written += wprintf(writer, "[Pre-root comment] %v\n", comment) + } + if doc.root != nil { wprintln(writer, " --- ") print_element(writer, doc.root) diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 34f6e65d0..b2226e6b9 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -86,10 +86,16 @@ Document :: struct { /* We only scan the . The grammar does not allow a comment to end in ---> */ - if doc.root == nil { - return doc, .Comment_Before_Root_Element - } - expect(t, .Dash) offset := t.offset @@ -329,12 +339,17 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err } if .Intern_Comments in opts.flags { - el := new(Element) + comment := strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) - el.parent = element - el.kind = .Comment - el.value = strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) - append(&element.children, el) + if doc.root == nil { + append(&doc.comments, comment) + } else { + el := new(Element) + el.parent = element + el.kind = .Comment + el.value = comment + append(&element.children, el) + } } expect(t, .Dash) @@ -350,6 +365,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err e.g. `, which means this is an 'empty' or self-closing tag. */ end_token := scan(t) - #partial switch end_token.kind { case .Gt: /* @@ -394,9 +409,12 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err case .Slash: /* - Empty tag? + Empty tag. Close it. */ expect(t, .Gt) or_return + parent = element.parent + element = parent + tag_is_open = false case: error(t, t.offset, "Expected close tag, got: %#v\n", end_token) @@ -411,25 +429,33 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err _ = expect(t, .Gt) or_return if element.ident != ident.text { - error(t, t.offset, "Mismatched Closing Tag: %v\n", ident.text) + error(t, t.offset, "Mismatched Closing Tag. Expected %v, got %v\n", element.ident, ident.text) return doc, .Mismatched_Closing_Tag } - parent = element.parent - element = parent + parent = element.parent + element = parent + tag_is_open = false case: error(t, t.offset, "Invalid Token after <: %#v\n", open) return } - case .EOF: + case -1: + /* + End of file. + */ + if tag_is_open { + return doc, .Premature_EOF + } break loop case: /* This should be a tag's body text. */ - element.value = scan_string(t, tok.pos.offset) or_return + body_text := scan_string(t, t.offset) or_return + element.value = strings.intern_get(&doc.intern, body_text) } } @@ -480,6 +506,7 @@ destroy :: proc(doc: ^Document) { strings.intern_destroy(&doc.intern) delete(doc.prolog) + delete(doc.comments) free(doc) } From beff90e1d12391e63cd1119023f8565eda97593e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 1 Dec 2021 18:02:48 +0100 Subject: [PATCH 007/245] [xml] Slight optimization. About a 5% speed bump. More rigorous optimization later. --- core/encoding/xml/tokenizer.odin | 62 ++++++++++++++++++------------- core/encoding/xml/xml_reader.odin | 4 +- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index e453552b8..9247d2531 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -110,44 +110,51 @@ error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) { t.error_count += 1 } +@(optimization_mode="speed") advance_rune :: proc(using t: ^Tokenizer) { - if read_offset < len(src) { - offset = read_offset - if ch == '\n' { - line_offset = offset - line_count += 1 - } - r, w := rune(src[read_offset]), 1 - switch { - case r == 0: - error(t, t.offset, "illegal character NUL") - case r >= utf8.RUNE_SELF: - r, w = utf8.decode_rune_in_string(src[read_offset:]) - if r == utf8.RUNE_ERROR && w == 1 { - error(t, t.offset, "illegal UTF-8 encoding") - } else if r == utf8.RUNE_BOM && offset > 0 { - error(t, t.offset, "illegal byte order mark") + #no_bounds_check { + /* + Already bounds-checked here. + */ + if read_offset < len(src) { + offset = read_offset + if ch == '\n' { + line_offset = offset + line_count += 1 } + r, w := rune(src[read_offset]), 1 + switch { + case r == 0: + error(t, t.offset, "illegal character NUL") + case r >= utf8.RUNE_SELF: + r, w = #force_inline utf8.decode_rune_in_string(src[read_offset:]) + if r == utf8.RUNE_ERROR && w == 1 { + error(t, t.offset, "illegal UTF-8 encoding") + } else if r == utf8.RUNE_BOM && offset > 0 { + error(t, t.offset, "illegal byte order mark") + } + } + read_offset += w + ch = r + } else { + offset = len(src) + if ch == '\n' { + line_offset = offset + line_count += 1 + } + ch = -1 } - read_offset += w - ch = r - } else { - offset = len(src) - if ch == '\n' { - line_offset = offset - line_count += 1 - } - ch = -1 } } peek_byte :: proc(t: ^Tokenizer, offset := 0) -> byte { if t.read_offset+offset < len(t.src) { - return t.src[t.read_offset+offset] + #no_bounds_check return t.src[t.read_offset+offset] } return 0 } +@(optimization_mode="speed") skip_whitespace :: proc(t: ^Tokenizer) { for { switch t.ch { @@ -159,6 +166,7 @@ skip_whitespace :: proc(t: ^Tokenizer) { } } +@(optimization_mode="speed") is_letter :: proc(r: rune) -> bool { if r < utf8.RUNE_SELF { switch r { @@ -177,6 +185,7 @@ is_valid_identifier_rune :: proc(r: rune) -> bool { case '_', '-', ':': return true case 'A'..='Z', 'a'..='z': return true case '0'..'9': return true + case -1: return false } } @@ -205,6 +214,7 @@ scan_identifier :: proc(t: ^Tokenizer) -> string { return string(t.src[offset : t.offset]) } +@(optimization_mode="speed") scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) { err = .None in_cdata := false diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index b2226e6b9..35dd83b3f 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -239,7 +239,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err /* Consume peeked `<` */ - tok := scan(t) + advance_rune(t) open := scan(t) #partial switch open.kind { @@ -265,7 +265,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err skip_element(t) or_return } case: - error(t, t.offset, "Expected \" Date: Wed, 1 Dec 2021 22:01:19 +0100 Subject: [PATCH 008/245] [xml] Improve CDATA + comment handling in tag body. --- core/encoding/xml/tokenizer.odin | 117 ++++++++++++++++++++++++------ core/encoding/xml/xml_reader.odin | 36 +-------- 2 files changed, 96 insertions(+), 57 deletions(-) diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index 9247d2531..95024518d 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -46,8 +46,11 @@ Token_Kind :: enum { EOF, } -CDATA_START :: "" +CDATA_START :: "" + +COMMENT_START :: "" Tokenizer :: struct { // Immutable data @@ -214,10 +217,83 @@ scan_identifier :: proc(t: ^Tokenizer) -> string { return string(t.src[offset : t.offset]) } +/* + A comment ends when we see -->, preceded by a character that's not a dash. + "For compatibility, the string "--" (double-hyphen) must not occur within comments." + + See: https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-comment + + Thanks to the length (4) of the comment start, we also have enough lookback, + and the peek at the next byte asserts that there's at least one more character + that's a `>`. +*/ +scan_comment :: proc(t: ^Tokenizer) -> (comment: string, err: Error) { + offset := t.offset + + for { + advance_rune(t) + ch := t.ch + + if ch < 0 { + error(t, offset, "[parse] Comment was not terminated\n") + return "", .Unclosed_Comment + } + + if string(t.src[t.offset - 1:][:2]) == "--" { + if peek_byte(t) == '>' { + break + } else { + error(t, t.offset - 1, "Invalid -- sequence in comment.\n") + return "", .Invalid_Sequence_In_Comment + } + } + } + + expect(t, .Dash) + expect(t, .Gt) + + return string(t.src[offset : t.offset - 1]), .None +} + +/* + Skip CDATA +*/ +skip_cdata :: proc(t: ^Tokenizer) -> (err: Error) { + if t.read_offset + len(CDATA_START) >= len(t.src) { + /* + Can't be the start of a CDATA tag. + */ + return .None + } + + if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START { + t.read_offset += len(CDATA_START) + offset := t.offset + + cdata_scan: for { + advance_rune(t) + if t.ch < 0 { + error(t, offset, "[scan_string] CDATA was not terminated\n") + return .Premature_EOF + } + + /* + Scan until the end of a CDATA tag. + */ + if t.read_offset + len(CDATA_END) < len(t.src) { + if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END { + t.read_offset += len(CDATA_END) + break cdata_scan + } + } + } + } + return +} + @(optimization_mode="speed") scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close := false, multiline := true) -> (value: string, err: Error) { err = .None - in_cdata := false loop: for { ch := t.ch @@ -228,27 +304,23 @@ scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close return "", .Premature_EOF case '<': - /* - Might be the start of a CDATA tag. - */ - if t.read_offset + len(CDATA_START) < len(t.src) { - if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START { - in_cdata = true - } - } - - case ']': - /* - Might be the end of a CDATA tag. - */ - if t.read_offset + len(CDATA_END) < len(t.src) { - if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END { - in_cdata = false + if peek_byte(t) == '!' { + if peek_byte(t, 1) == '[' { + /* + Might be the start of a CDATA tag. + */ + skip_cdata(t) or_return + } else if peek_byte(t, 1) == '-' && peek_byte(t, 2) == '-' { + /* + Comment start. Eat comment. + */ + t.read_offset += 3 + _ = scan_comment(t) or_return } } case '\n': - if !(multiline || in_cdata) { + if !multiline { error(t, offset, string(t.src[offset : t.offset])) error(t, offset, "[scan_string] Not terminated\n") err = .Invalid_Tag_Value @@ -256,13 +328,12 @@ scan_string :: proc(t: ^Tokenizer, offset: int, close: rune = '<', consume_close } } - if ch == close && !in_cdata { + if t.ch == close { /* - If it's not a CDATA tag, it's the end of this body. + If it's not a CDATA or comment, it's the end of this body. */ break loop } - advance_rune(t) } diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 35dd83b3f..146c278cb 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -307,39 +307,10 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err The grammar does not allow a comment to end in ---> */ expect(t, .Dash) - offset := t.offset - - for { - advance_rune(t) - ch := t.ch - - /* - A comment ends when we see -->, preceded by a character that's not a dash. - "For compatibility, the string "--" (double-hyphen) must not occur within comments." - - See: https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-comment - - Thanks to the length (4) of the comment start, we also have enough lookback, - and the peek at the next byte asserts that there's at least one more character - that's a `>`. - */ - if ch < 0 { - error(t, offset, "[parse] Comment was not terminated\n") - return doc, .Unclosed_Comment - } - - if string(t.src[t.offset - 1:][:2]) == "--" { - if peek_byte(t) == '>' { - break - } else { - error(t, t.offset - 1, "Invalid -- sequence in comment.\n") - return doc, .Invalid_Sequence_In_Comment - } - } - } + comment := scan_comment(t) or_return if .Intern_Comments in opts.flags { - comment := strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) + comment = strings.intern_get(&doc.intern, comment) if doc.root == nil { append(&doc.comments, comment) @@ -352,9 +323,6 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err } } - expect(t, .Dash) - expect(t, .Gt) - case: error(t, t.offset, "Invalid Token after Date: Thu, 2 Dec 2021 18:00:29 +0100 Subject: [PATCH 009/245] [xml] Improvements. --- core/encoding/xml/example/xml_example.odin | 71 +++++++++++-------- core/encoding/xml/helpers.odin | 49 +++++++++++++ core/encoding/xml/tokenizer.odin | 6 +- core/encoding/xml/xml_reader.odin | 2 + tests/core/assets/XML/.gitignore | 2 + tests/core/assets/{xml => XML}/nl_NL-qt-ts.ts | 0 .../assets/{xml => XML}/nl_NL-xliff-1.0.xliff | 0 .../assets/{xml => XML}/nl_NL-xliff-2.0.xliff | 0 tests/core/assets/{xml => XML}/utf8.xml | 0 tests/core/download_assets.py | 43 ++++++++--- tests/core/encoding/xml/test_core_xml.odin | 10 +-- 11 files changed, 137 insertions(+), 46 deletions(-) create mode 100644 core/encoding/xml/helpers.odin create mode 100644 tests/core/assets/XML/.gitignore rename tests/core/assets/{xml => XML}/nl_NL-qt-ts.ts (100%) rename tests/core/assets/{xml => XML}/nl_NL-xliff-1.0.xliff (100%) rename tests/core/assets/{xml => XML}/nl_NL-xliff-2.0.xliff (100%) rename tests/core/assets/{xml => XML}/utf8.xml (100%) diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index 82938c223..085252e92 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -1,45 +1,55 @@ package xml_example import "core:encoding/xml" +import "core:os" +import "core:path" import "core:mem" -import "core:strings" import "core:fmt" -Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) { +/* + Silent error handler for the parser. +*/ +Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) {} -} +OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, }, expected_doctype = "unicode", } -FILENAME :: "../../../../tests/core/assets/xml/nl_NL-xliff-1.0.xliff" -DOC :: #load(FILENAME) - -OPTIONS :: xml.Options{ - flags = { - .Ignore_Unsupported, .Intern_Comments, - }, - expected_doctype = "", -} - -_main :: proc() { +example :: proc() { using fmt - println("--- DOCUMENT TO PARSE ---") - println(string(DOC)) - println("--- /DOCUMENT TO PARSE ---\n") + filename := path.join(ODIN_ROOT, "tests", "core", "assets", "XML", "unicode.xml") + defer delete(filename) - doc, err := xml.parse(DOC, OPTIONS, FILENAME, Error_Handler) + doc, err := xml.parse(filename, OPTIONS, Error_Handler) defer xml.destroy(doc) - buf: strings.Builder - defer strings.destroy_builder(&buf) - w := strings.to_writer(&buf) - - xml.print(w, doc) - println(strings.to_string(buf)) - if err != .None { - printf("Parse error: %v\n", err) - } else { - println("DONE!") + printf("Load/Parse error: %v\n", err) + if err == .File_Error { + printf("\"%v\" not found. Did you run \"tests\\download_assets.py\"?", filename) + } + os.exit(1) + } + + printf("\"%v\" loaded and parsed.\n", filename) + + charlist, charlist_ok := xml.find_child_by_ident(doc.root, "charlist") + if !charlist_ok { + eprintln("Could not locate top-level `` tag.") + os.exit(1) + } + + printf("Found `` with %v children.\n", len(charlist.children)) + + for char in charlist.children { + if char.ident != "character" { + eprintf("Expected ``, got `<%v>`\n", char.ident) + os.exit(1) + } + + if _, ok := xml.find_attribute_val_by_key(char, "dec"); !ok { + eprintln("`` attribute not found.") + os.exit(1) + } } } @@ -50,12 +60,13 @@ main :: proc() { mem.tracking_allocator_init(&track, context.allocator) context.allocator = mem.tracking_allocator(&track) - _main() + example() if len(track.allocation_map) > 0 { println() for _, v in track.allocation_map { printf("%v Leaked %v bytes.\n", v.location, v.size) } - } + } + println("Done and cleaned up!") } \ No newline at end of file diff --git a/core/encoding/xml/helpers.odin b/core/encoding/xml/helpers.odin new file mode 100644 index 000000000..14597ddbd --- /dev/null +++ b/core/encoding/xml/helpers.odin @@ -0,0 +1,49 @@ +package xml +/* + An XML 1.0 / 1.1 parser + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + This file contains helper functions. +*/ + + +/* + Find `tag`'s nth child with a given ident. +*/ +find_child_by_ident :: proc(tag: ^Element, ident: string, nth := 0) -> (res: ^Element, found: bool) { + if tag == nil { return nil, false } + + count := 0 + for child in tag.children { + /* + Skip commments. They have no name. + */ + if child.kind != .Element { continue } + + /* + If the ident matches and it's the nth such child, return it. + */ + if child.ident == ident { + if count == nth { return child, true } + count += 1 + } + } + return nil, false +} + +/* + Find an attribute by key. +*/ +find_attribute_val_by_key :: proc(tag: ^Element, key: string) -> (val: string, found: bool) { + if tag == nil { return "", false } + + for attr in tag.attribs { + /* + If the ident matches, we're done. There can only ever be one attribute with the same name. + */ + if attr.key == key { return attr.val, true } + } + return "", false +} \ No newline at end of file diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index 95024518d..2da3b7683 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -403,11 +403,11 @@ scan :: proc(t: ^Tokenizer) -> Token { case ':': kind = .Colon case '"', '\'': + kind = .Invalid + lit, err = scan_string(t, t.offset, ch, true, false) if err == .None { kind = .String - } else { - kind = .Invalid } case '\n': @@ -418,7 +418,7 @@ scan :: proc(t: ^Tokenizer) -> Token { } } - if lit == "" { + if kind != .String && lit == "" { lit = string(t.src[offset : t.offset]) } return Token{kind, lit, pos} diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 146c278cb..563294309 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -519,6 +519,8 @@ parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) _ = expect(t, .Eq) or_return value := expect(t, .String) or_return + error(t, t.offset, "String: %v\n", value) + attr.key = strings.intern_get(&doc.intern, key.text) attr.val = strings.intern_get(&doc.intern, value.text) diff --git a/tests/core/assets/XML/.gitignore b/tests/core/assets/XML/.gitignore new file mode 100644 index 000000000..32dc58b57 --- /dev/null +++ b/tests/core/assets/XML/.gitignore @@ -0,0 +1,2 @@ +# This file will be downloaded by download_assets.py +unicode.xml \ No newline at end of file diff --git a/tests/core/assets/xml/nl_NL-qt-ts.ts b/tests/core/assets/XML/nl_NL-qt-ts.ts similarity index 100% rename from tests/core/assets/xml/nl_NL-qt-ts.ts rename to tests/core/assets/XML/nl_NL-qt-ts.ts diff --git a/tests/core/assets/xml/nl_NL-xliff-1.0.xliff b/tests/core/assets/XML/nl_NL-xliff-1.0.xliff similarity index 100% rename from tests/core/assets/xml/nl_NL-xliff-1.0.xliff rename to tests/core/assets/XML/nl_NL-xliff-1.0.xliff diff --git a/tests/core/assets/xml/nl_NL-xliff-2.0.xliff b/tests/core/assets/XML/nl_NL-xliff-2.0.xliff similarity index 100% rename from tests/core/assets/xml/nl_NL-xliff-2.0.xliff rename to tests/core/assets/XML/nl_NL-xliff-2.0.xliff diff --git a/tests/core/assets/xml/utf8.xml b/tests/core/assets/XML/utf8.xml similarity index 100% rename from tests/core/assets/xml/utf8.xml rename to tests/core/assets/XML/utf8.xml diff --git a/tests/core/download_assets.py b/tests/core/download_assets.py index d86f7f1e7..831b5b13a 100644 --- a/tests/core/download_assets.py +++ b/tests/core/download_assets.py @@ -50,10 +50,7 @@ def try_download_file(url, out_file): print("Could not download", url) return 1 -def try_download_and_unpack_zip(suite): - url = ASSETS_BASE_URL.format(suite, "{}.zip".format(suite)) - out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite) - +def try_download_and_unpack_zip(url, out_file, extract_path): print("\tDownloading {} to {}.".format(url, out_file)) if try_download_file(url, out_file) is not None: @@ -65,7 +62,6 @@ def try_download_and_unpack_zip(suite): with zipfile.ZipFile(out_file) as z: for file in z.filelist: filename = file.filename - extract_path = DOWNLOAD_BASE_PATH.format(suite) print("\t\tExtracting: {}".format(filename)) z.extract(file, extract_path) @@ -73,25 +69,56 @@ def try_download_and_unpack_zip(suite): print("Could not extract ZIP file") return 2 +def download_png_assets(): + suite = "PNG" + url = ASSETS_BASE_URL.format(suite, "{}.zip".format(suite)) + out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite) + extract_path = DOWNLOAD_BASE_PATH.format(suite) -def main(): print("Downloading PNG assets") # Make PNG assets path try: - path = DOWNLOAD_BASE_PATH.format("PNG") + path = DOWNLOAD_BASE_PATH.format(suite) os.makedirs(path) except FileExistsError: pass # Try downloading and unpacking the PNG assets - r = try_download_and_unpack_zip("PNG") + r = try_download_and_unpack_zip(url, out_file, extract_path) if r is not None: return r # We could fall back on downloading the PNG files individually, but it's slow print("Done downloading PNG assets") + +def download_unicode_assets(): + suite = "XML" + url = "https://www.w3.org/2003/entities/2007xml/unicode.xml.zip" + out_file = DOWNLOAD_BASE_PATH.format(suite) + "/{}.zip".format(suite) + extract_path = DOWNLOAD_BASE_PATH.format(suite) + + print("Downloading {}.".format(url)) + + # Make XML assets path + try: + path = DOWNLOAD_BASE_PATH.format(suite) + os.makedirs(path) + except FileExistsError: + pass + + # Try downloading and unpacking the assets + r = try_download_and_unpack_zip(url, out_file, extract_path) + if r is not None: + return r + + print("Done downloading Unicode/XML assets") + +def main(): + download_png_assets() + download_unicode_assets() + return 0 if __name__ == '__main__': diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index 7eefac212..c2e0aa172 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -35,7 +35,7 @@ TESTS :: []TEST{ First we test that certain files parse without error. */ { - filename = "assets/xml/utf8.xml", + filename = "assets/XML/utf8.xml", options = OPTIONS, expected = { error = .None, @@ -45,7 +45,7 @@ TESTS :: []TEST{ }, }, { - filename = "assets/xml/nl_NL-qt-ts.ts", + filename = "assets/XML/nl_NL-qt-ts.ts", options = OPTIONS, expected = { error = .None, @@ -55,7 +55,7 @@ TESTS :: []TEST{ }, }, { - filename = "assets/xml/nl_NL-xliff-1.0.xliff", + filename = "assets/XML/nl_NL-xliff-1.0.xliff", options = OPTIONS, expected = { error = .None, @@ -65,7 +65,7 @@ TESTS :: []TEST{ }, }, { - filename = "assets/xml/nl_NL-xliff-2.0.xliff", + filename = "assets/XML/nl_NL-xliff-2.0.xliff", options = OPTIONS, expected = { error = .None, @@ -79,7 +79,7 @@ TESTS :: []TEST{ Then we test that certain errors are returned as expected. */ { - filename = "assets/xml/utf8.xml", + filename = "assets/XML/utf8.xml", options = { flags = { .Ignore_Unsupported, .Intern_Comments, From 2dd67dba89732b89adb0199bc0a99de4cbc34e8f Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 2 Dec 2021 20:12:12 +0100 Subject: [PATCH 010/245] [core:encoding/entity] Add new package to decode &; entities. Includes generator to generate a lookup for named entitiess. --- core/encoding/entity/LICENSE_table.md | 21 + core/encoding/entity/entity.odin | 358 + .../entity/example/entity_example.odin | 122 + core/encoding/entity/example/test.html | 26 + core/encoding/entity/generated.odin | 7493 +++++++++++++++++ core/encoding/xml/xml_reader.odin | 2 - core/unicode/tools/generate_entity_table.odin | 287 + 7 files changed, 8307 insertions(+), 2 deletions(-) create mode 100644 core/encoding/entity/LICENSE_table.md create mode 100644 core/encoding/entity/entity.odin create mode 100644 core/encoding/entity/example/entity_example.odin create mode 100644 core/encoding/entity/example/test.html create mode 100644 core/encoding/entity/generated.odin create mode 100644 core/unicode/tools/generate_entity_table.odin diff --git a/core/encoding/entity/LICENSE_table.md b/core/encoding/entity/LICENSE_table.md new file mode 100644 index 000000000..51e3f34b5 --- /dev/null +++ b/core/encoding/entity/LICENSE_table.md @@ -0,0 +1,21 @@ +# License + +By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions. + +Permission to copy, modify, and distribute this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications: + +The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. +Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body of any redistributed or derivative code. + +Notice of any changes or modifications to the files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.) + +# Disclaimers + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. + +The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders. + +# Notes +This version: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 \ No newline at end of file diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin new file mode 100644 index 000000000..e40896819 --- /dev/null +++ b/core/encoding/entity/entity.odin @@ -0,0 +1,358 @@ +package unicode_entity +/* + A unicode entity encoder/decoder + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + This code has several procedures to map unicode runes to/from different textual encodings. + - SGML/XML/HTML entity + -- &#; + -- &#x; + -- &; (If the lookup tables are compiled in). + Reference: https://www.w3.org/2003/entities/2007xml/unicode.xml + + - URL encode / decode %hex entity + Reference: https://datatracker.ietf.org/doc/html/rfc3986/#section-2.1 + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + +import "core:unicode/utf8" +import "core:unicode" +import "core:strings" + +MAX_RUNE_CODEPOINT :: int(unicode.MAX_RUNE) + +write_rune :: strings.write_rune_builder +write_string :: strings.write_string_builder + +Error :: enum u8 { + None = 0, + Tokenizer_Is_Nil, + + Illegal_NUL_Character, + Illegal_UTF_Encoding, + Illegal_BOM, + + CDATA_Not_Terminated, + Comment_Not_Terminated, + Invalid_Entity_Encoding, +} + +Tokenizer :: struct { + r: rune, + w: int, + + src: string, + offset: int, + read_offset: int, +} + +CDATA_START :: "" + +COMMENT_START :: "" + +/* + Default: CDATA and comments are passed through unchanged. +*/ +XML_Decode_Option :: enum u8 { + /* + CDATA is unboxed. + */ + CDATA_Unbox, + + /* + Unboxed CDATA is decoded as well. + Ignored if `.CDATA_Unbox` is not given. + */ + CDATA_Decode, + + /* + Comments are stripped. + */ + Comment_Strip, +} +XML_Decode_Options :: bit_set[XML_Decode_Option; u8] + +/* + Decode a string that may include SGML/XML/HTML entities. + The caller has to free the result. +*/ +decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator := context.allocator) -> (decoded: string, err: Error) { + context.allocator = allocator + + l := len(input) + if l == 0 { return "", .None } + + builder := strings.make_builder() + defer strings.destroy_builder(&builder) + + t := Tokenizer{src=input} + in_data := false + + loop: for { + advance(&t) or_return + if t.r < 0 { break loop } + + /* + Below here we're never inside a CDATA tag. + At most we'll see the start of one, but that doesn't affect the logic. + */ + switch t.r { + case '<': + /* + Might be the start of a CDATA tag or comment. + + We don't need to check if we need to write a `<`, because if it isn't CDATA or a comment, + it couldn't have been part of an XML tag body to be decoded here. + */ + in_data = _handle_xml_special(&t, &builder, options) or_return + + case ']': + /* + If we're unboxing _and_ decoding CDATA, we'll have to check for the end tag. + */ + if in_data { + if t.read_offset + len(CDATA_END) < len(t.src) { + if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END { + in_data = false + t.read_offset += len(CDATA_END) - 1 + } + } + continue + } else { + write_rune(&builder, ']') + } + + case: + if in_data && .CDATA_Decode not_in options { + /* + Unboxed, but undecoded. + */ + write_rune(&builder, t.r) + continue + } + + if t.r == '&' { + if entity, entity_err := _extract_xml_entity(&t); entity_err != .None { + /* + We read to the end of the string without closing the entity. + Pass through as-is. + */ + write_string(&builder, entity) + } else { + if decoded, ok := xml_decode_entity(entity); ok { + write_rune(&builder, decoded) + } else { + /* + Decode failed. Pass through original. + */ + write_string(&builder, "&") + write_string(&builder, entity) + write_string(&builder, ";") + } + + } + } else { + write_rune(&builder, t.r) + } + } + } + + return strings.clone(strings.to_string(builder), allocator), err +} + +advance :: proc(t: ^Tokenizer) -> (err: Error) { + if t == nil { return .Tokenizer_Is_Nil } + using t + + #no_bounds_check { + if read_offset < len(src) { + offset = read_offset + r, w = rune(src[read_offset]), 1 + switch { + case r == 0: + return .Illegal_NUL_Character + case r >= utf8.RUNE_SELF: + r, w = utf8.decode_rune_in_string(src[read_offset:]) + if r == utf8.RUNE_ERROR && w == 1 { + return .Illegal_UTF_Encoding + } else if r == utf8.RUNE_BOM && offset > 0 { + return .Illegal_BOM + } + } + read_offset += w + return .None + } else { + offset = len(src) + r = -1 + return + } + } +} + +xml_decode_entity :: proc(entity: string) -> (decoded: rune, ok: bool) { + entity := entity + if len(entity) == 0 { return -1, false } + + switch entity[0] { + case '#': + base := 10 + val := 0 + entity = entity[1:] + + if len(entity) == 0 { return -1, false } + + if entity[0] == 'x' || entity[0] == 'X' { + base = 16 + entity = entity[1:] + } + + for len(entity) > 0 { + r := entity[0] + switch r { + case '0'..'9': + val *= base + val += int(r - '0') + + case 'a'..'f': + if base == 10 { return -1, false } + val *= base + val += int(r - 'a' + 10) + + case 'A'..'F': + if base == 10 { return -1, false } + val *= base + val += int(r - 'A' + 10) + + case: + return -1, false + } + + if val > MAX_RUNE_CODEPOINT { return -1, false } + entity = entity[1:] + } + return rune(val), true + + case: + /* + Named entity. + */ + return named_xml_entity_to_rune(entity) + } +} + +/* + Private XML helper to extract `&;` entity. +*/ +@(private="file") +_extract_xml_entity :: proc(t: ^Tokenizer) -> (entity: string, err: Error) { + assert(t != nil && t.r == '&') + + /* + All of these would be in the ASCII range. + Even if one is not, it doesn't matter. All characters we need to compare to extract are. + */ + using t + + length := len(t.src) + found := false + + #no_bounds_check { + for read_offset < length { + if src[read_offset] == ';' { + found = true + read_offset += 1 + break + } + read_offset += 1 + } + } + + if found { + return string(src[offset + 1 : read_offset - 1]), .None + } + return string(src[offset : read_offset]), .Invalid_Entity_Encoding +} + +/* + Private XML helper for CDATA and comments. +*/ +@(private="file") +_handle_xml_special :: proc(t: ^Tokenizer, builder: ^strings.Builder, options: XML_Decode_Options) -> (in_data: bool, err: Error) { + assert(t != nil && t.r == '<') + if t.read_offset + len(CDATA_START) >= len(t.src) { return false, .None } + + if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START { + t.read_offset += len(CDATA_START) - 1 + + if .CDATA_Unbox in options && .CDATA_Decode in options { + /* + We're unboxing _and_ decoding CDATA + */ + return true, .None + } + + /* + CDATA is passed through. + */ + offset := t.offset + + /* + Scan until end of CDATA. + */ + for { + advance(t) or_return + if t.r < 0 { return true, .CDATA_Not_Terminated } + + if t.read_offset + len(CDATA_END) < len(t.src) { + if string(t.src[t.offset:][:len(CDATA_END)]) == CDATA_END { + t.read_offset += len(CDATA_END) - 1 + + cdata := string(t.src[offset : t.read_offset]) + + if .CDATA_Unbox in options { + cdata = cdata[len(CDATA_START):] + cdata = cdata[:len(cdata) - len(CDATA_END)] + } + + write_string(builder, cdata) + return false, .None + } + } + } + + } else if string(t.src[t.offset:][:len(COMMENT_START)]) == COMMENT_START { + t.read_offset += len(COMMENT_START) + /* + Comment is passed through by default. + */ + offset := t.offset + + /* + Scan until end of Comment. + */ + for { + advance(t) or_return + if t.r < 0 { return true, .Comment_Not_Terminated } + + if t.read_offset + len(COMMENT_END) < len(t.src) { + if string(t.src[t.offset:][:len(COMMENT_END)]) == COMMENT_END { + t.read_offset += len(COMMENT_END) - 1 + + if .Comment_Strip not_in options { + comment := string(t.src[offset : t.read_offset]) + write_string(builder, comment) + } + return false, .None + } + } + } + + } + return false, .None +} \ No newline at end of file diff --git a/core/encoding/entity/example/entity_example.odin b/core/encoding/entity/example/entity_example.odin new file mode 100644 index 000000000..8758d9ad9 --- /dev/null +++ b/core/encoding/entity/example/entity_example.odin @@ -0,0 +1,122 @@ +package unicode_entity_example + +import "core:encoding/xml" +import "core:encoding/entity" +import "core:strings" +import "core:mem" +import "core:fmt" +import "core:time" + +OPTIONS :: xml.Options{ + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "", +} + +doc_print :: proc(doc: ^xml.Document) { + buf: strings.Builder + defer strings.destroy_builder(&buf) + w := strings.to_writer(&buf) + + xml.print(w, doc) + fmt.println(strings.to_string(buf)) +} + +_entities :: proc() { + doc: ^xml.Document + err: xml.Error + + DOC :: #load("../../../../tests/core/assets/XML/unicode.xml") + + parse_duration: time.Duration + + { + time.SCOPED_TICK_DURATION(&parse_duration) + doc, err = xml.parse(DOC, OPTIONS) + } + defer xml.destroy(doc) + + doc_print(doc) + + ms := time.duration_milliseconds(parse_duration) + + speed := (f64(1000.0) / ms) * f64(len(DOC)) / 1_024.0 / 1_024.0 + + fmt.printf("Parse time: %.2f ms (%.2f MiB/s).\n", ms, speed) + fmt.printf("Error: %v\n", err) +} + +_main :: proc() { + using fmt + + doc, err := xml.parse(#load("test.html")) + defer xml.destroy(doc) + doc_print(doc) + + if false { + val := doc.root.children[1].children[2].value + + println() + replaced, ok := entity.decode_xml(val) + defer delete(replaced) + + printf("Before: '%v', Err: %v\n", val, err) + printf("Passthrough: '%v'\nOK: %v\n", replaced, ok) + println() + } + + if false { + val := doc.root.children[1].children[2].value + + println() + replaced, ok := entity.decode_xml(val, { .CDATA_Unbox }) + defer delete(replaced) + + printf("Before: '%v', Err: %v\n", val, err) + printf("CDATA_Unbox: '%v'\nOK: %v\n", replaced, ok) + println() + } + + if true { + val := doc.root.children[1].children[2].value + + println() + replaced, ok := entity.decode_xml(val, { .CDATA_Unbox, .CDATA_Decode }) + defer delete(replaced) + + printf("Before: '%v', Err: %v\n", val, err) + printf("CDATA_Decode: '%v'\nOK: %v\n", replaced, ok) + println() + } + + if true { + val := doc.root.children[1].children[1].value + + println() + replaced, ok := entity.decode_xml(val, { .Comment_Strip }) + defer delete(replaced) + + printf("Before: '%v', Err: %v\n", val, err) + printf("Comment_Strip: '%v'\nOK: %v\n", replaced, ok) + println() + } +} + +main :: proc() { + using fmt + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + _main() + //_entities() + + if len(track.allocation_map) > 0 { + println() + for _, v in track.allocation_map { + printf("%v Leaked %v bytes.\n", v.location, v.size) + } + } +} \ No newline at end of file diff --git a/core/encoding/entity/example/test.html b/core/encoding/entity/example/test.html new file mode 100644 index 000000000..60e32bf03 --- /dev/null +++ b/core/encoding/entity/example/test.html @@ -0,0 +1,26 @@ + + + Entity Reference Test + + + +

Entity Reference Test

+
+ Foozle]! © 42&;1234& +
+
+ Foozle]! © 42&;1234& +
+
+ | | | fj ` \ ® ϱ ∳ +
+ + \ No newline at end of file diff --git a/core/encoding/entity/generated.odin b/core/encoding/entity/generated.odin new file mode 100644 index 000000000..9afdcae6d --- /dev/null +++ b/core/encoding/entity/generated.odin @@ -0,0 +1,7493 @@ +package unicode_entity + +/* + ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ +*/ + +/* + This file is generated from "https://www.w3.org/2003/entities/2007xml/unicode.xml". + + UPDATE: + - Ensure the XML file was downloaded using "tests\core\download_assets.py". + - Run "core/unicode/tools/generate_entity_table.odin" + + Odin unicode generated tables: https://github.com/odin-lang/Odin/tree/master/core/encoding/entity + + Copyright © 2021 World Wide Web Consortium, (Massachusetts Institute of Technology, + European Research Consortium for Informatics and Mathematics, Keio University, Beihang). + + All Rights Reserved. + + This work is distributed under the W3C® Software License [1] in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + [1] http://www.w3.org/Consortium/Legal/copyright-software + + See also: LICENSE_table.md +*/ + +// `<` +XML_NAME_TO_RUNE_MIN_LENGTH :: 2 +// `∳` +XML_NAME_TO_RUNE_MAX_LENGTH :: 31 + + +/* + Input: + entity_name - a string, like "copy" that describes a user-encoded Unicode entity as used in XML. + + Output: + "decoded" - The decoded rune if found by name, or -1 otherwise. + "ok" - true if found, false if not. + + IMPORTANT: XML processors (including browsers) treat these names as case-sensitive. So do we. +*/ +named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { + /* + Early out if the name is too short or too long. + min as a precaution in case the generated table has a bogus value. + */ + if len(name) < min(1, XML_NAME_TO_RUNE_MIN_LENGTH) || len(name) > XML_NAME_TO_RUNE_MAX_LENGTH { + return -1, false + } + + switch rune(name[0]) { + + case 'A': + switch name { + case "AElig": + // LATIN CAPITAL LETTER AE + return rune(0xc6), true + case "AMP": + // AMPERSAND + return rune(0x26), true + case "Aacgr": + // GREEK CAPITAL LETTER ALPHA WITH TONOS + return rune(0x0386), true + case "Aacute": + // LATIN CAPITAL LETTER A WITH ACUTE + return rune(0xc1), true + case "Abreve": + // LATIN CAPITAL LETTER A WITH BREVE + return rune(0x0102), true + case "Acirc": + // LATIN CAPITAL LETTER A WITH CIRCUMFLEX + return rune(0xc2), true + case "Acy": + // CYRILLIC CAPITAL LETTER A + return rune(0x0410), true + case "Afr": + // MATHEMATICAL FRAKTUR CAPITAL A + return rune(0x01d504), true + case "Agrave": + // LATIN CAPITAL LETTER A WITH GRAVE + return rune(0xc0), true + case "Agr": + // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Alpha": + // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Amacr": + // LATIN CAPITAL LETTER A WITH MACRON + return rune(0x0100), true + case "And": + // DOUBLE LOGICAL AND + return rune(0x2a53), true + case "Aogon": + // LATIN CAPITAL LETTER A WITH OGONEK + return rune(0x0104), true + case "Aopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL A + return rune(0x01d538), true + case "ApplyFunction": + // FUNCTION APPLICATION + return rune(0x2061), true + case "Aring": + // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "Ascr": + // MATHEMATICAL SCRIPT CAPITAL A + return rune(0x01d49c), true + case "Assign": + // COLON EQUALS + return rune(0x2254), true + case "Ast": + // TWO ASTERISKS ALIGNED VERTICALLY + return rune(0x2051), true + case "Atilde": + // LATIN CAPITAL LETTER A WITH TILDE + return rune(0xc3), true + case "Auml": + // LATIN CAPITAL LETTER A WITH DIAERESIS + return rune(0xc4), true + } + + case 'B': + switch name { + case "Backslash": + // SET MINUS + return rune(0x2216), true + case "Barint": + // INTEGRAL WITH DOUBLE STROKE + return rune(0x2a0e), true + case "Barv": + // SHORT DOWN TACK WITH OVERBAR + return rune(0x2ae7), true + case "Barwedl": + // LOGICAL AND WITH DOUBLE OVERBAR + return rune(0x2a5e), true + case "Barwed": + // PERSPECTIVE + return rune(0x2306), true + case "Bcy": + // CYRILLIC CAPITAL LETTER BE + return rune(0x0411), true + case "Because": + // BECAUSE + return rune(0x2235), true + case "Bernoullis": + // SCRIPT CAPITAL B + return rune(0x212c), true + case "Beta": + // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bfr": + // MATHEMATICAL FRAKTUR CAPITAL B + return rune(0x01d505), true + case "Bgr": + // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL B + return rune(0x01d539), true + case "Breve": + // BREVE + return rune(0x02d8), true + case "Bscr": + // SCRIPT CAPITAL B + return rune(0x212c), true + case "Bumpeq": + // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "Bvert": + // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + return rune(0x2506), true + } + + case 'C': + switch name { + case "CHcy": + // CYRILLIC CAPITAL LETTER CHE + return rune(0x0427), true + case "COPY": + // COPYRIGHT SIGN + return rune(0xa9), true + case "Cacute": + // LATIN CAPITAL LETTER C WITH ACUTE + return rune(0x0106), true + case "CapitalDifferentialD": + // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "Cap": + // DOUBLE INTERSECTION + return rune(0x22d2), true + case "Cayleys": + // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Ccaron": + // LATIN CAPITAL LETTER C WITH CARON + return rune(0x010c), true + case "Ccedil": + // LATIN CAPITAL LETTER C WITH CEDILLA + return rune(0xc7), true + case "Ccirc": + // LATIN CAPITAL LETTER C WITH CIRCUMFLEX + return rune(0x0108), true + case "Cconint": + // VOLUME INTEGRAL + return rune(0x2230), true + case "Cdot": + // LATIN CAPITAL LETTER C WITH DOT ABOVE + return rune(0x010a), true + case "Cedilla": + // CEDILLA + return rune(0xb8), true + case "CenterDot": + // MIDDLE DOT + return rune(0xb7), true + case "Cfr": + // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Chi": + // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "CircleDot": + // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "CircleMinus": + // CIRCLED MINUS + return rune(0x2296), true + case "CirclePlus": + // CIRCLED PLUS + return rune(0x2295), true + case "CircleTimes": + // CIRCLED TIMES + return rune(0x2297), true + case "ClockwiseContourIntegral": + // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "CloseCurlyDoubleQuote": + // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "CloseCurlyQuote": + // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "Colon": + // PROPORTION + return rune(0x2237), true + case "Colone": + // DOUBLE COLON EQUAL + return rune(0x2a74), true + case "Congruent": + // IDENTICAL TO + return rune(0x2261), true + case "Conint": + // SURFACE INTEGRAL + return rune(0x222f), true + case "ContourIntegral": + // CONTOUR INTEGRAL + return rune(0x222e), true + case "Copf": + // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "Coproduct": + // N-ARY COPRODUCT + return rune(0x2210), true + case "CounterClockwiseContourIntegral": + // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "Cross": + // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "Cscr": + // MATHEMATICAL SCRIPT CAPITAL C + return rune(0x01d49e), true + case "CupCap": + // EQUIVALENT TO + return rune(0x224d), true + case "Cup": + // DOUBLE UNION + return rune(0x22d3), true + } + + case 'D': + switch name { + case "DD": + // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "DDotrahd": + // RIGHTWARDS ARROW WITH DOTTED STEM + return rune(0x2911), true + case "DJcy": + // CYRILLIC CAPITAL LETTER DJE + return rune(0x0402), true + case "DScy": + // CYRILLIC CAPITAL LETTER DZE + return rune(0x0405), true + case "DZcy": + // CYRILLIC CAPITAL LETTER DZHE + return rune(0x040f), true + case "Dagger": + // DOUBLE DAGGER + return rune(0x2021), true + case "Darr": + // DOWNWARDS TWO HEADED ARROW + return rune(0x21a1), true + case "Dashv": + // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "Dcaron": + // LATIN CAPITAL LETTER D WITH CARON + return rune(0x010e), true + case "Dcy": + // CYRILLIC CAPITAL LETTER DE + return rune(0x0414), true + case "Del": + // NABLA + return rune(0x2207), true + case "Delta": + // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "Dfr": + // MATHEMATICAL FRAKTUR CAPITAL D + return rune(0x01d507), true + case "Dgr": + // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "DiacriticalAcute": + // ACUTE ACCENT + return rune(0xb4), true + case "DiacriticalDot": + // DOT ABOVE + return rune(0x02d9), true + case "DiacriticalDoubleAcute": + // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "DiacriticalGrave": + // GRAVE ACCENT + return rune(0x60), true + case "DiacriticalTilde": + // SMALL TILDE + return rune(0x02dc), true + case "Diamond": + // DIAMOND OPERATOR + return rune(0x22c4), true + case "DifferentialD": + // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "Dopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL D + return rune(0x01d53b), true + case "Dot": + // DIAERESIS + return rune(0xa8), true + case "DotDot": + // COMBINING FOUR DOTS ABOVE + return rune(0x20dc), true + case "DotEqual": + // APPROACHES THE LIMIT + return rune(0x2250), true + case "DoubleContourIntegral": + // SURFACE INTEGRAL + return rune(0x222f), true + case "DoubleDot": + // DIAERESIS + return rune(0xa8), true + case "DoubleDownArrow": + // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "DoubleLeftArrow": + // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "DoubleLeftRightArrow": + // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "DoubleLeftTee": + // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "DoubleLongLeftArrow": + // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "DoubleLongLeftRightArrow": + // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "DoubleLongRightArrow": + // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "DoubleRightArrow": + // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "DoubleRightTee": + // TRUE + return rune(0x22a8), true + case "DoubleUpArrow": + // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "DoubleUpDownArrow": + // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "DoubleVerticalBar": + // PARALLEL TO + return rune(0x2225), true + case "DownArrowUpArrow": + // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "DownArrow": + // DOWNWARDS ARROW + return rune(0x2193), true + case "DownArrowBar": + // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "DownBreve": + // COMBINING INVERTED BREVE + return rune(0x0311), true + case "DownLeftRightVector": + // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "DownLeftTeeVector": + // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "DownLeftVector": + // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "DownLeftVectorBar": + // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "DownRightTeeVector": + // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "DownRightVector": + // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "DownRightVectorBar": + // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "DownTeeArrow": + // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "DownTee": + // DOWN TACK + return rune(0x22a4), true + case "Downarrow": + // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "Dscr": + // MATHEMATICAL SCRIPT CAPITAL D + return rune(0x01d49f), true + case "Dstrok": + // LATIN CAPITAL LETTER D WITH STROKE + return rune(0x0110), true + } + + case 'E': + switch name { + case "EEacgr": + // GREEK CAPITAL LETTER ETA WITH TONOS + return rune(0x0389), true + case "EEgr": + // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "ENG": + // LATIN CAPITAL LETTER ENG + return rune(0x014a), true + case "ETH": + // LATIN CAPITAL LETTER ETH + return rune(0xd0), true + case "Eacgr": + // GREEK CAPITAL LETTER EPSILON WITH TONOS + return rune(0x0388), true + case "Eacute": + // LATIN CAPITAL LETTER E WITH ACUTE + return rune(0xc9), true + case "Ecaron": + // LATIN CAPITAL LETTER E WITH CARON + return rune(0x011a), true + case "Ecirc": + // LATIN CAPITAL LETTER E WITH CIRCUMFLEX + return rune(0xca), true + case "Ecy": + // CYRILLIC CAPITAL LETTER E + return rune(0x042d), true + case "Edot": + // LATIN CAPITAL LETTER E WITH DOT ABOVE + return rune(0x0116), true + case "Efr": + // MATHEMATICAL FRAKTUR CAPITAL E + return rune(0x01d508), true + case "Egrave": + // LATIN CAPITAL LETTER E WITH GRAVE + return rune(0xc8), true + case "Egr": + // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "Element": + // ELEMENT OF + return rune(0x2208), true + case "Emacr": + // LATIN CAPITAL LETTER E WITH MACRON + return rune(0x0112), true + case "EmptySmallSquare": + // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "EmptyVerySmallSquare": + // WHITE SMALL SQUARE + return rune(0x25ab), true + case "Eogon": + // LATIN CAPITAL LETTER E WITH OGONEK + return rune(0x0118), true + case "Eopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL E + return rune(0x01d53c), true + case "Epsilon": + // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "EqualTilde": + // MINUS TILDE + return rune(0x2242), true + case "Equal": + // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "Equilibrium": + // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "Escr": + // SCRIPT CAPITAL E + return rune(0x2130), true + case "Esim": + // EQUALS SIGN ABOVE TILDE OPERATOR + return rune(0x2a73), true + case "Eta": + // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "Euml": + // LATIN CAPITAL LETTER E WITH DIAERESIS + return rune(0xcb), true + case "Exists": + // THERE EXISTS + return rune(0x2203), true + case "ExponentialE": + // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true + } + + case 'F': + switch name { + case "Fcy": + // CYRILLIC CAPITAL LETTER EF + return rune(0x0424), true + case "Ffr": + // MATHEMATICAL FRAKTUR CAPITAL F + return rune(0x01d509), true + case "FilledSmallSquare": + // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "FilledVerySmallSquare": + // BLACK SMALL SQUARE + return rune(0x25aa), true + case "Fopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL F + return rune(0x01d53d), true + case "ForAll": + // FOR ALL + return rune(0x2200), true + case "Fouriertrf": + // SCRIPT CAPITAL F + return rune(0x2131), true + case "Fscr": + // SCRIPT CAPITAL F + return rune(0x2131), true + } + + case 'G': + switch name { + case "GJcy": + // CYRILLIC CAPITAL LETTER GJE + return rune(0x0403), true + case "GT": + // GREATER-THAN SIGN + return rune(0x3e), true + case "Game": + // TURNED SANS-SERIF CAPITAL G + return rune(0x2141), true + case "Gamma": + // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gammad": + // GREEK LETTER DIGAMMA + return rune(0x03dc), true + case "Gbreve": + // LATIN CAPITAL LETTER G WITH BREVE + return rune(0x011e), true + case "Gcedil": + // LATIN CAPITAL LETTER G WITH CEDILLA + return rune(0x0122), true + case "Gcirc": + // LATIN CAPITAL LETTER G WITH CIRCUMFLEX + return rune(0x011c), true + case "Gcy": + // CYRILLIC CAPITAL LETTER GHE + return rune(0x0413), true + case "Gdot": + // LATIN CAPITAL LETTER G WITH DOT ABOVE + return rune(0x0120), true + case "Gfr": + // MATHEMATICAL FRAKTUR CAPITAL G + return rune(0x01d50a), true + case "Ggr": + // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gg": + // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "Gopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL G + return rune(0x01d53e), true + case "GreaterEqual": + // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "GreaterEqualLess": + // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "GreaterFullEqual": + // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "GreaterGreater": + // DOUBLE NESTED GREATER-THAN + return rune(0x2aa2), true + case "GreaterLess": + // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "GreaterSlantEqual": + // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "GreaterTilde": + // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "Gscr": + // MATHEMATICAL SCRIPT CAPITAL G + return rune(0x01d4a2), true + case "Gt": + // MUCH GREATER-THAN + return rune(0x226b), true + } + + case 'H': + switch name { + case "HARDcy": + // CYRILLIC CAPITAL LETTER HARD SIGN + return rune(0x042a), true + case "Hacek": + // CARON + return rune(0x02c7), true + case "Hat": + // CIRCUMFLEX ACCENT + return rune(0x5e), true + case "Hcirc": + // LATIN CAPITAL LETTER H WITH CIRCUMFLEX + return rune(0x0124), true + case "Hfr": + // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "HilbertSpace": + // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hopf": + // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "HorizontalLine": + // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "Hscr": + // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hstrok": + // LATIN CAPITAL LETTER H WITH STROKE + return rune(0x0126), true + case "HumpDownHump": + // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "HumpEqual": + // DIFFERENCE BETWEEN + return rune(0x224f), true + } + + case 'I': + switch name { + case "IEcy": + // CYRILLIC CAPITAL LETTER IE + return rune(0x0415), true + case "IJlig": + // LATIN CAPITAL LIGATURE IJ + return rune(0x0132), true + case "IOcy": + // CYRILLIC CAPITAL LETTER IO + return rune(0x0401), true + case "Iacgr": + // GREEK CAPITAL LETTER IOTA WITH TONOS + return rune(0x038a), true + case "Iacute": + // LATIN CAPITAL LETTER I WITH ACUTE + return rune(0xcd), true + case "Icirc": + // LATIN CAPITAL LETTER I WITH CIRCUMFLEX + return rune(0xce), true + case "Icy": + // CYRILLIC CAPITAL LETTER I + return rune(0x0418), true + case "Idigr": + // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + return rune(0x03aa), true + case "Idot": + // LATIN CAPITAL LETTER I WITH DOT ABOVE + return rune(0x0130), true + case "Ifr": + // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Igrave": + // LATIN CAPITAL LETTER I WITH GRAVE + return rune(0xcc), true + case "Igr": + // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Imacr": + // LATIN CAPITAL LETTER I WITH MACRON + return rune(0x012a), true + case "ImaginaryI": + // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "Implies": + // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Im": + // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Integral": + // INTEGRAL + return rune(0x222b), true + case "Int": + // DOUBLE INTEGRAL + return rune(0x222c), true + case "Intersection": + // N-ARY INTERSECTION + return rune(0x22c2), true + case "InvisibleComma": + // INVISIBLE SEPARATOR + return rune(0x2063), true + case "InvisibleTimes": + // INVISIBLE TIMES + return rune(0x2062), true + case "Iogon": + // LATIN CAPITAL LETTER I WITH OGONEK + return rune(0x012e), true + case "Iopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL I + return rune(0x01d540), true + case "Iota": + // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Iscr": + // SCRIPT CAPITAL I + return rune(0x2110), true + case "Itilde": + // LATIN CAPITAL LETTER I WITH TILDE + return rune(0x0128), true + case "Iukcy": + // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0406), true + case "Iuml": + // LATIN CAPITAL LETTER I WITH DIAERESIS + return rune(0xcf), true + } + + case 'J': + switch name { + case "Jcirc": + // LATIN CAPITAL LETTER J WITH CIRCUMFLEX + return rune(0x0134), true + case "Jcy": + // CYRILLIC CAPITAL LETTER SHORT I + return rune(0x0419), true + case "Jfr": + // MATHEMATICAL FRAKTUR CAPITAL J + return rune(0x01d50d), true + case "Jopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL J + return rune(0x01d541), true + case "Jscr": + // MATHEMATICAL SCRIPT CAPITAL J + return rune(0x01d4a5), true + case "Jsercy": + // CYRILLIC CAPITAL LETTER JE + return rune(0x0408), true + case "Jukcy": + // CYRILLIC CAPITAL LETTER UKRAINIAN IE + return rune(0x0404), true + } + + case 'K': + switch name { + case "KHcy": + // CYRILLIC CAPITAL LETTER HA + return rune(0x0425), true + case "KHgr": + // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "KJcy": + // CYRILLIC CAPITAL LETTER KJE + return rune(0x040c), true + case "Kappa": + // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kcedil": + // LATIN CAPITAL LETTER K WITH CEDILLA + return rune(0x0136), true + case "Kcy": + // CYRILLIC CAPITAL LETTER KA + return rune(0x041a), true + case "Kfr": + // MATHEMATICAL FRAKTUR CAPITAL K + return rune(0x01d50e), true + case "Kgr": + // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL K + return rune(0x01d542), true + case "Kscr": + // MATHEMATICAL SCRIPT CAPITAL K + return rune(0x01d4a6), true + } + + case 'L': + switch name { + case "LJcy": + // CYRILLIC CAPITAL LETTER LJE + return rune(0x0409), true + case "LT": + // LESS-THAN SIGN + return rune(0x3c), true + case "Lacute": + // LATIN CAPITAL LETTER L WITH ACUTE + return rune(0x0139), true + case "Lambda": + // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Lang": + // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + return rune(0x27ea), true + case "Laplacetrf": + // SCRIPT CAPITAL L + return rune(0x2112), true + case "Larr": + // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "Lcaron": + // LATIN CAPITAL LETTER L WITH CARON + return rune(0x013d), true + case "Lcedil": + // LATIN CAPITAL LETTER L WITH CEDILLA + return rune(0x013b), true + case "Lcy": + // CYRILLIC CAPITAL LETTER EL + return rune(0x041b), true + case "LeftAngleBracket": + // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "LeftArrowBar": + // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "LeftArrowRightArrow": + // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "LeftArrow": + // LEFTWARDS ARROW + return rune(0x2190), true + case "LeftCeiling": + // LEFT CEILING + return rune(0x2308), true + case "LeftDoubleBracket": + // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "LeftDownTeeVector": + // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "LeftDownVector": + // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "LeftDownVectorBar": + // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "LeftFloor": + // LEFT FLOOR + return rune(0x230a), true + case "LeftRightArrow": + // LEFT RIGHT ARROW + return rune(0x2194), true + case "LeftRightVector": + // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "LeftTeeArrow": + // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "LeftTeeVector": + // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "LeftTee": + // LEFT TACK + return rune(0x22a3), true + case "LeftTriangleBar": + // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "LeftTriangle": + // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "LeftTriangleEqual": + // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "LeftUpDownVector": + // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "LeftUpTeeVector": + // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "LeftUpVector": + // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "LeftUpVectorBar": + // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "LeftVector": + // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "LeftVectorBar": + // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "Leftarrow": + // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "Leftrightarrow": + // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "LessEqualGreater": + // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "LessFullEqual": + // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "LessGreater": + // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "LessLess": + // DOUBLE NESTED LESS-THAN + return rune(0x2aa1), true + case "LessSlantEqual": + // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "LessTilde": + // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "Lfr": + // MATHEMATICAL FRAKTUR CAPITAL L + return rune(0x01d50f), true + case "Lgr": + // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Lleftarrow": + // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "Ll": + // VERY MUCH LESS-THAN + return rune(0x22d8), true + case "Lmidot": + // LATIN CAPITAL LETTER L WITH MIDDLE DOT + return rune(0x013f), true + case "LongLeftArrow": + // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "LongLeftRightArrow": + // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "LongRightArrow": + // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "Longleftarrow": + // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "Longleftrightarrow": + // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "Longrightarrow": + // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "Lopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL L + return rune(0x01d543), true + case "LowerLeftArrow": + // SOUTH WEST ARROW + return rune(0x2199), true + case "LowerRightArrow": + // SOUTH EAST ARROW + return rune(0x2198), true + case "Lscr": + // SCRIPT CAPITAL L + return rune(0x2112), true + case "Lsh": + // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "Lstrok": + // LATIN CAPITAL LETTER L WITH STROKE + return rune(0x0141), true + case "Ltbar": + // DOUBLE NESTED LESS-THAN WITH UNDERBAR + return rune(0x2aa3), true + case "Lt": + // MUCH LESS-THAN + return rune(0x226a), true + } + + case 'M': + switch name { + case "Mapfrom": + // LEFTWARDS DOUBLE ARROW FROM BAR + return rune(0x2906), true + case "Mapto": + // RIGHTWARDS DOUBLE ARROW FROM BAR + return rune(0x2907), true + case "Map": + // RIGHTWARDS TWO-HEADED ARROW FROM BAR + return rune(0x2905), true + case "Mcy": + // CYRILLIC CAPITAL LETTER EM + return rune(0x041c), true + case "MediumSpace": + // MEDIUM MATHEMATICAL SPACE + return rune(0x205f), true + case "Mellintrf": + // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mfr": + // MATHEMATICAL FRAKTUR CAPITAL M + return rune(0x01d510), true + case "Mgr": + // GREEK CAPITAL LETTER MU + return rune(0x039c), true + case "MinusPlus": + // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "Mopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL M + return rune(0x01d544), true + case "Mscr": + // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mu": + // GREEK CAPITAL LETTER MU + return rune(0x039c), true + } + + case 'N': + switch name { + case "NJcy": + // CYRILLIC CAPITAL LETTER NJE + return rune(0x040a), true + case "Nacute": + // LATIN CAPITAL LETTER N WITH ACUTE + return rune(0x0143), true + case "Ncaron": + // LATIN CAPITAL LETTER N WITH CARON + return rune(0x0147), true + case "Ncedil": + // LATIN CAPITAL LETTER N WITH CEDILLA + return rune(0x0145), true + case "Ncy": + // CYRILLIC CAPITAL LETTER EN + return rune(0x041d), true + case "NegativeMediumSpace": + // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThickSpace": + // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThinSpace": + // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeVeryThinSpace": + // ZERO WIDTH SPACE + return rune(0x200b), true + case "NestedGreaterGreater": + // MUCH GREATER-THAN + return rune(0x226b), true + case "NestedLessLess": + // MUCH LESS-THAN + return rune(0x226a), true + case "NewLine": + // LINE FEED (LF) + return rune(0x0a), true + case "Nfr": + // MATHEMATICAL FRAKTUR CAPITAL N + return rune(0x01d511), true + case "Ngr": + // GREEK CAPITAL LETTER NU + return rune(0x039d), true + case "NoBreak": + // WORD JOINER + return rune(0x2060), true + case "NonBreakingSpace": + // NO-BREAK SPACE + return rune(0xa0), true + case "Nopf": + // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "NotDoubleVerticalBar": + // NOT PARALLEL TO + return rune(0x2226), true + case "NotElement": + // NOT AN ELEMENT OF + return rune(0x2209), true + case "NotEqualTilde": + // MINUS TILDE with slash + return rune(0x2242), true + case "NotEqual": + // NOT EQUAL TO + return rune(0x2260), true + case "NotExists": + // THERE DOES NOT EXIST + return rune(0x2204), true + case "NotHumpDownHump": + // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "NotHumpEqual": + // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "NotLessGreater": + // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "NotReverseElement": + // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "NotTilde": + // NOT TILDE + return rune(0x2241), true + case "NotTildeEqual": + // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "NotTildeFullEqual": + // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "NotTildeTilde": + // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "NotVerticalBar": + // DOES NOT DIVIDE + return rune(0x2224), true + case "Not": + // DOUBLE STROKE NOT SIGN + return rune(0x2aec), true + case "NotCongruent": + // NOT IDENTICAL TO + return rune(0x2262), true + case "NotCupCap": + // NOT EQUIVALENT TO + return rune(0x226d), true + case "NotGreaterFullEqual": + // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "NotGreaterGreater": + // MUCH GREATER THAN with slash + return rune(0x226b), true + case "NotGreaterSlantEqual": + // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "NotGreater": + // NOT GREATER-THAN + return rune(0x226f), true + case "NotGreaterEqual": + // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "NotGreaterLess": + // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "NotGreaterTilde": + // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "NotLeftTriangleBar": + // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "NotLeftTriangle": + // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "NotLeftTriangleEqual": + // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "NotLessLess": + // MUCH LESS THAN with slash + return rune(0x226a), true + case "NotLessSlantEqual": + // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "NotLess": + // NOT LESS-THAN + return rune(0x226e), true + case "NotLessEqual": + // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "NotLessTilde": + // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "NotNestedGreaterGreater": + // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "NotNestedLessLess": + // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "NotPrecedesEqual": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "NotPrecedes": + // DOES NOT PRECEDE + return rune(0x2280), true + case "NotPrecedesSlantEqual": + // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "NotRightTriangleBar": + // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "NotRightTriangle": + // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "NotRightTriangleEqual": + // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "NotSquareSubset": + // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "NotSquareSubsetEqual": + // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "NotSquareSuperset": + // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "NotSquareSupersetEqual": + // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "NotSubset": + // SUBSET OF with vertical line + return rune(0x2282), true + case "NotSubsetEqual": + // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "NotSucceedsEqual": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "NotSucceedsTilde": + // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "NotSucceeds": + // DOES NOT SUCCEED + return rune(0x2281), true + case "NotSucceedsSlantEqual": + // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "NotSuperset": + // SUPERSET OF with vertical line + return rune(0x2283), true + case "NotSupersetEqual": + // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "Nscr": + // MATHEMATICAL SCRIPT CAPITAL N + return rune(0x01d4a9), true + case "Ntilde": + // LATIN CAPITAL LETTER N WITH TILDE + return rune(0xd1), true + case "Nu": + // GREEK CAPITAL LETTER NU + return rune(0x039d), true + } + + case 'O': + switch name { + case "OElig": + // LATIN CAPITAL LIGATURE OE + return rune(0x0152), true + case "OHacgr": + // GREEK CAPITAL LETTER OMEGA WITH TONOS + return rune(0x038f), true + case "OHgr": + // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Oacgr": + // GREEK CAPITAL LETTER OMICRON WITH TONOS + return rune(0x038c), true + case "Oacute": + // LATIN CAPITAL LETTER O WITH ACUTE + return rune(0xd3), true + case "Ocirc": + // LATIN CAPITAL LETTER O WITH CIRCUMFLEX + return rune(0xd4), true + case "Ocy": + // CYRILLIC CAPITAL LETTER O + return rune(0x041e), true + case "Odblac": + // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + return rune(0x0150), true + case "Ofr": + // MATHEMATICAL FRAKTUR CAPITAL O + return rune(0x01d512), true + case "Ograve": + // LATIN CAPITAL LETTER O WITH GRAVE + return rune(0xd2), true + case "Ogr": + // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Omacr": + // LATIN CAPITAL LETTER O WITH MACRON + return rune(0x014c), true + case "Omega": + // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Omicron": + // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Oopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL O + return rune(0x01d546), true + case "OpenCurlyDoubleQuote": + // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "OpenCurlyQuote": + // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "Or": + // DOUBLE LOGICAL OR + return rune(0x2a54), true + case "Oscr": + // MATHEMATICAL SCRIPT CAPITAL O + return rune(0x01d4aa), true + case "Oslash": + // LATIN CAPITAL LETTER O WITH STROKE + return rune(0xd8), true + case "Otilde": + // LATIN CAPITAL LETTER O WITH TILDE + return rune(0xd5), true + case "Otimes": + // MULTIPLICATION SIGN IN DOUBLE CIRCLE + return rune(0x2a37), true + case "Ouml": + // LATIN CAPITAL LETTER O WITH DIAERESIS + return rune(0xd6), true + case "OverBar": + // OVERLINE + return rune(0x203e), true + case "OverBrace": + // TOP CURLY BRACKET + return rune(0x23de), true + case "OverBracket": + // TOP SQUARE BRACKET + return rune(0x23b4), true + case "OverParenthesis": + // TOP PARENTHESIS + return rune(0x23dc), true + } + + case 'P': + switch name { + case "PHgr": + // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "PSgr": + // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true + case "PartialD": + // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "Pcy": + // CYRILLIC CAPITAL LETTER PE + return rune(0x041f), true + case "Pfr": + // MATHEMATICAL FRAKTUR CAPITAL P + return rune(0x01d513), true + case "Pgr": + // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "Phi": + // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "Pi": + // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "PlusMinus": + // PLUS-MINUS SIGN + return rune(0xb1), true + case "Poincareplane": + // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "Popf": + // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "Product": + // N-ARY PRODUCT + return rune(0x220f), true + case "Proportional": + // PROPORTIONAL TO + return rune(0x221d), true + case "Proportion": + // PROPORTION + return rune(0x2237), true + case "Pr": + // DOUBLE PRECEDES + return rune(0x2abb), true + case "PrecedesEqual": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "Precedes": + // PRECEDES + return rune(0x227a), true + case "PrecedesSlantEqual": + // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "PrecedesTilde": + // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "Prime": + // DOUBLE PRIME + return rune(0x2033), true + case "Pscr": + // MATHEMATICAL SCRIPT CAPITAL P + return rune(0x01d4ab), true + case "Psi": + // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true + } + + case 'Q': + switch name { + case "QUOT": + // QUOTATION MARK + return rune(0x22), true + case "Qfr": + // MATHEMATICAL FRAKTUR CAPITAL Q + return rune(0x01d514), true + case "Qopf": + // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "Qscr": + // MATHEMATICAL SCRIPT CAPITAL Q + return rune(0x01d4ac), true + } + + case 'R': + switch name { + case "RBarr": + // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "REG": + // REGISTERED SIGN + return rune(0xae), true + case "Racute": + // LATIN CAPITAL LETTER R WITH ACUTE + return rune(0x0154), true + case "Rang": + // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + return rune(0x27eb), true + case "Rarr": + // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true + case "Rarrtl": + // RIGHTWARDS TWO-HEADED ARROW WITH TAIL + return rune(0x2916), true + case "Rcaron": + // LATIN CAPITAL LETTER R WITH CARON + return rune(0x0158), true + case "Rcedil": + // LATIN CAPITAL LETTER R WITH CEDILLA + return rune(0x0156), true + case "Rcy": + // CYRILLIC CAPITAL LETTER ER + return rune(0x0420), true + case "ReverseElement": + // CONTAINS AS MEMBER + return rune(0x220b), true + case "ReverseEquilibrium": + // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "Re": + // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "ReverseUpEquilibrium": + // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "Rfr": + // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "Rgr": + // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "Rho": + // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "RightAngleBracket": + // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "RightArrowBar": + // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "RightArrow": + // RIGHTWARDS ARROW + return rune(0x2192), true + case "RightArrowLeftArrow": + // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "RightCeiling": + // RIGHT CEILING + return rune(0x2309), true + case "RightDoubleBracket": + // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "RightDownTeeVector": + // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "RightDownVector": + // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "RightDownVectorBar": + // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "RightFloor": + // RIGHT FLOOR + return rune(0x230b), true + case "RightTeeArrow": + // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "RightTeeVector": + // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "RightTee": + // RIGHT TACK + return rune(0x22a2), true + case "RightTriangleBar": + // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "RightTriangle": + // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "RightTriangleEqual": + // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "RightUpDownVector": + // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "RightUpTeeVector": + // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true + case "RightUpVector": + // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "RightUpVectorBar": + // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "RightVector": + // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "RightVectorBar": + // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "Rightarrow": + // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Ropf": + // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "RoundImplies": + // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "Rrightarrow": + // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "Rscr": + // SCRIPT CAPITAL R + return rune(0x211b), true + case "Rsh": + // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "RuleDelayed": + // RULE-DELAYED + return rune(0x29f4), true + } + + case 'S': + switch name { + case "SHCHcy": + // CYRILLIC CAPITAL LETTER SHCHA + return rune(0x0429), true + case "SHcy": + // CYRILLIC CAPITAL LETTER SHA + return rune(0x0428), true + case "SOFTcy": + // CYRILLIC CAPITAL LETTER SOFT SIGN + return rune(0x042c), true + case "Sacute": + // LATIN CAPITAL LETTER S WITH ACUTE + return rune(0x015a), true + case "Sc": + // DOUBLE SUCCEEDS + return rune(0x2abc), true + case "Scaron": + // LATIN CAPITAL LETTER S WITH CARON + return rune(0x0160), true + case "Scedil": + // LATIN CAPITAL LETTER S WITH CEDILLA + return rune(0x015e), true + case "Scirc": + // LATIN CAPITAL LETTER S WITH CIRCUMFLEX + return rune(0x015c), true + case "Scy": + // CYRILLIC CAPITAL LETTER ES + return rune(0x0421), true + case "Sfr": + // MATHEMATICAL FRAKTUR CAPITAL S + return rune(0x01d516), true + case "Sgr": + // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "ShortDownArrow": + // DOWNWARDS ARROW + return rune(0x2193), true + case "ShortLeftArrow": + // LEFTWARDS ARROW + return rune(0x2190), true + case "ShortRightArrow": + // RIGHTWARDS ARROW + return rune(0x2192), true + case "ShortUpArrow": + // UPWARDS ARROW + return rune(0x2191), true + case "Sigma": + // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "SmallCircle": + // RING OPERATOR + return rune(0x2218), true + case "Sopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL S + return rune(0x01d54a), true + case "Sqrt": + // SQUARE ROOT + return rune(0x221a), true + case "SquareIntersection": + // SQUARE CAP + return rune(0x2293), true + case "SquareSubset": + // SQUARE IMAGE OF + return rune(0x228f), true + case "SquareSubsetEqual": + // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "Square": + // WHITE SQUARE + return rune(0x25a1), true + case "SquareSuperset": + // SQUARE ORIGINAL OF + return rune(0x2290), true + case "SquareSupersetEqual": + // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "SquareUnion": + // SQUARE CUP + return rune(0x2294), true + case "Sscr": + // MATHEMATICAL SCRIPT CAPITAL S + return rune(0x01d4ae), true + case "Star": + // STAR OPERATOR + return rune(0x22c6), true + case "Sub": + // DOUBLE SUBSET + return rune(0x22d0), true + case "Subset": + // DOUBLE SUBSET + return rune(0x22d0), true + case "SubsetEqual": + // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "Succeeds": + // SUCCEEDS + return rune(0x227b), true + case "SucceedsEqual": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "SucceedsSlantEqual": + // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "SucceedsTilde": + // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "SuchThat": + // CONTAINS AS MEMBER + return rune(0x220b), true + case "Sum": + // N-ARY SUMMATION + return rune(0x2211), true + case "SupersetEqual": + // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "Sup": + // DOUBLE SUPERSET + return rune(0x22d1), true + case "Superset": + // SUPERSET OF + return rune(0x2283), true + case "Supset": + // DOUBLE SUPERSET + return rune(0x22d1), true + } + + case 'T': + switch name { + case "THORN": + // LATIN CAPITAL LETTER THORN + return rune(0xde), true + case "THgr": + // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "TRADE": + // TRADE MARK SIGN + return rune(0x2122), true + case "TSHcy": + // CYRILLIC CAPITAL LETTER TSHE + return rune(0x040b), true + case "TScy": + // CYRILLIC CAPITAL LETTER TSE + return rune(0x0426), true + case "Tab": + // CHARACTER TABULATION + return rune(0x09), true + case "Tau": + // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Tcaron": + // LATIN CAPITAL LETTER T WITH CARON + return rune(0x0164), true + case "Tcedil": + // LATIN CAPITAL LETTER T WITH CEDILLA + return rune(0x0162), true + case "Tcy": + // CYRILLIC CAPITAL LETTER TE + return rune(0x0422), true + case "Tfr": + // MATHEMATICAL FRAKTUR CAPITAL T + return rune(0x01d517), true + case "Tgr": + // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Therefore": + // THEREFORE + return rune(0x2234), true + case "Theta": + // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "Thetav": + // GREEK CAPITAL THETA SYMBOL + return rune(0x03f4), true + case "ThickSpace": + // space of width 5/18 em + return rune(0x205f), true + case "ThinSpace": + // THIN SPACE + return rune(0x2009), true + case "Tilde": + // TILDE OPERATOR + return rune(0x223c), true + case "TildeEqual": + // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "TildeFullEqual": + // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "TildeTilde": + // ALMOST EQUAL TO + return rune(0x2248), true + case "Topf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL T + return rune(0x01d54b), true + case "TripleDot": + // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "Tscr": + // MATHEMATICAL SCRIPT CAPITAL T + return rune(0x01d4af), true + case "Tstrok": + // LATIN CAPITAL LETTER T WITH STROKE + return rune(0x0166), true + } + + case 'U': + switch name { + case "Uacgr": + // GREEK CAPITAL LETTER UPSILON WITH TONOS + return rune(0x038e), true + case "Uacute": + // LATIN CAPITAL LETTER U WITH ACUTE + return rune(0xda), true + case "Uarrocir": + // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE + return rune(0x2949), true + case "Uarr": + // UPWARDS TWO HEADED ARROW + return rune(0x219f), true + case "Ubrcy": + // CYRILLIC CAPITAL LETTER SHORT U + return rune(0x040e), true + case "Ubreve": + // LATIN CAPITAL LETTER U WITH BREVE + return rune(0x016c), true + case "Ucirc": + // LATIN CAPITAL LETTER U WITH CIRCUMFLEX + return rune(0xdb), true + case "Ucy": + // CYRILLIC CAPITAL LETTER U + return rune(0x0423), true + case "Udblac": + // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + return rune(0x0170), true + case "Udigr": + // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + return rune(0x03ab), true + case "Ufr": + // MATHEMATICAL FRAKTUR CAPITAL U + return rune(0x01d518), true + case "Ugrave": + // LATIN CAPITAL LETTER U WITH GRAVE + return rune(0xd9), true + case "Ugr": + // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Umacr": + // LATIN CAPITAL LETTER U WITH MACRON + return rune(0x016a), true + case "UnderBar": + // LOW LINE + return rune(0x5f), true + case "UnderBrace": + // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "UnderBracket": + // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "UnderParenthesis": + // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "Union": + // N-ARY UNION + return rune(0x22c3), true + case "UnionPlus": + // MULTISET UNION + return rune(0x228e), true + case "Uogon": + // LATIN CAPITAL LETTER U WITH OGONEK + return rune(0x0172), true + case "Uopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL U + return rune(0x01d54c), true + case "UpArrow": + // UPWARDS ARROW + return rune(0x2191), true + case "UpArrowBar": + // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "UpArrowDownArrow": + // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "UpDownArrow": + // UP DOWN ARROW + return rune(0x2195), true + case "UpEquilibrium": + // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "UpTee": + // UP TACK + return rune(0x22a5), true + case "UpTeeArrow": + // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "Uparrow": + // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "Updownarrow": + // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "UpperLeftArrow": + // NORTH WEST ARROW + return rune(0x2196), true + case "UpperRightArrow": + // NORTH EAST ARROW + return rune(0x2197), true + case "Upsilon": + // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Upsi": + // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "Uring": + // LATIN CAPITAL LETTER U WITH RING ABOVE + return rune(0x016e), true + case "Uscr": + // MATHEMATICAL SCRIPT CAPITAL U + return rune(0x01d4b0), true + case "Utilde": + // LATIN CAPITAL LETTER U WITH TILDE + return rune(0x0168), true + case "Uuml": + // LATIN CAPITAL LETTER U WITH DIAERESIS + return rune(0xdc), true + } + + case 'V': + switch name { + case "VDash": + // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22ab), true + case "Vbar": + // DOUBLE UP TACK + return rune(0x2aeb), true + case "Vcy": + // CYRILLIC CAPITAL LETTER VE + return rune(0x0412), true + case "Vdashl": + // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL + return rune(0x2ae6), true + case "Vdash": + // FORCES + return rune(0x22a9), true + case "Vee": + // N-ARY LOGICAL OR + return rune(0x22c1), true + case "Verbar": + // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "Vert": + // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "VerticalBar": + // DIVIDES + return rune(0x2223), true + case "VerticalLine": + // VERTICAL LINE + return rune(0x7c), true + case "VerticalSeparator": + // LIGHT VERTICAL BAR + return rune(0x2758), true + case "VerticalTilde": + // WREATH PRODUCT + return rune(0x2240), true + case "VeryThinSpace": + // HAIR SPACE + return rune(0x200a), true + case "Vfr": + // MATHEMATICAL FRAKTUR CAPITAL V + return rune(0x01d519), true + case "Vopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL V + return rune(0x01d54d), true + case "Vscr": + // MATHEMATICAL SCRIPT CAPITAL V + return rune(0x01d4b1), true + case "Vvdash": + // TRIPLE VERTICAL BAR RIGHT TURNSTILE + return rune(0x22aa), true + } + + case 'W': + switch name { + case "Wcirc": + // LATIN CAPITAL LETTER W WITH CIRCUMFLEX + return rune(0x0174), true + case "Wedge": + // N-ARY LOGICAL AND + return rune(0x22c0), true + case "Wfr": + // MATHEMATICAL FRAKTUR CAPITAL W + return rune(0x01d51a), true + case "Wopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL W + return rune(0x01d54e), true + case "Wscr": + // MATHEMATICAL SCRIPT CAPITAL W + return rune(0x01d4b2), true + } + + case 'X': + switch name { + case "Xfr": + // MATHEMATICAL FRAKTUR CAPITAL X + return rune(0x01d51b), true + case "Xgr": + // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xi": + // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL X + return rune(0x01d54f), true + case "Xscr": + // MATHEMATICAL SCRIPT CAPITAL X + return rune(0x01d4b3), true + } + + case 'Y': + switch name { + case "YAcy": + // CYRILLIC CAPITAL LETTER YA + return rune(0x042f), true + case "YIcy": + // CYRILLIC CAPITAL LETTER YI + return rune(0x0407), true + case "YUcy": + // CYRILLIC CAPITAL LETTER YU + return rune(0x042e), true + case "Yacute": + // LATIN CAPITAL LETTER Y WITH ACUTE + return rune(0xdd), true + case "Ycirc": + // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + return rune(0x0176), true + case "Ycy": + // CYRILLIC CAPITAL LETTER YERU + return rune(0x042b), true + case "Yfr": + // MATHEMATICAL FRAKTUR CAPITAL Y + return rune(0x01d51c), true + case "Yopf": + // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + return rune(0x01d550), true + case "Yscr": + // MATHEMATICAL SCRIPT CAPITAL Y + return rune(0x01d4b4), true + case "Yuml": + // LATIN CAPITAL LETTER Y WITH DIAERESIS + return rune(0x0178), true + } + + case 'Z': + switch name { + case "ZHcy": + // CYRILLIC CAPITAL LETTER ZHE + return rune(0x0416), true + case "Zacute": + // LATIN CAPITAL LETTER Z WITH ACUTE + return rune(0x0179), true + case "Zcaron": + // LATIN CAPITAL LETTER Z WITH CARON + return rune(0x017d), true + case "Zcy": + // CYRILLIC CAPITAL LETTER ZE + return rune(0x0417), true + case "Zdot": + // LATIN CAPITAL LETTER Z WITH DOT ABOVE + return rune(0x017b), true + case "ZeroWidthSpace": + // ZERO WIDTH SPACE + return rune(0x200b), true + case "Zeta": + // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zfr": + // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "Zgr": + // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zopf": + // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "Zscr": + // MATHEMATICAL SCRIPT CAPITAL Z + return rune(0x01d4b5), true + } + + case 'a': + switch name { + case "aacgr": + // GREEK SMALL LETTER ALPHA WITH TONOS + return rune(0x03ac), true + case "aacute": + // LATIN SMALL LETTER A WITH ACUTE + return rune(0xe1), true + case "abreve": + // LATIN SMALL LETTER A WITH BREVE + return rune(0x0103), true + case "acE": + // INVERTED LAZY S with double underline + return rune(0x223e), true + case "acd": + // SINE WAVE + return rune(0x223f), true + case "acute": + // ACUTE ACCENT + return rune(0xb4), true + case "ac": + // INVERTED LAZY S + return rune(0x223e), true + case "acirc": + // LATIN SMALL LETTER A WITH CIRCUMFLEX + return rune(0xe2), true + case "actuary": + // COMBINING ANNUITY SYMBOL + return rune(0x20e7), true + case "acy": + // CYRILLIC SMALL LETTER A + return rune(0x0430), true + case "aelig": + // LATIN SMALL LETTER AE + return rune(0xe6), true + case "af": + // FUNCTION APPLICATION + return rune(0x2061), true + case "afr": + // MATHEMATICAL FRAKTUR SMALL A + return rune(0x01d51e), true + case "agr": + // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "agrave": + // LATIN SMALL LETTER A WITH GRAVE + return rune(0xe0), true + case "alefsym": + // ALEF SYMBOL + return rune(0x2135), true + case "aleph": + // ALEF SYMBOL + return rune(0x2135), true + case "alpha": + // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "amacr": + // LATIN SMALL LETTER A WITH MACRON + return rune(0x0101), true + case "amalg": + // AMALGAMATION OR COPRODUCT + return rune(0x2a3f), true + case "amp": + // AMPERSAND + return rune(0x26), true + case "andand": + // TWO INTERSECTING LOGICAL AND + return rune(0x2a55), true + case "andd": + // LOGICAL AND WITH HORIZONTAL DASH + return rune(0x2a5c), true + case "andslope": + // SLOPING LARGE AND + return rune(0x2a58), true + case "andv": + // LOGICAL AND WITH MIDDLE STEM + return rune(0x2a5a), true + case "and": + // LOGICAL AND + return rune(0x2227), true + case "angdnl": + // TURNED ANGLE + return rune(0x29a2), true + case "angdnr": + // ACUTE ANGLE + return rune(0x299f), true + case "ange": + // ANGLE WITH UNDERBAR + return rune(0x29a4), true + case "angles": + // ANGLE WITH S INSIDE + return rune(0x299e), true + case "angle": + // ANGLE + return rune(0x2220), true + case "angmsdaa": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT + return rune(0x29a8), true + case "angmsdab": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT + return rune(0x29a9), true + case "angmsdac": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT + return rune(0x29aa), true + case "angmsdad": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT + return rune(0x29ab), true + case "angmsdae": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP + return rune(0x29ac), true + case "angmsdaf": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP + return rune(0x29ad), true + case "angmsdag": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN + return rune(0x29ae), true + case "angmsdah": + // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN + return rune(0x29af), true + case "angmsd": + // MEASURED ANGLE + return rune(0x2221), true + case "angrtvbd": + // MEASURED RIGHT ANGLE WITH DOT + return rune(0x299d), true + case "angrtvb": + // RIGHT ANGLE WITH ARC + return rune(0x22be), true + case "angsph": + // SPHERICAL ANGLE + return rune(0x2222), true + case "angst": + // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "angupl": + // REVERSED ANGLE + return rune(0x29a3), true + case "angzarr": + // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + return rune(0x237c), true + case "ang": + // ANGLE + return rune(0x2220), true + case "ang90": + // RIGHT ANGLE + return rune(0x221f), true + case "angrt": + // RIGHT ANGLE + return rune(0x221f), true + case "aogon": + // LATIN SMALL LETTER A WITH OGONEK + return rune(0x0105), true + case "aopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL A + return rune(0x01d552), true + case "apE": + // APPROXIMATELY EQUAL OR EQUAL TO + return rune(0x2a70), true + case "apacir": + // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT + return rune(0x2a6f), true + case "ape": + // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "apid": + // TRIPLE TILDE + return rune(0x224b), true + case "approxeq": + // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "approx": + // ALMOST EQUAL TO + return rune(0x2248), true + case "ap": + // ALMOST EQUAL TO + return rune(0x2248), true + case "apos": + // APOSTROPHE + return rune(0x27), true + case "aring": + // LATIN SMALL LETTER A WITH RING ABOVE + return rune(0xe5), true + case "arrllsr": + // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW + return rune(0x2943), true + case "arrlrsl": + // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW + return rune(0x2942), true + case "arrsrll": + // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW + return rune(0x2944), true + case "ascr": + // MATHEMATICAL SCRIPT SMALL A + return rune(0x01d4b6), true + case "astb": + // SQUARED ASTERISK + return rune(0x29c6), true + case "ast": + // ASTERISK + return rune(0x2a), true + case "asympeq": + // EQUIVALENT TO + return rune(0x224d), true + case "asymp": + // ALMOST EQUAL TO + return rune(0x2248), true + case "atilde": + // LATIN SMALL LETTER A WITH TILDE + return rune(0xe3), true + case "auml": + // LATIN SMALL LETTER A WITH DIAERESIS + return rune(0xe4), true + case "awconint": + // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "awint": + // ANTICLOCKWISE INTEGRATION + return rune(0x2a11), true + } + + case 'b': + switch name { + case "b.Delta": + // MATHEMATICAL BOLD CAPITAL DELTA + return rune(0x01d6ab), true + case "b.Gamma": + // MATHEMATICAL BOLD CAPITAL GAMMA + return rune(0x01d6aa), true + case "b.Gammad": + // MATHEMATICAL BOLD CAPITAL DIGAMMA + return rune(0x01d7ca), true + case "b.Lambda": + // MATHEMATICAL BOLD CAPITAL LAMDA + return rune(0x01d6b2), true + case "b.Omega": + // MATHEMATICAL BOLD CAPITAL OMEGA + return rune(0x01d6c0), true + case "b.Phi": + // MATHEMATICAL BOLD CAPITAL PHI + return rune(0x01d6bd), true + case "b.Pi": + // MATHEMATICAL BOLD CAPITAL PI + return rune(0x01d6b7), true + case "b.Psi": + // MATHEMATICAL BOLD CAPITAL PSI + return rune(0x01d6bf), true + case "b.Sigma": + // MATHEMATICAL BOLD CAPITAL SIGMA + return rune(0x01d6ba), true + case "b.Theta": + // MATHEMATICAL BOLD CAPITAL THETA + return rune(0x01d6af), true + case "b.Upsi": + // MATHEMATICAL BOLD CAPITAL UPSILON + return rune(0x01d6bc), true + case "b.Xi": + // MATHEMATICAL BOLD CAPITAL XI + return rune(0x01d6b5), true + case "b.alpha": + // MATHEMATICAL BOLD SMALL ALPHA + return rune(0x01d6c2), true + case "b.beta": + // MATHEMATICAL BOLD SMALL BETA + return rune(0x01d6c3), true + case "b.chi": + // MATHEMATICAL BOLD SMALL CHI + return rune(0x01d6d8), true + case "b.delta": + // MATHEMATICAL BOLD SMALL DELTA + return rune(0x01d6c5), true + case "b.epsi": + // MATHEMATICAL BOLD SMALL EPSILON + return rune(0x01d6c6), true + case "b.epsiv": + // MATHEMATICAL BOLD EPSILON SYMBOL + return rune(0x01d6dc), true + case "b.eta": + // MATHEMATICAL BOLD SMALL ETA + return rune(0x01d6c8), true + case "b.gammad": + // MATHEMATICAL BOLD SMALL DIGAMMA + return rune(0x01d7cb), true + case "b.gamma": + // MATHEMATICAL BOLD SMALL GAMMA + return rune(0x01d6c4), true + case "b.iota": + // MATHEMATICAL BOLD SMALL IOTA + return rune(0x01d6ca), true + case "b.kappa": + // MATHEMATICAL BOLD SMALL KAPPA + return rune(0x01d6cb), true + case "b.kappav": + // MATHEMATICAL BOLD KAPPA SYMBOL + return rune(0x01d6de), true + case "b.lambda": + // MATHEMATICAL BOLD SMALL LAMDA + return rune(0x01d6cc), true + case "b.mu": + // MATHEMATICAL BOLD SMALL MU + return rune(0x01d6cd), true + case "b.nu": + // MATHEMATICAL BOLD SMALL NU + return rune(0x01d6ce), true + case "b.omega": + // MATHEMATICAL BOLD SMALL OMEGA + return rune(0x01d6da), true + case "b.phi": + // MATHEMATICAL BOLD SMALL PHI + return rune(0x01d6d7), true + case "b.phiv": + // MATHEMATICAL BOLD PHI SYMBOL + return rune(0x01d6df), true + case "b.pi": + // MATHEMATICAL BOLD SMALL PI + return rune(0x01d6d1), true + case "b.piv": + // MATHEMATICAL BOLD PI SYMBOL + return rune(0x01d6e1), true + case "b.psi": + // MATHEMATICAL BOLD SMALL PSI + return rune(0x01d6d9), true + case "b.rho": + // MATHEMATICAL BOLD SMALL RHO + return rune(0x01d6d2), true + case "b.rhov": + // MATHEMATICAL BOLD RHO SYMBOL + return rune(0x01d6e0), true + case "b.sigmav": + // MATHEMATICAL BOLD SMALL FINAL SIGMA + return rune(0x01d6d3), true + case "b.sigma": + // MATHEMATICAL BOLD SMALL SIGMA + return rune(0x01d6d4), true + case "b.tau": + // MATHEMATICAL BOLD SMALL TAU + return rune(0x01d6d5), true + case "b.thetas": + // MATHEMATICAL BOLD SMALL THETA + return rune(0x01d6c9), true + case "b.thetav": + // MATHEMATICAL BOLD THETA SYMBOL + return rune(0x01d6dd), true + case "b.upsi": + // MATHEMATICAL BOLD SMALL UPSILON + return rune(0x01d6d6), true + case "b.xi": + // MATHEMATICAL BOLD SMALL XI + return rune(0x01d6cf), true + case "b.zeta": + // MATHEMATICAL BOLD SMALL ZETA + return rune(0x01d6c7), true + case "bNot": + // REVERSED DOUBLE STROKE NOT SIGN + return rune(0x2aed), true + case "backcong": + // ALL EQUAL TO + return rune(0x224c), true + case "backepsilon": + // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "backprime": + // REVERSED PRIME + return rune(0x2035), true + case "backsimeq": + // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "backsim": + // REVERSED TILDE + return rune(0x223d), true + case "barV": + // DOUBLE DOWN TACK + return rune(0x2aea), true + case "barvee": + // NOR + return rune(0x22bd), true + case "barwed": + // PROJECTIVE + return rune(0x2305), true + case "barwedge": + // PROJECTIVE + return rune(0x2305), true + case "bbrk": + // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "bbrktbrk": + // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET + return rune(0x23b6), true + case "bcong": + // ALL EQUAL TO + return rune(0x224c), true + case "bcy": + // CYRILLIC SMALL LETTER BE + return rune(0x0431), true + case "bdlhar": + // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "bdquo": + // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "bdrhar": + // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "because": + // BECAUSE + return rune(0x2235), true + case "becaus": + // BECAUSE + return rune(0x2235), true + case "bemptyv": + // REVERSED EMPTY SET + return rune(0x29b0), true + case "bepsi": + // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "bernou": + // SCRIPT CAPITAL B + return rune(0x212c), true + case "beta": + // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "beth": + // BET SYMBOL + return rune(0x2136), true + case "between": + // BETWEEN + return rune(0x226c), true + case "bfr": + // MATHEMATICAL FRAKTUR SMALL B + return rune(0x01d51f), true + case "bgr": + // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "bigcap": + // N-ARY INTERSECTION + return rune(0x22c2), true + case "bigcirc": + // LARGE CIRCLE + return rune(0x25ef), true + case "bigcup": + // N-ARY UNION + return rune(0x22c3), true + case "bigodot": + // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "bigoplus": + // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "bigotimes": + // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "bigsqcup": + // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "bigstar": + // BLACK STAR + return rune(0x2605), true + case "bigtriangledown": + // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "bigtriangleup": + // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "biguplus": + // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "bigvee": + // N-ARY LOGICAL OR + return rune(0x22c1), true + case "bigwedge": + // N-ARY LOGICAL AND + return rune(0x22c0), true + case "bkarow": + // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "blacklozenge": + // BLACK LOZENGE + return rune(0x29eb), true + case "blacksquare": + // BLACK SMALL SQUARE + return rune(0x25aa), true + case "blacktriangledown": + // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "blacktriangleleft": + // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "blacktriangleright": + // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "blacktriangle": + // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "blank": + // BLANK SYMBOL + return rune(0x2422), true + case "bldhar": + // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "blk12": + // MEDIUM SHADE + return rune(0x2592), true + case "blk14": + // LIGHT SHADE + return rune(0x2591), true + case "blk34": + // DARK SHADE + return rune(0x2593), true + case "block": + // FULL BLOCK + return rune(0x2588), true + case "bluhar": + // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "bnequiv": + // IDENTICAL TO with reverse slash + return rune(0x2261), true + case "bne": + // EQUALS SIGN with reverse slash + return rune(0x3d), true + case "bnot": + // REVERSED NOT SIGN + return rune(0x2310), true + case "bopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL B + return rune(0x01d553), true + case "bot": + // UP TACK + return rune(0x22a5), true + case "bottom": + // UP TACK + return rune(0x22a5), true + case "bowtie": + // BOWTIE + return rune(0x22c8), true + case "boxDL": + // BOX DRAWINGS DOUBLE DOWN AND LEFT + return rune(0x2557), true + case "boxDR": + // BOX DRAWINGS DOUBLE DOWN AND RIGHT + return rune(0x2554), true + case "boxDl": + // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + return rune(0x2556), true + case "boxDr": + // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + return rune(0x2553), true + case "boxHD": + // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + return rune(0x2566), true + case "boxHU": + // BOX DRAWINGS DOUBLE UP AND HORIZONTAL + return rune(0x2569), true + case "boxHd": + // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + return rune(0x2564), true + case "boxHu": + // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + return rune(0x2567), true + case "boxH": + // BOX DRAWINGS DOUBLE HORIZONTAL + return rune(0x2550), true + case "boxUL": + // BOX DRAWINGS DOUBLE UP AND LEFT + return rune(0x255d), true + case "boxUR": + // BOX DRAWINGS DOUBLE UP AND RIGHT + return rune(0x255a), true + case "boxUl": + // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + return rune(0x255c), true + case "boxUr": + // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + return rune(0x2559), true + case "boxVH": + // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + return rune(0x256c), true + case "boxVL": + // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + return rune(0x2563), true + case "boxVR": + // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + return rune(0x2560), true + case "boxVh": + // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + return rune(0x256b), true + case "boxVl": + // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + return rune(0x2562), true + case "boxVr": + // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + return rune(0x255f), true + case "boxV": + // BOX DRAWINGS DOUBLE VERTICAL + return rune(0x2551), true + case "boxbox": + // TWO JOINED SQUARES + return rune(0x29c9), true + case "boxdL": + // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + return rune(0x2555), true + case "boxdR": + // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + return rune(0x2552), true + case "boxdl": + // BOX DRAWINGS LIGHT DOWN AND LEFT + return rune(0x2510), true + case "boxdr": + // BOX DRAWINGS LIGHT DOWN AND RIGHT + return rune(0x250c), true + case "boxhU": + // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + return rune(0x2568), true + case "boxh": + // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "boxhD": + // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + return rune(0x2565), true + case "boxhd": + // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + return rune(0x252c), true + case "boxhu": + // BOX DRAWINGS LIGHT UP AND HORIZONTAL + return rune(0x2534), true + case "boxminus": + // SQUARED MINUS + return rune(0x229f), true + case "boxplus": + // SQUARED PLUS + return rune(0x229e), true + case "boxtimes": + // SQUARED TIMES + return rune(0x22a0), true + case "boxuL": + // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + return rune(0x255b), true + case "boxuR": + // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + return rune(0x2558), true + case "boxul": + // BOX DRAWINGS LIGHT UP AND LEFT + return rune(0x2518), true + case "boxur": + // BOX DRAWINGS LIGHT UP AND RIGHT + return rune(0x2514), true + case "boxvL": + // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + return rune(0x2561), true + case "boxvR": + // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + return rune(0x255e), true + case "boxvl": + // BOX DRAWINGS LIGHT VERTICAL AND LEFT + return rune(0x2524), true + case "boxvr": + // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + return rune(0x251c), true + case "boxv": + // BOX DRAWINGS LIGHT VERTICAL + return rune(0x2502), true + case "boxvH": + // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + return rune(0x256a), true + case "boxvh": + // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + return rune(0x253c), true + case "bprime": + // REVERSED PRIME + return rune(0x2035), true + case "brdhar": + // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "breve": + // BREVE + return rune(0x02d8), true + case "bruhar": + // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "brvbar": + // BROKEN BAR + return rune(0xa6), true + case "bscr": + // MATHEMATICAL SCRIPT SMALL B + return rune(0x01d4b7), true + case "bsemi": + // REVERSED SEMICOLON + return rune(0x204f), true + case "bsim": + // REVERSED TILDE + return rune(0x223d), true + case "bsime": + // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "bsolb": + // SQUARED FALLING DIAGONAL SLASH + return rune(0x29c5), true + case "bsolhsub": + // REVERSE SOLIDUS PRECEDING SUBSET + return rune(0x27c8), true + case "bsol": + // REVERSE SOLIDUS + return rune(0x5c), true + case "btimes": + // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED + return rune(0x2a32), true + case "bulhar": + // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "bullet": + // BULLET + return rune(0x2022), true + case "bull": + // BULLET + return rune(0x2022), true + case "bump": + // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "bumpE": + // EQUALS SIGN WITH BUMPY ABOVE + return rune(0x2aae), true + case "bumpe": + // DIFFERENCE BETWEEN + return rune(0x224f), true + case "bumpeq": + // DIFFERENCE BETWEEN + return rune(0x224f), true + case "burhar": + // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true + } + + case 'c': + switch name { + case "cacute": + // LATIN SMALL LETTER C WITH ACUTE + return rune(0x0107), true + case "cap": + // INTERSECTION + return rune(0x2229), true + case "capand": + // INTERSECTION WITH LOGICAL AND + return rune(0x2a44), true + case "capbrcup": + // INTERSECTION ABOVE BAR ABOVE UNION + return rune(0x2a49), true + case "capcap": + // INTERSECTION BESIDE AND JOINED WITH INTERSECTION + return rune(0x2a4b), true + case "capcup": + // INTERSECTION ABOVE UNION + return rune(0x2a47), true + case "capdot": + // INTERSECTION WITH DOT + return rune(0x2a40), true + case "capint": + // INTEGRAL WITH INTERSECTION + return rune(0x2a19), true + case "caps": + // INTERSECTION with serifs + return rune(0x2229), true + case "caret": + // CARET INSERTION POINT + return rune(0x2041), true + case "caron": + // CARON + return rune(0x02c7), true + case "ccaps": + // CLOSED INTERSECTION WITH SERIFS + return rune(0x2a4d), true + case "ccaron": + // LATIN SMALL LETTER C WITH CARON + return rune(0x010d), true + case "ccedil": + // LATIN SMALL LETTER C WITH CEDILLA + return rune(0xe7), true + case "ccirc": + // LATIN SMALL LETTER C WITH CIRCUMFLEX + return rune(0x0109), true + case "ccups": + // CLOSED UNION WITH SERIFS + return rune(0x2a4c), true + case "ccupssm": + // CLOSED UNION WITH SERIFS AND SMASH PRODUCT + return rune(0x2a50), true + case "cdot": + // LATIN SMALL LETTER C WITH DOT ABOVE + return rune(0x010b), true + case "cedil": + // CEDILLA + return rune(0xb8), true + case "cemptyv": + // EMPTY SET WITH SMALL CIRCLE ABOVE + return rune(0x29b2), true + case "centerdot": + // MIDDLE DOT + return rune(0xb7), true + case "cent": + // CENT SIGN + return rune(0xa2), true + case "cfr": + // MATHEMATICAL FRAKTUR SMALL C + return rune(0x01d520), true + case "chcy": + // CYRILLIC SMALL LETTER CHE + return rune(0x0447), true + case "check": + // CHECK MARK + return rune(0x2713), true + case "checkmark": + // CHECK MARK + return rune(0x2713), true + case "chi": + // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "circeq": + // RING EQUAL TO + return rune(0x2257), true + case "circlearrowleft": + // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "circlearrowright": + // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "circledS": + // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "circledast": + // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "circledcirc": + // CIRCLED RING OPERATOR + return rune(0x229a), true + case "circleddash": + // CIRCLED DASH + return rune(0x229d), true + case "cire": + // RING EQUAL TO + return rune(0x2257), true + case "cir": + // WHITE CIRCLE + return rune(0x25cb), true + case "cirE": + // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT + return rune(0x29c3), true + case "cirb": + // SQUARED SMALL CIRCLE + return rune(0x29c7), true + case "circ": + // MODIFIER LETTER CIRCUMFLEX ACCENT + return rune(0x02c6), true + case "circledR": + // REGISTERED SIGN + return rune(0xae), true + case "cirdarr": + // WHITE CIRCLE WITH DOWN ARROW + return rune(0x29ec), true + case "cirerr": + // ERROR-BARRED WHITE CIRCLE + return rune(0x29f2), true + case "cirfdarr": + // BLACK CIRCLE WITH DOWN ARROW + return rune(0x29ed), true + case "cirferr": + // ERROR-BARRED BLACK CIRCLE + return rune(0x29f3), true + case "cirfnint": + // CIRCULATION FUNCTION + return rune(0x2a10), true + case "cirmid": + // VERTICAL LINE WITH CIRCLE ABOVE + return rune(0x2aef), true + case "cirscir": + // CIRCLE WITH SMALL CIRCLE TO THE RIGHT + return rune(0x29c2), true + case "closur": + // CLOSE UP + return rune(0x2050), true + case "clubs": + // BLACK CLUB SUIT + return rune(0x2663), true + case "clubsuit": + // BLACK CLUB SUIT + return rune(0x2663), true + case "colone": + // COLON EQUALS + return rune(0x2254), true + case "coloneq": + // COLON EQUALS + return rune(0x2254), true + case "colon": + // COLON + return rune(0x3a), true + case "commat": + // COMMERCIAL AT + return rune(0x40), true + case "comma": + // COMMA + return rune(0x2c), true + case "comp": + // COMPLEMENT + return rune(0x2201), true + case "compfn": + // RING OPERATOR + return rune(0x2218), true + case "complement": + // COMPLEMENT + return rune(0x2201), true + case "complexes": + // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "cong": + // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "congdot": + // CONGRUENT WITH DOT ABOVE + return rune(0x2a6d), true + case "conint": + // CONTOUR INTEGRAL + return rune(0x222e), true + case "copf": + // MATHEMATICAL DOUBLE-STRUCK SMALL C + return rune(0x01d554), true + case "coprod": + // N-ARY COPRODUCT + return rune(0x2210), true + case "copysr": + // SOUND RECORDING COPYRIGHT + return rune(0x2117), true + case "copy": + // COPYRIGHT SIGN + return rune(0xa9), true + case "crarr": + // DOWNWARDS ARROW WITH CORNER LEFTWARDS + return rune(0x21b5), true + case "cross": + // BALLOT X + return rune(0x2717), true + case "cscr": + // MATHEMATICAL SCRIPT SMALL C + return rune(0x01d4b8), true + case "csub": + // CLOSED SUBSET + return rune(0x2acf), true + case "csube": + // CLOSED SUBSET OR EQUAL TO + return rune(0x2ad1), true + case "csup": + // CLOSED SUPERSET + return rune(0x2ad0), true + case "csupe": + // CLOSED SUPERSET OR EQUAL TO + return rune(0x2ad2), true + case "ctdot": + // MIDLINE HORIZONTAL ELLIPSIS + return rune(0x22ef), true + case "cudarrl": + // RIGHT-SIDE ARC CLOCKWISE ARROW + return rune(0x2938), true + case "cudarrr": + // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS + return rune(0x2935), true + case "cuepr": + // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "cuesc": + // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "cularr": + // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "cularrp": + // TOP ARC ANTICLOCKWISE ARROW WITH PLUS + return rune(0x293d), true + case "cup": + // UNION + return rune(0x222a), true + case "cupbrcap": + // UNION ABOVE BAR ABOVE INTERSECTION + return rune(0x2a48), true + case "cupcap": + // UNION ABOVE INTERSECTION + return rune(0x2a46), true + case "cupcup": + // UNION BESIDE AND JOINED WITH UNION + return rune(0x2a4a), true + case "cupdot": + // MULTISET MULTIPLICATION + return rune(0x228d), true + case "cupint": + // INTEGRAL WITH UNION + return rune(0x2a1a), true + case "cupor": + // UNION WITH LOGICAL OR + return rune(0x2a45), true + case "cupre": + // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "cups": + // UNION with serifs + return rune(0x222a), true + case "curarr": + // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "curarrm": + // TOP ARC CLOCKWISE ARROW WITH MINUS + return rune(0x293c), true + case "curlyeqprec": + // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "curlyeqsucc": + // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "curlyvee": + // CURLY LOGICAL OR + return rune(0x22ce), true + case "curlywedge": + // CURLY LOGICAL AND + return rune(0x22cf), true + case "curren": + // CURRENCY SIGN + return rune(0xa4), true + case "curvearrowleft": + // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "curvearrowright": + // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "cuvee": + // CURLY LOGICAL OR + return rune(0x22ce), true + case "cuwed": + // CURLY LOGICAL AND + return rune(0x22cf), true + case "cwconint": + // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "cwint": + // CLOCKWISE INTEGRAL + return rune(0x2231), true + case "cylcty": + // CYLINDRICITY + return rune(0x232d), true + } + + case 'd': + switch name { + case "dAarr": + // DOWNWARDS TRIPLE ARROW + return rune(0x290b), true + case "dArr": + // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "dHar": + // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x2965), true + case "dagger": + // DAGGER + return rune(0x2020), true + case "dalembrt": + // SQUARE WITH CONTOURED OUTLINE + return rune(0x29e0), true + case "daleth": + // DALET SYMBOL + return rune(0x2138), true + case "darr2": + // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "darr": + // DOWNWARDS ARROW + return rune(0x2193), true + case "darrb": + // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "darrln": + // DOWNWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2908), true + case "dashv": + // LEFT TACK + return rune(0x22a3), true + case "dash": + // HYPHEN + return rune(0x2010), true + case "dashV": + // DOUBLE VERTICAL BAR LEFT TURNSTILE + return rune(0x2ae3), true + case "dbkarow": + // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "dblac": + // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "dcaron": + // LATIN SMALL LETTER D WITH CARON + return rune(0x010f), true + case "dcy": + // CYRILLIC SMALL LETTER DE + return rune(0x0434), true + case "ddarr": + // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "dd": + // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "ddagger": + // DOUBLE DAGGER + return rune(0x2021), true + case "ddotseq": + // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "deg": + // DEGREE SIGN + return rune(0xb0), true + case "delta": + // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "demptyv": + // EMPTY SET WITH OVERBAR + return rune(0x29b1), true + case "dfisht": + // DOWN FISH TAIL + return rune(0x297f), true + case "dfr": + // MATHEMATICAL FRAKTUR SMALL D + return rune(0x01d521), true + case "dgr": + // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "dharl": + // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "dharr": + // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "diam": + // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamdarr": + // BLACK DIAMOND WITH DOWN ARROW + return rune(0x29ea), true + case "diamerr": + // ERROR-BARRED WHITE DIAMOND + return rune(0x29f0), true + case "diamerrf": + // ERROR-BARRED BLACK DIAMOND + return rune(0x29f1), true + case "diamond": + // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamondsuit": + // BLACK DIAMOND SUIT + return rune(0x2666), true + case "diams": + // BLACK DIAMOND SUIT + return rune(0x2666), true + case "die": + // DIAERESIS + return rune(0xa8), true + case "digamma": + // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "disin": + // ELEMENT OF WITH LONG HORIZONTAL STROKE + return rune(0x22f2), true + case "divideontimes": + // DIVISION TIMES + return rune(0x22c7), true + case "divonx": + // DIVISION TIMES + return rune(0x22c7), true + case "div": + // DIVISION SIGN + return rune(0xf7), true + case "divide": + // DIVISION SIGN + return rune(0xf7), true + case "djcy": + // CYRILLIC SMALL LETTER DJE + return rune(0x0452), true + case "dlarr": + // SOUTH WEST ARROW + return rune(0x2199), true + case "dlcorn": + // BOTTOM LEFT CORNER + return rune(0x231e), true + case "dlcrop": + // BOTTOM LEFT CROP + return rune(0x230d), true + case "dlharb": + // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "dollar": + // DOLLAR SIGN + return rune(0x24), true + case "dopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL D + return rune(0x01d555), true + case "doteq": + // APPROACHES THE LIMIT + return rune(0x2250), true + case "doteqdot": + // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "dotminus": + // DOT MINUS + return rune(0x2238), true + case "dotplus": + // DOT PLUS + return rune(0x2214), true + case "dotsquare": + // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "dot": + // DOT ABOVE + return rune(0x02d9), true + case "doublebarwedge": + // PERSPECTIVE + return rune(0x2306), true + case "downarrow": + // DOWNWARDS ARROW + return rune(0x2193), true + case "downdownarrows": + // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "downharpoonleft": + // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "downharpoonright": + // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "drarr": + // SOUTH EAST ARROW + return rune(0x2198), true + case "drbkarow": + // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "drcorn": + // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "drcrop": + // BOTTOM RIGHT CROP + return rune(0x230c), true + case "drharb": + // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "dscr": + // MATHEMATICAL SCRIPT SMALL D + return rune(0x01d4b9), true + case "dscy": + // CYRILLIC SMALL LETTER DZE + return rune(0x0455), true + case "dsol": + // SOLIDUS WITH OVERBAR + return rune(0x29f6), true + case "dstrok": + // LATIN SMALL LETTER D WITH STROKE + return rune(0x0111), true + case "dtdot": + // DOWN RIGHT DIAGONAL ELLIPSIS + return rune(0x22f1), true + case "dtrif": + // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "dtri": + // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "dtrilf": + // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK + return rune(0x29e8), true + case "dtrirf": + // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK + return rune(0x29e9), true + case "duarr": + // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "duhar": + // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "dumap": + // DOUBLE-ENDED MULTIMAP + return rune(0x29df), true + case "dwangle": + // OBLIQUE ANGLE OPENING UP + return rune(0x29a6), true + case "dzcy": + // CYRILLIC SMALL LETTER DZHE + return rune(0x045f), true + case "dzigrarr": + // LONG RIGHTWARDS SQUIGGLE ARROW + return rune(0x27ff), true + } + + case 'e': + switch name { + case "eDDot": + // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "eDot": + // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "eacgr": + // GREEK SMALL LETTER EPSILON WITH TONOS + return rune(0x03ad), true + case "eacute": + // LATIN SMALL LETTER E WITH ACUTE + return rune(0xe9), true + case "easter": + // EQUALS WITH ASTERISK + return rune(0x2a6e), true + case "ecaron": + // LATIN SMALL LETTER E WITH CARON + return rune(0x011b), true + case "ecir": + // RING IN EQUAL TO + return rune(0x2256), true + case "ecirc": + // LATIN SMALL LETTER E WITH CIRCUMFLEX + return rune(0xea), true + case "ecolon": + // EQUALS COLON + return rune(0x2255), true + case "ecy": + // CYRILLIC SMALL LETTER E + return rune(0x044d), true + case "edot": + // LATIN SMALL LETTER E WITH DOT ABOVE + return rune(0x0117), true + case "ee": + // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true + case "eeacgr": + // GREEK SMALL LETTER ETA WITH TONOS + return rune(0x03ae), true + case "eegr": + // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "efDot": + // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "efr": + // MATHEMATICAL FRAKTUR SMALL E + return rune(0x01d522), true + case "egr": + // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "egs": + // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "egsdot": + // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE + return rune(0x2a98), true + case "eg": + // DOUBLE-LINE EQUAL TO OR GREATER-THAN + return rune(0x2a9a), true + case "egrave": + // LATIN SMALL LETTER E WITH GRAVE + return rune(0xe8), true + case "elinters": + // ELECTRICAL INTERSECTION + return rune(0x23e7), true + case "ell": + // SCRIPT SMALL L + return rune(0x2113), true + case "els": + // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "elsdot": + // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE + return rune(0x2a97), true + case "el": + // DOUBLE-LINE EQUAL TO OR LESS-THAN + return rune(0x2a99), true + case "emacr": + // LATIN SMALL LETTER E WITH MACRON + return rune(0x0113), true + case "empty": + // EMPTY SET + return rune(0x2205), true + case "emptyset": + // EMPTY SET + return rune(0x2205), true + case "emptyv": + // EMPTY SET + return rune(0x2205), true + case "emsp13": + // THREE-PER-EM SPACE + return rune(0x2004), true + case "emsp14": + // FOUR-PER-EM SPACE + return rune(0x2005), true + case "emsp": + // EM SPACE + return rune(0x2003), true + case "eng": + // LATIN SMALL LETTER ENG + return rune(0x014b), true + case "ensp": + // EN SPACE + return rune(0x2002), true + case "eogon": + // LATIN SMALL LETTER E WITH OGONEK + return rune(0x0119), true + case "eopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL E + return rune(0x01d556), true + case "epar": + // EQUAL AND PARALLEL TO + return rune(0x22d5), true + case "eparsl": + // EQUALS SIGN AND SLANTED PARALLEL + return rune(0x29e3), true + case "eplus": + // EQUALS SIGN ABOVE PLUS SIGN + return rune(0x2a71), true + case "epsilon": + // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "epsis": + // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "epsiv": + // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "epsi": + // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "eqcirc": + // RING IN EQUAL TO + return rune(0x2256), true + case "eqcolon": + // EQUALS COLON + return rune(0x2255), true + case "eqeq": + // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "eqsim": + // MINUS TILDE + return rune(0x2242), true + case "eqslantgtr": + // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "eqslantless": + // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "equals": + // EQUALS SIGN + return rune(0x3d), true + case "equest": + // QUESTIONED EQUAL TO + return rune(0x225f), true + case "equiv": + // IDENTICAL TO + return rune(0x2261), true + case "equivDD": + // EQUIVALENT WITH FOUR DOTS ABOVE + return rune(0x2a78), true + case "eqvparsl": + // IDENTICAL TO AND SLANTED PARALLEL + return rune(0x29e5), true + case "erDot": + // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "erarr": + // EQUALS SIGN ABOVE RIGHTWARDS ARROW + return rune(0x2971), true + case "escr": + // SCRIPT SMALL E + return rune(0x212f), true + case "esdot": + // APPROACHES THE LIMIT + return rune(0x2250), true + case "esim": + // MINUS TILDE + return rune(0x2242), true + case "eta": + // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "eth": + // LATIN SMALL LETTER ETH + return rune(0xf0), true + case "euml": + // LATIN SMALL LETTER E WITH DIAERESIS + return rune(0xeb), true + case "euro": + // EURO SIGN + return rune(0x20ac), true + case "excl": + // EXCLAMATION MARK + return rune(0x21), true + case "exist": + // THERE EXISTS + return rune(0x2203), true + case "expectation": + // SCRIPT CAPITAL E + return rune(0x2130), true + case "exponentiale": + // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true + } + + case 'f': + switch name { + case "fallingdotseq": + // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "fbowtie": + // BLACK BOWTIE + return rune(0x29d3), true + case "fcy": + // CYRILLIC SMALL LETTER EF + return rune(0x0444), true + case "fdiag": + // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "fdiordi": + // FALLING DIAGONAL CROSSING RISING DIAGONAL + return rune(0x292c), true + case "fdonearr": + // FALLING DIAGONAL CROSSING NORTH EAST ARROW + return rune(0x292f), true + case "female": + // FEMALE SIGN + return rune(0x2640), true + case "ffilig": + // LATIN SMALL LIGATURE FFI + return rune(0xfb03), true + case "fflig": + // LATIN SMALL LIGATURE FF + return rune(0xfb00), true + case "ffllig": + // LATIN SMALL LIGATURE FFL + return rune(0xfb04), true + case "ffr": + // MATHEMATICAL FRAKTUR SMALL F + return rune(0x01d523), true + case "fhrglass": + // BLACK HOURGLASS + return rune(0x29d7), true + case "filig": + // LATIN SMALL LIGATURE FI + return rune(0xfb01), true + case "fjlig": + // fj ligature + return rune(0x66), true + case "flat": + // MUSIC FLAT SIGN + return rune(0x266d), true + case "fllig": + // LATIN SMALL LIGATURE FL + return rune(0xfb02), true + case "fltns": + // WHITE PARALLELOGRAM + return rune(0x25b1), true + case "fnof": + // LATIN SMALL LETTER F WITH HOOK + return rune(0x0192), true + case "fopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL F + return rune(0x01d557), true + case "forall": + // FOR ALL + return rune(0x2200), true + case "fork": + // PITCHFORK + return rune(0x22d4), true + case "forkv": + // ELEMENT OF OPENING DOWNWARDS + return rune(0x2ad9), true + case "fpartint": + // FINITE PART INTEGRAL + return rune(0x2a0d), true + case "frac12": + // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "frac13": + // VULGAR FRACTION ONE THIRD + return rune(0x2153), true + case "frac14": + // VULGAR FRACTION ONE QUARTER + return rune(0xbc), true + case "frac15": + // VULGAR FRACTION ONE FIFTH + return rune(0x2155), true + case "frac16": + // VULGAR FRACTION ONE SIXTH + return rune(0x2159), true + case "frac18": + // VULGAR FRACTION ONE EIGHTH + return rune(0x215b), true + case "frac23": + // VULGAR FRACTION TWO THIRDS + return rune(0x2154), true + case "frac25": + // VULGAR FRACTION TWO FIFTHS + return rune(0x2156), true + case "frac34": + // VULGAR FRACTION THREE QUARTERS + return rune(0xbe), true + case "frac35": + // VULGAR FRACTION THREE FIFTHS + return rune(0x2157), true + case "frac38": + // VULGAR FRACTION THREE EIGHTHS + return rune(0x215c), true + case "frac45": + // VULGAR FRACTION FOUR FIFTHS + return rune(0x2158), true + case "frac56": + // VULGAR FRACTION FIVE SIXTHS + return rune(0x215a), true + case "frac58": + // VULGAR FRACTION FIVE EIGHTHS + return rune(0x215d), true + case "frac78": + // VULGAR FRACTION SEVEN EIGHTHS + return rune(0x215e), true + case "frasl": + // FRACTION SLASH + return rune(0x2044), true + case "frown": + // FROWN + return rune(0x2322), true + case "fscr": + // MATHEMATICAL SCRIPT SMALL F + return rune(0x01d4bb), true + } + + case 'g': + switch name { + case "gE": + // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "gEl": + // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gacute": + // LATIN SMALL LETTER G WITH ACUTE + return rune(0x01f5), true + case "gammad": + // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "gamma": + // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gap": + // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gbreve": + // LATIN SMALL LETTER G WITH BREVE + return rune(0x011f), true + case "gcedil": + // LATIN SMALL LETTER G WITH CEDILLA + return rune(0x0123), true + case "gcirc": + // LATIN SMALL LETTER G WITH CIRCUMFLEX + return rune(0x011d), true + case "gcy": + // CYRILLIC SMALL LETTER GHE + return rune(0x0433), true + case "gdot": + // LATIN SMALL LETTER G WITH DOT ABOVE + return rune(0x0121), true + case "ge": + // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "gel": + // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "geq": + // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "geqq": + // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "geqslant": + // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "gesl": + // GREATER-THAN slanted EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "ges": + // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "gescc": + // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa9), true + case "gesdot": + // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a80), true + case "gesdoto": + // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a82), true + case "gesdotol": + // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT + return rune(0x2a84), true + case "gesles": + // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL + return rune(0x2a94), true + case "gfr": + // MATHEMATICAL FRAKTUR SMALL G + return rune(0x01d524), true + case "gg": + // MUCH GREATER-THAN + return rune(0x226b), true + case "ggg": + // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "ggr": + // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gimel": + // GIMEL SYMBOL + return rune(0x2137), true + case "gjcy": + // CYRILLIC SMALL LETTER GJE + return rune(0x0453), true + case "gl": + // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "glE": + // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a92), true + case "gla": + // GREATER-THAN BESIDE LESS-THAN + return rune(0x2aa5), true + case "glj": + // GREATER-THAN OVERLAPPING LESS-THAN + return rune(0x2aa4), true + case "gnE": + // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gnap": + // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gnapprox": + // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gneqq": + // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gne": + // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gneq": + // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gnsim": + // GREATER-THAN BUT NOT EQUIVALENT TO + return rune(0x22e7), true + case "gopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL G + return rune(0x01d558), true + case "grave": + // GRAVE ACCENT + return rune(0x60), true + case "gscr": + // SCRIPT SMALL G + return rune(0x210a), true + case "gsdot": + // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gsim": + // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gsime": + // GREATER-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8e), true + case "gsiml": + // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN + return rune(0x2a90), true + case "gtcc": + // GREATER-THAN CLOSED BY CURVE + return rune(0x2aa7), true + case "gtcir": + // GREATER-THAN WITH CIRCLE INSIDE + return rune(0x2a7a), true + case "gtdot": + // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtlPar": + // DOUBLE LEFT ARC GREATER-THAN BRACKET + return rune(0x2995), true + case "gtquest": + // GREATER-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7c), true + case "gtrapprox": + // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gtrarr": + // GREATER-THAN ABOVE RIGHTWARDS ARROW + return rune(0x2978), true + case "gtrdot": + // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtreqless": + // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "gtreqqless": + // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gtrless": + // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "gtrpar": + // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "gtrsim": + // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gt": + // GREATER-THAN SIGN + return rune(0x3e), true + case "gvertneqq": + // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true + case "gvnE": + // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true + } + + case 'h': + switch name { + case "hArr": + // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "hairsp": + // HAIR SPACE + return rune(0x200a), true + case "half": + // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "hamilt": + // SCRIPT CAPITAL H + return rune(0x210b), true + case "hardcy": + // CYRILLIC SMALL LETTER HARD SIGN + return rune(0x044a), true + case "harrw": + // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "harr": + // LEFT RIGHT ARROW + return rune(0x2194), true + case "harrcir": + // LEFT RIGHT ARROW THROUGH SMALL CIRCLE + return rune(0x2948), true + case "hbar": + // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hcirc": + // LATIN SMALL LETTER H WITH CIRCUMFLEX + return rune(0x0125), true + case "hearts": + // BLACK HEART SUIT + return rune(0x2665), true + case "heartsuit": + // BLACK HEART SUIT + return rune(0x2665), true + case "hellip": + // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "hercon": + // HERMITIAN CONJUGATE MATRIX + return rune(0x22b9), true + case "hfr": + // MATHEMATICAL FRAKTUR SMALL H + return rune(0x01d525), true + case "hksearow": + // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "hkswarow": + // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "hoarr": + // LEFT RIGHT OPEN-HEADED ARROW + return rune(0x21ff), true + case "homtht": + // HOMOTHETIC + return rune(0x223b), true + case "hookleftarrow": + // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "hookrightarrow": + // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "hopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL H + return rune(0x01d559), true + case "horbar": + // HORIZONTAL BAR + return rune(0x2015), true + case "hrglass": + // WHITE HOURGLASS + return rune(0x29d6), true + case "hscr": + // MATHEMATICAL SCRIPT SMALL H + return rune(0x01d4bd), true + case "hslash": + // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hstrok": + // LATIN SMALL LETTER H WITH STROKE + return rune(0x0127), true + case "htimes": + // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "hybull": + // HYPHEN BULLET + return rune(0x2043), true + case "hyphen": + // HYPHEN + return rune(0x2010), true + } + + case 'i': + switch name { + case "iacgr": + // GREEK SMALL LETTER IOTA WITH TONOS + return rune(0x03af), true + case "iacute": + // LATIN SMALL LETTER I WITH ACUTE + return rune(0xed), true + case "ic": + // INVISIBLE SEPARATOR + return rune(0x2063), true + case "icirc": + // LATIN SMALL LETTER I WITH CIRCUMFLEX + return rune(0xee), true + case "icy": + // CYRILLIC SMALL LETTER I + return rune(0x0438), true + case "idiagr": + // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + return rune(0x0390), true + case "idigr": + // GREEK SMALL LETTER IOTA WITH DIALYTIKA + return rune(0x03ca), true + case "iecy": + // CYRILLIC SMALL LETTER IE + return rune(0x0435), true + case "iexcl": + // INVERTED EXCLAMATION MARK + return rune(0xa1), true + case "iff": + // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "ifr": + // MATHEMATICAL FRAKTUR SMALL I + return rune(0x01d526), true + case "igr": + // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "igrave": + // LATIN SMALL LETTER I WITH GRAVE + return rune(0xec), true + case "iiint": + // TRIPLE INTEGRAL + return rune(0x222d), true + case "ii": + // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "iiiint": + // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "iinfin": + // INCOMPLETE INFINITY + return rune(0x29dc), true + case "iiota": + // TURNED GREEK SMALL LETTER IOTA + return rune(0x2129), true + case "ijlig": + // LATIN SMALL LIGATURE IJ + return rune(0x0133), true + case "imacr": + // LATIN SMALL LETTER I WITH MACRON + return rune(0x012b), true + case "image": + // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imagline": + // SCRIPT CAPITAL I + return rune(0x2110), true + case "imagpart": + // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imath": + // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "imof": + // IMAGE OF + return rune(0x22b7), true + case "imped": + // LATIN CAPITAL LETTER Z WITH STROKE + return rune(0x01b5), true + case "in": + // ELEMENT OF + return rune(0x2208), true + case "incare": + // CARE OF + return rune(0x2105), true + case "infin": + // INFINITY + return rune(0x221e), true + case "infintie": + // TIE OVER INFINITY + return rune(0x29dd), true + case "inodot": + // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "int": + // INTEGRAL + return rune(0x222b), true + case "intcal": + // INTERCALATE + return rune(0x22ba), true + case "integers": + // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "intercal": + // INTERCALATE + return rune(0x22ba), true + case "intlarhk": + // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK + return rune(0x2a17), true + case "intprod": + // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iocy": + // CYRILLIC SMALL LETTER IO + return rune(0x0451), true + case "iogon": + // LATIN SMALL LETTER I WITH OGONEK + return rune(0x012f), true + case "iopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL I + return rune(0x01d55a), true + case "iota": + // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "iprod": + // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iprodr": + // RIGHTHAND INTERIOR PRODUCT + return rune(0x2a3d), true + case "iquest": + // INVERTED QUESTION MARK + return rune(0xbf), true + case "iscr": + // MATHEMATICAL SCRIPT SMALL I + return rune(0x01d4be), true + case "isin": + // ELEMENT OF + return rune(0x2208), true + case "isinE": + // ELEMENT OF WITH TWO HORIZONTAL STROKES + return rune(0x22f9), true + case "isindot": + // ELEMENT OF WITH DOT ABOVE + return rune(0x22f5), true + case "isinsv": + // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f3), true + case "isins": + // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f4), true + case "isinv": + // ELEMENT OF + return rune(0x2208), true + case "isinvb": + // ELEMENT OF WITH UNDERBAR + return rune(0x22f8), true + case "it": + // INVISIBLE TIMES + return rune(0x2062), true + case "itilde": + // LATIN SMALL LETTER I WITH TILDE + return rune(0x0129), true + case "iukcy": + // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0456), true + case "iuml": + // LATIN SMALL LETTER I WITH DIAERESIS + return rune(0xef), true + } + + case 'j': + switch name { + case "jcirc": + // LATIN SMALL LETTER J WITH CIRCUMFLEX + return rune(0x0135), true + case "jcy": + // CYRILLIC SMALL LETTER SHORT I + return rune(0x0439), true + case "jfr": + // MATHEMATICAL FRAKTUR SMALL J + return rune(0x01d527), true + case "jmath": + // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jnodot": + // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL J + return rune(0x01d55b), true + case "jscr": + // MATHEMATICAL SCRIPT SMALL J + return rune(0x01d4bf), true + case "jsercy": + // CYRILLIC SMALL LETTER JE + return rune(0x0458), true + case "jukcy": + // CYRILLIC SMALL LETTER UKRAINIAN IE + return rune(0x0454), true + } + + case 'k': + switch name { + case "kappav": + // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "kappa": + // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kcedil": + // LATIN SMALL LETTER K WITH CEDILLA + return rune(0x0137), true + case "kcy": + // CYRILLIC SMALL LETTER KA + return rune(0x043a), true + case "kfr": + // MATHEMATICAL FRAKTUR SMALL K + return rune(0x01d528), true + case "kgr": + // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kgreen": + // LATIN SMALL LETTER KRA + return rune(0x0138), true + case "khcy": + // CYRILLIC SMALL LETTER HA + return rune(0x0445), true + case "khgr": + // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "kjcy": + // CYRILLIC SMALL LETTER KJE + return rune(0x045c), true + case "kopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL K + return rune(0x01d55c), true + case "koppa": + // GREEK LETTER KOPPA + return rune(0x03de), true + case "kscr": + // MATHEMATICAL SCRIPT SMALL K + return rune(0x01d4c0), true + } + + case 'l': + switch name { + case "lAarr": + // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "lArr": + // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "lAtail": + // LEFTWARDS DOUBLE ARROW-TAIL + return rune(0x291b), true + case "lBarr": + // LEFTWARDS TRIPLE DASH ARROW + return rune(0x290e), true + case "lE": + // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "lEg": + // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lHar": + // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2962), true + case "lacute": + // LATIN SMALL LETTER L WITH ACUTE + return rune(0x013a), true + case "laemptyv": + // EMPTY SET WITH LEFT ARROW ABOVE + return rune(0x29b4), true + case "lagran": + // SCRIPT CAPITAL L + return rune(0x2112), true + case "lambda": + // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lang": + // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "langd": + // LEFT ANGLE BRACKET WITH DOT + return rune(0x2991), true + case "langle": + // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "lap": + // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "laquo": + // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xab), true + case "larr2": + // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "larrb": + // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "larrhk": + // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "larrlp": + // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "larrtl": + // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "larr": + // LEFTWARDS ARROW + return rune(0x2190), true + case "larrbfs": + // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x291f), true + case "larrfs": + // LEFTWARDS ARROW TO BLACK DIAMOND + return rune(0x291d), true + case "larrpl": + // LEFT-SIDE ARC ANTICLOCKWISE ARROW + return rune(0x2939), true + case "larrsim": + // LEFTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2973), true + case "latail": + // LEFTWARDS ARROW-TAIL + return rune(0x2919), true + case "lat": + // LARGER THAN + return rune(0x2aab), true + case "late": + // LARGER THAN OR EQUAL TO + return rune(0x2aad), true + case "lates": + // LARGER THAN OR slanted EQUAL + return rune(0x2aad), true + case "lbarr": + // LEFTWARDS DOUBLE DASH ARROW + return rune(0x290c), true + case "lbbrk": + // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2772), true + case "lbrace": + // LEFT CURLY BRACKET + return rune(0x7b), true + case "lbrack": + // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lbrke": + // LEFT SQUARE BRACKET WITH UNDERBAR + return rune(0x298b), true + case "lbrksld": + // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298f), true + case "lbrkslu": + // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x298d), true + case "lcaron": + // LATIN SMALL LETTER L WITH CARON + return rune(0x013e), true + case "lcedil": + // LATIN SMALL LETTER L WITH CEDILLA + return rune(0x013c), true + case "lceil": + // LEFT CEILING + return rune(0x2308), true + case "lcub": + // LEFT CURLY BRACKET + return rune(0x7b), true + case "lcy": + // CYRILLIC SMALL LETTER EL + return rune(0x043b), true + case "ldca": + // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS + return rune(0x2936), true + case "ldharb": + // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "ldot": + // LESS-THAN WITH DOT + return rune(0x22d6), true + case "ldquor": + // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "ldquo": + // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "ldrdhar": + // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2967), true + case "ldrdshar": + // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "ldrushar": + // LEFT BARB DOWN RIGHT BARB UP HARPOON + return rune(0x294b), true + case "ldsh": + // DOWNWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b2), true + case "leftarrowtail": + // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "leftarrow": + // LEFTWARDS ARROW + return rune(0x2190), true + case "leftharpoondown": + // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "leftharpoonup": + // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "leftleftarrows": + // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "leftrightarrows": + // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "leftrightarrow": + // LEFT RIGHT ARROW + return rune(0x2194), true + case "leftrightharpoons": + // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "leftrightsquigarrow": + // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "le": + // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leftthreetimes": + // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "leg": + // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "leq": + // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leqq": + // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "leqslant": + // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "lesg": + // LESS-THAN slanted EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lessdot": + // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lesseqgtr": + // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lessgtr": + // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lesssim": + // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "les": + // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "lescc": + // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa8), true + case "lesdot": + // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a7f), true + case "lesdoto": + // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a81), true + case "lesdotor": + // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT + return rune(0x2a83), true + case "lesges": + // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL + return rune(0x2a93), true + case "lessapprox": + // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "lesseqqgtr": + // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lfbowtie": + // BOWTIE WITH LEFT HALF BLACK + return rune(0x29d1), true + case "lfisht": + // LEFT FISH TAIL + return rune(0x297c), true + case "lfloor": + // LEFT FLOOR + return rune(0x230a), true + case "lfr": + // MATHEMATICAL FRAKTUR SMALL L + return rune(0x01d529), true + case "lftimes": + // TIMES WITH LEFT HALF BLACK + return rune(0x29d4), true + case "lg": + // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lgE": + // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a91), true + case "lgr": + // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lhard": + // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "lharu": + // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "lharul": + // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296a), true + case "lhblk": + // LOWER HALF BLOCK + return rune(0x2584), true + case "ljcy": + // CYRILLIC SMALL LETTER LJE + return rune(0x0459), true + case "llarr": + // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "ll": + // MUCH LESS-THAN + return rune(0x226a), true + case "llcorner": + // BOTTOM LEFT CORNER + return rune(0x231e), true + case "llhard": + // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296b), true + case "lltrif": + // BLACK LOWER LEFT TRIANGLE + return rune(0x25e3), true + case "lltri": + // LOWER LEFT TRIANGLE + return rune(0x25fa), true + case "lmidot": + // LATIN SMALL LETTER L WITH MIDDLE DOT + return rune(0x0140), true + case "lmoust": + // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lmoustache": + // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lnE": + // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lnap": + // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lnapprox": + // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lneqq": + // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lne": + // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lneq": + // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lnsim": + // LESS-THAN BUT NOT EQUIVALENT TO + return rune(0x22e6), true + case "loang": + // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + return rune(0x27ec), true + case "loarr": + // LEFTWARDS OPEN-HEADED ARROW + return rune(0x21fd), true + case "lobrk": + // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "locub": + // LEFT WHITE CURLY BRACKET + return rune(0x2983), true + case "longleftarrow": + // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "longleftrightarrow": + // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "longmapsto": + // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "longrightarrow": + // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "looparrowleft": + // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "looparrowright": + // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "lopar": + // LEFT WHITE PARENTHESIS + return rune(0x2985), true + case "lopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL L + return rune(0x01d55d), true + case "loplus": + // PLUS SIGN IN LEFT HALF CIRCLE + return rune(0x2a2d), true + case "lotimes": + // MULTIPLICATION SIGN IN LEFT HALF CIRCLE + return rune(0x2a34), true + case "lowast": + // LOW ASTERISK + return rune(0x204e), true + case "lowbar": + // LOW LINE + return rune(0x5f), true + case "lowint": + // INTEGRAL WITH UNDERBAR + return rune(0x2a1c), true + case "loz": + // LOZENGE + return rune(0x25ca), true + case "lozenge": + // LOZENGE + return rune(0x25ca), true + case "lozf": + // BLACK LOZENGE + return rune(0x29eb), true + case "lpargt": + // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "lparlt": + // LEFT ARC LESS-THAN BRACKET + return rune(0x2993), true + case "lpar": + // LEFT PARENTHESIS + return rune(0x28), true + case "lrarr2": + // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrarr": + // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrcorner": + // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "lrhar": + // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhar2": + // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhard": + // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296d), true + case "lrm": + // LEFT-TO-RIGHT MARK + return rune(0x200e), true + case "lrtri": + // RIGHT TRIANGLE + return rune(0x22bf), true + case "lsaquo": + // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + return rune(0x2039), true + case "lscr": + // MATHEMATICAL SCRIPT SMALL L + return rune(0x01d4c1), true + case "lsh": + // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "lsim": + // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "lsime": + // LESS-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8d), true + case "lsimg": + // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN + return rune(0x2a8f), true + case "lsqb": + // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lsquor": + // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "lsquo": + // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "lstrok": + // LATIN SMALL LETTER L WITH STROKE + return rune(0x0142), true + case "ltcc": + // LESS-THAN CLOSED BY CURVE + return rune(0x2aa6), true + case "ltcir": + // LESS-THAN WITH CIRCLE INSIDE + return rune(0x2a79), true + case "ltdot": + // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lthree": + // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "ltimes": + // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22c9), true + case "ltlarr": + // LESS-THAN ABOVE LEFTWARDS ARROW + return rune(0x2976), true + case "ltquest": + // LESS-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7b), true + case "ltrPar": + // DOUBLE RIGHT ARC LESS-THAN BRACKET + return rune(0x2996), true + case "ltrie": + // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "ltrif": + // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "ltri": + // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "ltrivb": + // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "lt": + // LESS-THAN SIGN + return rune(0x3c), true + case "luharb": + // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "lurdshar": + // LEFT BARB UP RIGHT BARB DOWN HARPOON + return rune(0x294a), true + case "luruhar": + // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP + return rune(0x2966), true + case "lurushar": + // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "lvertneqq": + // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true + case "lvnE": + // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true + } + + case 'm': + switch name { + case "mDDot": + // GEOMETRIC PROPORTION + return rune(0x223a), true + case "macr": + // MACRON + return rune(0xaf), true + case "male": + // MALE SIGN + return rune(0x2642), true + case "malt": + // MALTESE CROSS + return rune(0x2720), true + case "maltese": + // MALTESE CROSS + return rune(0x2720), true + case "mapstodown": + // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "mapsto": + // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "map": + // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "mapstoleft": + // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "mapstoup": + // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "marker": + // BLACK VERTICAL RECTANGLE + return rune(0x25ae), true + case "mcomma": + // MINUS SIGN WITH COMMA ABOVE + return rune(0x2a29), true + case "mcy": + // CYRILLIC SMALL LETTER EM + return rune(0x043c), true + case "mdash": + // EM DASH + return rune(0x2014), true + case "measuredangle": + // MEASURED ANGLE + return rune(0x2221), true + case "mfr": + // MATHEMATICAL FRAKTUR SMALL M + return rune(0x01d52a), true + case "mgr": + // GREEK SMALL LETTER MU + return rune(0x03bc), true + case "mho": + // INVERTED OHM SIGN + return rune(0x2127), true + case "micro": + // MICRO SIGN + return rune(0xb5), true + case "mid": + // DIVIDES + return rune(0x2223), true + case "midast": + // ASTERISK + return rune(0x2a), true + case "midcir": + // VERTICAL LINE WITH CIRCLE BELOW + return rune(0x2af0), true + case "middot": + // MIDDLE DOT + return rune(0xb7), true + case "minus": + // MINUS SIGN + return rune(0x2212), true + case "minusb": + // SQUARED MINUS + return rune(0x229f), true + case "minusd": + // DOT MINUS + return rune(0x2238), true + case "minusdu": + // MINUS SIGN WITH DOT BELOW + return rune(0x2a2a), true + case "mlcp": + // TRANSVERSAL INTERSECTION + return rune(0x2adb), true + case "mldr": + // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "mnplus": + // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "models": + // MODELS + return rune(0x22a7), true + case "mopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL M + return rune(0x01d55e), true + case "mp": + // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "mscr": + // MATHEMATICAL SCRIPT SMALL M + return rune(0x01d4c2), true + case "mstpos": + // INVERTED LAZY S + return rune(0x223e), true + case "multimap": + // MULTIMAP + return rune(0x22b8), true + case "mumap": + // MULTIMAP + return rune(0x22b8), true + case "mu": + // GREEK SMALL LETTER MU + return rune(0x03bc), true + } + + case 'n': + switch name { + case "nGg": + // VERY MUCH GREATER-THAN with slash + return rune(0x22d9), true + case "nGtv": + // MUCH GREATER THAN with slash + return rune(0x226b), true + case "nGt": + // MUCH GREATER THAN with vertical line + return rune(0x226b), true + case "nLeftarrow": + // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nLeftrightarrow": + // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nLl": + // VERY MUCH LESS-THAN with slash + return rune(0x22d8), true + case "nLtv": + // MUCH LESS THAN with slash + return rune(0x226a), true + case "nLt": + // MUCH LESS THAN with vertical line + return rune(0x226a), true + case "nRightarrow": + // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nVDash": + // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22af), true + case "nVdash": + // DOES NOT FORCE + return rune(0x22ae), true + case "nabla": + // NABLA + return rune(0x2207), true + case "nacute": + // LATIN SMALL LETTER N WITH ACUTE + return rune(0x0144), true + case "nang": + // ANGLE with vertical line + return rune(0x2220), true + case "nap": + // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "napE": + // APPROXIMATELY EQUAL OR EQUAL TO with slash + return rune(0x2a70), true + case "napid": + // TRIPLE TILDE with slash + return rune(0x224b), true + case "napos": + // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + return rune(0x0149), true + case "napprox": + // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "naturals": + // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "natur": + // MUSIC NATURAL SIGN + return rune(0x266e), true + case "natural": + // MUSIC NATURAL SIGN + return rune(0x266e), true + case "nbsp": + // NO-BREAK SPACE + return rune(0xa0), true + case "nbump": + // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "nbumpe": + // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "ncap": + // INTERSECTION WITH OVERBAR + return rune(0x2a43), true + case "ncaron": + // LATIN SMALL LETTER N WITH CARON + return rune(0x0148), true + case "ncedil": + // LATIN SMALL LETTER N WITH CEDILLA + return rune(0x0146), true + case "ncong": + // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "ncongdot": + // CONGRUENT WITH DOT ABOVE with slash + return rune(0x2a6d), true + case "ncup": + // UNION WITH OVERBAR + return rune(0x2a42), true + case "ncy": + // CYRILLIC SMALL LETTER EN + return rune(0x043d), true + case "ndash": + // EN DASH + return rune(0x2013), true + case "neArr": + // NORTH EAST DOUBLE ARROW + return rune(0x21d7), true + case "nearrow": + // NORTH EAST ARROW + return rune(0x2197), true + case "nearr": + // NORTH EAST ARROW + return rune(0x2197), true + case "nedot": + // APPROACHES THE LIMIT with slash + return rune(0x2250), true + case "nesim": + // MINUS TILDE with slash + return rune(0x2242), true + case "nexist": + // THERE DOES NOT EXIST + return rune(0x2204), true + case "nexists": + // THERE DOES NOT EXIST + return rune(0x2204), true + case "ne": + // NOT EQUAL TO + return rune(0x2260), true + case "nearhk": + // NORTH EAST ARROW WITH HOOK + return rune(0x2924), true + case "neonwarr": + // NORTH EAST ARROW CROSSING NORTH WEST ARROW + return rune(0x2931), true + case "neosearr": + // NORTH EAST ARROW CROSSING SOUTH EAST ARROW + return rune(0x292e), true + case "nequiv": + // NOT IDENTICAL TO + return rune(0x2262), true + case "nesear": + // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "neswsarr": + // NORTH EAST AND SOUTH WEST ARROW + return rune(0x2922), true + case "nfr": + // MATHEMATICAL FRAKTUR SMALL N + return rune(0x01d52b), true + case "ngE": + // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "ngeqq": + // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "nge": + // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeq": + // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeqslant": + // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "nges": + // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "ngr": + // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "ngsim": + // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "ngt": + // NOT GREATER-THAN + return rune(0x226f), true + case "ngtr": + // NOT GREATER-THAN + return rune(0x226f), true + case "nhArr": + // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nharr": + // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nhpar": + // PARALLEL WITH HORIZONTAL STROKE + return rune(0x2af2), true + case "niv": + // CONTAINS AS MEMBER + return rune(0x220b), true + case "ni": + // CONTAINS AS MEMBER + return rune(0x220b), true + case "nisd": + // CONTAINS WITH LONG HORIZONTAL STROKE + return rune(0x22fa), true + case "nis": + // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fc), true + case "njcy": + // CYRILLIC SMALL LETTER NJE + return rune(0x045a), true + case "nlArr": + // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nlE": + // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nlarr": + // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nldr": + // TWO DOT LEADER + return rune(0x2025), true + case "nleftarrow": + // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nleftrightarrow": + // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nleqq": + // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nless": + // NOT LESS-THAN + return rune(0x226e), true + case "nle": + // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleq": + // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleqslant": + // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nles": + // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nlsim": + // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "nlt": + // NOT LESS-THAN + return rune(0x226e), true + case "nltri": + // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "nltrie": + // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "nltrivb": + // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "nmid": + // DOES NOT DIVIDE + return rune(0x2224), true + case "nopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL N + return rune(0x01d55f), true + case "notin": + // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinE": + // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash + return rune(0x22f9), true + case "notindot": + // ELEMENT OF WITH DOT ABOVE with slash + return rune(0x22f5), true + case "notinva": + // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinvb": + // SMALL ELEMENT OF WITH OVERBAR + return rune(0x22f7), true + case "notinvc": + // ELEMENT OF WITH OVERBAR + return rune(0x22f6), true + case "notni": + // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notniva": + // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notnivb": + // SMALL CONTAINS WITH OVERBAR + return rune(0x22fe), true + case "notnivc": + // CONTAINS WITH OVERBAR + return rune(0x22fd), true + case "not": + // NOT SIGN + return rune(0xac), true + case "npart": + // PARTIAL DIFFERENTIAL with slash + return rune(0x2202), true + case "npar": + // NOT PARALLEL TO + return rune(0x2226), true + case "nparallel": + // NOT PARALLEL TO + return rune(0x2226), true + case "nparsl": + // DOUBLE SOLIDUS OPERATOR with reverse slash + return rune(0x2afd), true + case "npolint": + // LINE INTEGRATION NOT INCLUDING THE POLE + return rune(0x2a14), true + case "nprsim": + // PRECEDES OR EQUIVALENT TO with slash + return rune(0x227e), true + case "npr": + // DOES NOT PRECEDE + return rune(0x2280), true + case "nprcue": + // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "nprec": + // DOES NOT PRECEDE + return rune(0x2280), true + case "npre": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "npreceq": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "nrArr": + // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nrarrw": + // RIGHTWARDS WAVE ARROW with slash + return rune(0x219d), true + case "nrarr": + // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrarrc": + // WAVE ARROW POINTING DIRECTLY RIGHT with slash + return rune(0x2933), true + case "nrightarrow": + // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrtri": + // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "nrtrie": + // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "nsGt": + // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "nsLt": + // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "nscsim": + // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "nsc": + // DOES NOT SUCCEED + return rune(0x2281), true + case "nsccue": + // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "nsce": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nscr": + // MATHEMATICAL SCRIPT SMALL N + return rune(0x01d4c3), true + case "nshortmid": + // DOES NOT DIVIDE + return rune(0x2224), true + case "nshortparallel": + // NOT PARALLEL TO + return rune(0x2226), true + case "nsim": + // NOT TILDE + return rune(0x2241), true + case "nsime": + // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsimeq": + // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsmid": + // DOES NOT DIVIDE + return rune(0x2224), true + case "nspar": + // NOT PARALLEL TO + return rune(0x2226), true + case "nsqsub": + // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "nsqsube": + // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "nsqsup": + // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "nsqsupe": + // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "nsubset": + // SUBSET OF with vertical line + return rune(0x2282), true + case "nsub": + // NOT A SUBSET OF + return rune(0x2284), true + case "nsubE": + // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsube": + // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubseteq": + // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubseteqq": + // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsucc": + // DOES NOT SUCCEED + return rune(0x2281), true + case "nsucceq": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nsupset": + // SUPERSET OF with vertical line + return rune(0x2283), true + case "nsup": + // NOT A SUPERSET OF + return rune(0x2285), true + case "nsupE": + // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "nsupe": + // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupseteq": + // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupseteqq": + // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "ntgl": + // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "ntilde": + // LATIN SMALL LETTER N WITH TILDE + return rune(0xf1), true + case "ntlg": + // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "ntriangleleft": + // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "ntrianglelefteq": + // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "ntriangleright": + // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "ntrianglerighteq": + // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "numero": + // NUMERO SIGN + return rune(0x2116), true + case "numsp": + // FIGURE SPACE + return rune(0x2007), true + case "nu": + // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "num": + // NUMBER SIGN + return rune(0x23), true + case "nvDash": + // NOT TRUE + return rune(0x22ad), true + case "nvHarr": + // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2904), true + case "nvap": + // EQUIVALENT TO with vertical line + return rune(0x224d), true + case "nvbrtri": + // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "nvdash": + // DOES NOT PROVE + return rune(0x22ac), true + case "nvge": + // GREATER-THAN OR EQUAL TO with vertical line + return rune(0x2265), true + case "nvgt": + // GREATER-THAN SIGN with vertical line + return rune(0x3e), true + case "nvinfin": + // INFINITY NEGATED WITH VERTICAL BAR + return rune(0x29de), true + case "nvlArr": + // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2902), true + case "nvle": + // LESS-THAN OR EQUAL TO with vertical line + return rune(0x2264), true + case "nvltrie": + // NORMAL SUBGROUP OF OR EQUAL TO with vertical line + return rune(0x22b4), true + case "nvlt": + // LESS-THAN SIGN with vertical line + return rune(0x3c), true + case "nvrArr": + // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2903), true + case "nvrtrie": + // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line + return rune(0x22b5), true + case "nvsim": + // TILDE OPERATOR with vertical line + return rune(0x223c), true + case "nwArr": + // NORTH WEST DOUBLE ARROW + return rune(0x21d6), true + case "nwarhk": + // NORTH WEST ARROW WITH HOOK + return rune(0x2923), true + case "nwarrow": + // NORTH WEST ARROW + return rune(0x2196), true + case "nwarr": + // NORTH WEST ARROW + return rune(0x2196), true + case "nwnear": + // NORTH WEST ARROW AND NORTH EAST ARROW + return rune(0x2927), true + case "nwonearr": + // NORTH WEST ARROW CROSSING NORTH EAST ARROW + return rune(0x2932), true + case "nwsesarr": + // NORTH WEST AND SOUTH EAST ARROW + return rune(0x2921), true + } + + case 'o': + switch name { + case "oS": + // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "oacgr": + // GREEK SMALL LETTER OMICRON WITH TONOS + return rune(0x03cc), true + case "oacute": + // LATIN SMALL LETTER O WITH ACUTE + return rune(0xf3), true + case "oast": + // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "obsol": + // CIRCLED REVERSE SOLIDUS + return rune(0x29b8), true + case "ocir": + // CIRCLED RING OPERATOR + return rune(0x229a), true + case "ocirc": + // LATIN SMALL LETTER O WITH CIRCUMFLEX + return rune(0xf4), true + case "ocy": + // CYRILLIC SMALL LETTER O + return rune(0x043e), true + case "odash": + // CIRCLED DASH + return rune(0x229d), true + case "odblac": + // LATIN SMALL LETTER O WITH DOUBLE ACUTE + return rune(0x0151), true + case "odiv": + // CIRCLED DIVISION SIGN + return rune(0x2a38), true + case "odot": + // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "odsold": + // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN + return rune(0x29bc), true + case "oelig": + // LATIN SMALL LIGATURE OE + return rune(0x0153), true + case "ofcir": + // CIRCLED BULLET + return rune(0x29bf), true + case "ofr": + // MATHEMATICAL FRAKTUR SMALL O + return rune(0x01d52c), true + case "ogon": + // OGONEK + return rune(0x02db), true + case "ogr": + // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "ograve": + // LATIN SMALL LETTER O WITH GRAVE + return rune(0xf2), true + case "ogt": + // CIRCLED GREATER-THAN + return rune(0x29c1), true + case "ohacgr": + // GREEK SMALL LETTER OMEGA WITH TONOS + return rune(0x03ce), true + case "ohbar": + // CIRCLE WITH HORIZONTAL BAR + return rune(0x29b5), true + case "ohgr": + // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "ohm": + // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "oint": + // CONTOUR INTEGRAL + return rune(0x222e), true + case "olarr": + // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "olcir": + // CIRCLED WHITE BULLET + return rune(0x29be), true + case "olcross": + // CIRCLE WITH SUPERIMPOSED X + return rune(0x29bb), true + case "oline": + // OVERLINE + return rune(0x203e), true + case "olt": + // CIRCLED LESS-THAN + return rune(0x29c0), true + case "omacr": + // LATIN SMALL LETTER O WITH MACRON + return rune(0x014d), true + case "omega": + // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "omicron": + // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "omid": + // CIRCLED VERTICAL BAR + return rune(0x29b6), true + case "ominus": + // CIRCLED MINUS + return rune(0x2296), true + case "oopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL O + return rune(0x01d560), true + case "opar": + // CIRCLED PARALLEL + return rune(0x29b7), true + case "operp": + // CIRCLED PERPENDICULAR + return rune(0x29b9), true + case "opfgamma": + // DOUBLE-STRUCK SMALL GAMMA + return rune(0x213d), true + case "opfpi": + // DOUBLE-STRUCK CAPITAL PI + return rune(0x213f), true + case "opfsum": + // DOUBLE-STRUCK N-ARY SUMMATION + return rune(0x2140), true + case "oplus": + // CIRCLED PLUS + return rune(0x2295), true + case "orarr": + // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "or": + // LOGICAL OR + return rune(0x2228), true + case "orderof": + // SCRIPT SMALL O + return rune(0x2134), true + case "order": + // SCRIPT SMALL O + return rune(0x2134), true + case "ord": + // LOGICAL OR WITH HORIZONTAL DASH + return rune(0x2a5d), true + case "ordf": + // FEMININE ORDINAL INDICATOR + return rune(0xaa), true + case "ordm": + // MASCULINE ORDINAL INDICATOR + return rune(0xba), true + case "origof": + // ORIGINAL OF + return rune(0x22b6), true + case "oror": + // TWO INTERSECTING LOGICAL OR + return rune(0x2a56), true + case "orslope": + // SLOPING LARGE OR + return rune(0x2a57), true + case "orv": + // LOGICAL OR WITH MIDDLE STEM + return rune(0x2a5b), true + case "oscr": + // SCRIPT SMALL O + return rune(0x2134), true + case "oslash": + // LATIN SMALL LETTER O WITH STROKE + return rune(0xf8), true + case "osol": + // CIRCLED DIVISION SLASH + return rune(0x2298), true + case "otilde": + // LATIN SMALL LETTER O WITH TILDE + return rune(0xf5), true + case "otimes": + // CIRCLED TIMES + return rune(0x2297), true + case "otimesas": + // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT + return rune(0x2a36), true + case "ouml": + // LATIN SMALL LETTER O WITH DIAERESIS + return rune(0xf6), true + case "ovbar": + // APL FUNCTIONAL SYMBOL CIRCLE STILE + return rune(0x233d), true + case "ovrbrk": + // TOP SQUARE BRACKET + return rune(0x23b4), true + case "ovrcub": + // TOP CURLY BRACKET + return rune(0x23de), true + case "ovrpar": + // TOP PARENTHESIS + return rune(0x23dc), true + case "oxuarr": + // UP ARROW THROUGH CIRCLE + return rune(0x29bd), true + } + + case 'p': + switch name { + case "part": + // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "par": + // PARALLEL TO + return rune(0x2225), true + case "parallel": + // PARALLEL TO + return rune(0x2225), true + case "para": + // PILCROW SIGN + return rune(0xb6), true + case "parsim": + // PARALLEL WITH TILDE OPERATOR + return rune(0x2af3), true + case "parsl": + // DOUBLE SOLIDUS OPERATOR + return rune(0x2afd), true + case "pcy": + // CYRILLIC SMALL LETTER PE + return rune(0x043f), true + case "percnt": + // PERCENT SIGN + return rune(0x25), true + case "period": + // FULL STOP + return rune(0x2e), true + case "permil": + // PER MILLE SIGN + return rune(0x2030), true + case "perp": + // UP TACK + return rune(0x22a5), true + case "pertenk": + // PER TEN THOUSAND SIGN + return rune(0x2031), true + case "pfr": + // MATHEMATICAL FRAKTUR SMALL P + return rune(0x01d52d), true + case "pgr": + // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "phgr": + // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phis": + // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phiv": + // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phi": + // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phmmat": + // SCRIPT CAPITAL M + return rune(0x2133), true + case "phone": + // BLACK TELEPHONE + return rune(0x260e), true + case "pitchfork": + // PITCHFORK + return rune(0x22d4), true + case "piv": + // GREEK PI SYMBOL + return rune(0x03d6), true + case "pi": + // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "planck": + // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "planckh": + // PLANCK CONSTANT + return rune(0x210e), true + case "plankv": + // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "plusacir": + // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE + return rune(0x2a23), true + case "plusb": + // SQUARED PLUS + return rune(0x229e), true + case "pluscir": + // PLUS SIGN WITH SMALL CIRCLE ABOVE + return rune(0x2a22), true + case "plusdo": + // DOT PLUS + return rune(0x2214), true + case "plusdu": + // PLUS SIGN WITH DOT BELOW + return rune(0x2a25), true + case "pluse": + // PLUS SIGN ABOVE EQUALS SIGN + return rune(0x2a72), true + case "plusmn": + // PLUS-MINUS SIGN + return rune(0xb1), true + case "plussim": + // PLUS SIGN WITH TILDE BELOW + return rune(0x2a26), true + case "plustrif": + // PLUS SIGN WITH BLACK TRIANGLE + return rune(0x2a28), true + case "plustwo": + // PLUS SIGN WITH SUBSCRIPT TWO + return rune(0x2a27), true + case "plus": + // PLUS SIGN + return rune(0x2b), true + case "pm": + // PLUS-MINUS SIGN + return rune(0xb1), true + case "pointint": + // INTEGRAL AROUND A POINT OPERATOR + return rune(0x2a15), true + case "popf": + // MATHEMATICAL DOUBLE-STRUCK SMALL P + return rune(0x01d561), true + case "pound": + // POUND SIGN + return rune(0xa3), true + case "prod": + // N-ARY PRODUCT + return rune(0x220f), true + case "prop": + // PROPORTIONAL TO + return rune(0x221d), true + case "propto": + // PROPORTIONAL TO + return rune(0x221d), true + case "pr": + // PRECEDES + return rune(0x227a), true + case "prE": + // PRECEDES ABOVE EQUALS SIGN + return rune(0x2ab3), true + case "prap": + // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "prcue": + // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "prec": + // PRECEDES + return rune(0x227a), true + case "preccurlyeq": + // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "precnsim": + // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "precsim": + // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "pre": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "precapprox": + // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "preceq": + // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "precnapprox": + // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "precneqq": + // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "primes": + // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "prime": + // PRIME + return rune(0x2032), true + case "prnE": + // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "prnap": + // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "prnsim": + // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "profalar": + // ALL AROUND-PROFILE + return rune(0x232e), true + case "profline": + // ARC + return rune(0x2312), true + case "profsurf": + // SEGMENT + return rune(0x2313), true + case "prsim": + // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "prurel": + // PRECEDES UNDER RELATION + return rune(0x22b0), true + case "pscr": + // MATHEMATICAL SCRIPT SMALL P + return rune(0x01d4c5), true + case "psgr": + // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "psi": + // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "puncsp": + // PUNCTUATION SPACE + return rune(0x2008), true + } + + case 'q': + switch name { + case "qfr": + // MATHEMATICAL FRAKTUR SMALL Q + return rune(0x01d52e), true + case "qint": + // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "qopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL Q + return rune(0x01d562), true + case "qprime": + // QUADRUPLE PRIME + return rune(0x2057), true + case "qscr": + // MATHEMATICAL SCRIPT SMALL Q + return rune(0x01d4c6), true + case "quaternions": + // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "quatint": + // QUATERNION INTEGRAL OPERATOR + return rune(0x2a16), true + case "questeq": + // QUESTIONED EQUAL TO + return rune(0x225f), true + case "quest": + // QUESTION MARK + return rune(0x3f), true + case "quot": + // QUOTATION MARK + return rune(0x22), true + } + + case 'r': + switch name { + case "rAarr": + // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "rArr": + // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "rAtail": + // RIGHTWARDS DOUBLE ARROW-TAIL + return rune(0x291c), true + case "rBarr": + // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "rHar": + // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2964), true + case "race": + // REVERSED TILDE with underline + return rune(0x223d), true + case "racute": + // LATIN SMALL LETTER R WITH ACUTE + return rune(0x0155), true + case "radic": + // SQUARE ROOT + return rune(0x221a), true + case "raemptyv": + // EMPTY SET WITH RIGHT ARROW ABOVE + return rune(0x29b3), true + case "rang": + // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "rangd": + // RIGHT ANGLE BRACKET WITH DOT + return rune(0x2992), true + case "range": + // REVERSED ANGLE WITH UNDERBAR + return rune(0x29a5), true + case "rangle": + // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "raquo": + // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xbb), true + case "rarr2": + // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rarr3": + // THREE RIGHTWARDS ARROWS + return rune(0x21f6), true + case "rarrb": + // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "rarrhk": + // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "rarrlp": + // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "rarrtl": + // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rarrw": + // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rarr": + // RIGHTWARDS ARROW + return rune(0x2192), true + case "rarrap": + // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO + return rune(0x2975), true + case "rarrbfs": + // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x2920), true + case "rarrc": + // WAVE ARROW POINTING DIRECTLY RIGHT + return rune(0x2933), true + case "rarrfs": + // RIGHTWARDS ARROW TO BLACK DIAMOND + return rune(0x291e), true + case "rarrpl": + // RIGHTWARDS ARROW WITH PLUS BELOW + return rune(0x2945), true + case "rarrsim": + // RIGHTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2974), true + case "rarrx": + // RIGHTWARDS ARROW THROUGH X + return rune(0x2947), true + case "ratail": + // RIGHTWARDS ARROW-TAIL + return rune(0x291a), true + case "ratio": + // RATIO + return rune(0x2236), true + case "rationals": + // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "rbarr": + // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "rbbrk": + // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2773), true + case "rbrace": + // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rbrack": + // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rbrke": + // RIGHT SQUARE BRACKET WITH UNDERBAR + return rune(0x298c), true + case "rbrksld": + // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298e), true + case "rbrkslu": + // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x2990), true + case "rcaron": + // LATIN SMALL LETTER R WITH CARON + return rune(0x0159), true + case "rcedil": + // LATIN SMALL LETTER R WITH CEDILLA + return rune(0x0157), true + case "rceil": + // RIGHT CEILING + return rune(0x2309), true + case "rcub": + // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rcy": + // CYRILLIC SMALL LETTER ER + return rune(0x0440), true + case "rdca": + // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS + return rune(0x2937), true + case "rdharb": + // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "rdiag": + // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "rdiofdi": + // RISING DIAGONAL CROSSING FALLING DIAGONAL + return rune(0x292b), true + case "rdldhar": + // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2969), true + case "rdosearr": + // RISING DIAGONAL CROSSING SOUTH EAST ARROW + return rune(0x2930), true + case "rdquor": + // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdquo": + // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdsh": + // DOWNWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b3), true + case "realpart": + // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "reals": + // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "real": + // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "realine": + // SCRIPT CAPITAL R + return rune(0x211b), true + case "rect": + // WHITE RECTANGLE + return rune(0x25ad), true + case "reg": + // REGISTERED SIGN + return rune(0xae), true + case "rfbowtie": + // BOWTIE WITH RIGHT HALF BLACK + return rune(0x29d2), true + case "rfisht": + // RIGHT FISH TAIL + return rune(0x297d), true + case "rfloor": + // RIGHT FLOOR + return rune(0x230b), true + case "rfr": + // MATHEMATICAL FRAKTUR SMALL R + return rune(0x01d52f), true + case "rftimes": + // TIMES WITH RIGHT HALF BLACK + return rune(0x29d5), true + case "rgr": + // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rhard": + // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rharu": + // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rharul": + // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296c), true + case "rhov": + // GREEK RHO SYMBOL + return rune(0x03f1), true + case "rho": + // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rightarrowtail": + // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rightarrow": + // RIGHTWARDS ARROW + return rune(0x2192), true + case "rightharpoondown": + // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rightharpoonup": + // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rightleftarrows": + // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rightleftharpoons": + // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rightrightarrows": + // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rightsquigarrow": + // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rightthreetimes": + // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rimply": + // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "ring": + // RING ABOVE + return rune(0x02da), true + case "risingdotseq": + // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "rlarr2": + // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlarr": + // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlhar": + // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlhar2": + // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlm": + // RIGHT-TO-LEFT MARK + return rune(0x200f), true + case "rmoust": + // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rmoustache": + // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rnmid": + // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH + return rune(0x2aee), true + case "roang": + // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + return rune(0x27ed), true + case "roarr": + // RIGHTWARDS OPEN-HEADED ARROW + return rune(0x21fe), true + case "robrk": + // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "rocub": + // RIGHT WHITE CURLY BRACKET + return rune(0x2984), true + case "ropar": + // RIGHT WHITE PARENTHESIS + return rune(0x2986), true + case "ropf": + // MATHEMATICAL DOUBLE-STRUCK SMALL R + return rune(0x01d563), true + case "roplus": + // PLUS SIGN IN RIGHT HALF CIRCLE + return rune(0x2a2e), true + case "rotimes": + // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE + return rune(0x2a35), true + case "rpargt": + // RIGHT ARC GREATER-THAN BRACKET + return rune(0x2994), true + case "rpar": + // RIGHT PARENTHESIS + return rune(0x29), true + case "rppolint": + // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE + return rune(0x2a12), true + case "rrarr": + // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rsaquo": + // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + return rune(0x203a), true + case "rscr": + // MATHEMATICAL SCRIPT SMALL R + return rune(0x01d4c7), true + case "rsh": + // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "rsolbar": + // REVERSE SOLIDUS WITH HORIZONTAL STROKE + return rune(0x29f7), true + case "rsqb": + // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rsquor": + // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rsquo": + // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rthree": + // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rtimes": + // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22ca), true + case "rtrie": + // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "rtrif": + // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "rtri": + // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "rtriltri": + // RIGHT TRIANGLE ABOVE LEFT TRIANGLE + return rune(0x29ce), true + case "ruharb": + // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "ruluhar": + // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP + return rune(0x2968), true + case "rx": + // PRESCRIPTION TAKE + return rune(0x211e), true + } + + case 's': + switch name { + case "sacute": + // LATIN SMALL LETTER S WITH ACUTE + return rune(0x015b), true + case "samalg": + // N-ARY COPRODUCT + return rune(0x2210), true + case "sampi": + // GREEK LETTER SAMPI + return rune(0x03e0), true + case "sbquo": + // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "sbsol": + // SMALL REVERSE SOLIDUS + return rune(0xfe68), true + case "sc": + // SUCCEEDS + return rune(0x227b), true + case "scE": + // SUCCEEDS ABOVE EQUALS SIGN + return rune(0x2ab4), true + case "scap": + // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "scaron": + // LATIN SMALL LETTER S WITH CARON + return rune(0x0161), true + case "sccue": + // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "scedil": + // LATIN SMALL LETTER S WITH CEDILLA + return rune(0x015f), true + case "sce": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "scirc": + // LATIN SMALL LETTER S WITH CIRCUMFLEX + return rune(0x015d), true + case "scnE": + // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "scnap": + // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "scnsim": + // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "scpolint": + // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE + return rune(0x2a13), true + case "scsim": + // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "scy": + // CYRILLIC SMALL LETTER ES + return rune(0x0441), true + case "sdotb": + // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "sdot": + // DOT OPERATOR + return rune(0x22c5), true + case "sdote": + // EQUALS SIGN WITH DOT BELOW + return rune(0x2a66), true + case "seArr": + // SOUTH EAST DOUBLE ARROW + return rune(0x21d8), true + case "searhk": + // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "searrow": + // SOUTH EAST ARROW + return rune(0x2198), true + case "searr": + // SOUTH EAST ARROW + return rune(0x2198), true + case "sect": + // SECTION SIGN + return rune(0xa7), true + case "semi": + // SEMICOLON + return rune(0x3b), true + case "seonearr": + // SOUTH EAST ARROW CROSSING NORTH EAST ARROW + return rune(0x292d), true + case "seswar": + // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "setminus": + // SET MINUS + return rune(0x2216), true + case "setmn": + // SET MINUS + return rune(0x2216), true + case "sext": + // SIX POINTED BLACK STAR + return rune(0x2736), true + case "sfgr": + // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sfrown": + // FROWN + return rune(0x2322), true + case "sfr": + // MATHEMATICAL FRAKTUR SMALL S + return rune(0x01d530), true + case "sgr": + // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sharp": + // MUSIC SHARP SIGN + return rune(0x266f), true + case "shchcy": + // CYRILLIC SMALL LETTER SHCHA + return rune(0x0449), true + case "shcy": + // CYRILLIC SMALL LETTER SHA + return rune(0x0448), true + case "shortmid": + // DIVIDES + return rune(0x2223), true + case "shortparallel": + // PARALLEL TO + return rune(0x2225), true + case "shuffle": + // SHUFFLE PRODUCT + return rune(0x29e2), true + case "shy": + // SOFT HYPHEN + return rune(0xad), true + case "sigma": + // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sigmaf": + // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sigmav": + // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sim": + // TILDE OPERATOR + return rune(0x223c), true + case "simdot": + // TILDE OPERATOR WITH DOT ABOVE + return rune(0x2a6a), true + case "sime": + // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simeq": + // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simg": + // SIMILAR OR GREATER-THAN + return rune(0x2a9e), true + case "simgE": + // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN + return rune(0x2aa0), true + case "siml": + // SIMILAR OR LESS-THAN + return rune(0x2a9d), true + case "simlE": + // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN + return rune(0x2a9f), true + case "simne": + // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO + return rune(0x2246), true + case "simplus": + // PLUS SIGN WITH TILDE ABOVE + return rune(0x2a24), true + case "simrarr": + // TILDE OPERATOR ABOVE RIGHTWARDS ARROW + return rune(0x2972), true + case "slarr": + // LEFTWARDS ARROW + return rune(0x2190), true + case "slint": + // INTEGRAL AVERAGE WITH SLASH + return rune(0x2a0f), true + case "smallsetminus": + // SET MINUS + return rune(0x2216), true + case "smashp": + // SMASH PRODUCT + return rune(0x2a33), true + case "smeparsl": + // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE + return rune(0x29e4), true + case "smid": + // DIVIDES + return rune(0x2223), true + case "smile": + // SMILE + return rune(0x2323), true + case "smt": + // SMALLER THAN + return rune(0x2aaa), true + case "smte": + // SMALLER THAN OR EQUAL TO + return rune(0x2aac), true + case "smtes": + // SMALLER THAN OR slanted EQUAL + return rune(0x2aac), true + case "softcy": + // CYRILLIC SMALL LETTER SOFT SIGN + return rune(0x044c), true + case "solbar": + // APL FUNCTIONAL SYMBOL SLASH BAR + return rune(0x233f), true + case "solb": + // SQUARED RISING DIAGONAL SLASH + return rune(0x29c4), true + case "sol": + // SOLIDUS + return rune(0x2f), true + case "sopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL S + return rune(0x01d564), true + case "spades": + // BLACK SPADE SUIT + return rune(0x2660), true + case "spadesuit": + // BLACK SPADE SUIT + return rune(0x2660), true + case "spar": + // PARALLEL TO + return rune(0x2225), true + case "sqcap": + // SQUARE CAP + return rune(0x2293), true + case "sqcaps": + // SQUARE CAP with serifs + return rune(0x2293), true + case "sqcup": + // SQUARE CUP + return rune(0x2294), true + case "sqcups": + // SQUARE CUP with serifs + return rune(0x2294), true + case "sqsub": + // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsube": + // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsubset": + // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsubseteq": + // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsup": + // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupe": + // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "sqsupset": + // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupseteq": + // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "squ": + // WHITE SQUARE + return rune(0x25a1), true + case "square": + // WHITE SQUARE + return rune(0x25a1), true + case "squarf": + // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squb": + // SQUARED SQUARE + return rune(0x29c8), true + case "squerr": + // ERROR-BARRED WHITE SQUARE + return rune(0x29ee), true + case "squf": + // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squferr": + // ERROR-BARRED BLACK SQUARE + return rune(0x29ef), true + case "srarr": + // RIGHTWARDS ARROW + return rune(0x2192), true + case "sscr": + // MATHEMATICAL SCRIPT SMALL S + return rune(0x01d4c8), true + case "ssetmn": + // SET MINUS + return rune(0x2216), true + case "ssmile": + // SMILE + return rune(0x2323), true + case "sstarf": + // STAR OPERATOR + return rune(0x22c6), true + case "starf": + // BLACK STAR + return rune(0x2605), true + case "star": + // WHITE STAR + return rune(0x2606), true + case "stigma": + // GREEK LETTER STIGMA + return rune(0x03da), true + case "straightepsilon": + // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "straightphi": + // GREEK PHI SYMBOL + return rune(0x03d5), true + case "strns": + // MACRON + return rune(0xaf), true + case "sub": + // SUBSET OF + return rune(0x2282), true + case "subE": + // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subdot": + // SUBSET WITH DOT + return rune(0x2abd), true + case "sube": + // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subedot": + // SUBSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac3), true + case "submult": + // SUBSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac1), true + case "subnE": + // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subne": + // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subplus": + // SUBSET WITH PLUS SIGN BELOW + return rune(0x2abf), true + case "subrarr": + // SUBSET ABOVE RIGHTWARDS ARROW + return rune(0x2979), true + case "subset": + // SUBSET OF + return rune(0x2282), true + case "subseteq": + // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subseteqq": + // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subsetneq": + // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subsetneqq": + // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subsim": + // SUBSET OF ABOVE TILDE OPERATOR + return rune(0x2ac7), true + case "subsub": + // SUBSET ABOVE SUBSET + return rune(0x2ad5), true + case "subsup": + // SUBSET ABOVE SUPERSET + return rune(0x2ad3), true + case "succ": + // SUCCEEDS + return rune(0x227b), true + case "succapprox": + // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "succcurlyeq": + // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "succeq": + // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "succnapprox": + // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "succneqq": + // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "succnsim": + // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "succsim": + // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "sum": + // N-ARY SUMMATION + return rune(0x2211), true + case "sumint": + // SUMMATION WITH INTEGRAL + return rune(0x2a0b), true + case "sung": + // EIGHTH NOTE + return rune(0x266a), true + case "sup": + // SUPERSET OF + return rune(0x2283), true + case "sup1": + // SUPERSCRIPT ONE + return rune(0xb9), true + case "sup2": + // SUPERSCRIPT TWO + return rune(0xb2), true + case "sup3": + // SUPERSCRIPT THREE + return rune(0xb3), true + case "supE": + // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supdot": + // SUPERSET WITH DOT + return rune(0x2abe), true + case "supdsub": + // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET + return rune(0x2ad8), true + case "supe": + // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supedot": + // SUPERSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac4), true + case "suphsol": + // SUPERSET PRECEDING SOLIDUS + return rune(0x27c9), true + case "suphsub": + // SUPERSET BESIDE SUBSET + return rune(0x2ad7), true + case "suplarr": + // SUPERSET ABOVE LEFTWARDS ARROW + return rune(0x297b), true + case "supmult": + // SUPERSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac2), true + case "supnE": + // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supne": + // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supplus": + // SUPERSET WITH PLUS SIGN BELOW + return rune(0x2ac0), true + case "supset": + // SUPERSET OF + return rune(0x2283), true + case "supseteq": + // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supseteqq": + // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supsetneq": + // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supsetneqq": + // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supsim": + // SUPERSET OF ABOVE TILDE OPERATOR + return rune(0x2ac8), true + case "supsub": + // SUPERSET ABOVE SUBSET + return rune(0x2ad4), true + case "supsup": + // SUPERSET ABOVE SUPERSET + return rune(0x2ad6), true + case "swArr": + // SOUTH WEST DOUBLE ARROW + return rune(0x21d9), true + case "swarhk": + // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "swarrow": + // SOUTH WEST ARROW + return rune(0x2199), true + case "swarr": + // SOUTH WEST ARROW + return rune(0x2199), true + case "swnwar": + // SOUTH WEST ARROW AND NORTH WEST ARROW + return rune(0x292a), true + case "szlig": + // LATIN SMALL LETTER SHARP S + return rune(0xdf), true + } + + case 't': + switch name { + case "target": + // POSITION INDICATOR + return rune(0x2316), true + case "tau": + // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "tbrk": + // TOP SQUARE BRACKET + return rune(0x23b4), true + case "tcaron": + // LATIN SMALL LETTER T WITH CARON + return rune(0x0165), true + case "tcedil": + // LATIN SMALL LETTER T WITH CEDILLA + return rune(0x0163), true + case "tcy": + // CYRILLIC SMALL LETTER TE + return rune(0x0442), true + case "tdot": + // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "telrec": + // TELEPHONE RECORDER + return rune(0x2315), true + case "tfr": + // MATHEMATICAL FRAKTUR SMALL T + return rune(0x01d531), true + case "tgr": + // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "there4": + // THEREFORE + return rune(0x2234), true + case "therefore": + // THEREFORE + return rune(0x2234), true + case "thermod": + // THERMODYNAMIC + return rune(0x29e7), true + case "thetasym": + // GREEK THETA SYMBOL + return rune(0x03d1), true + case "thetas": + // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thetav": + // GREEK THETA SYMBOL + return rune(0x03d1), true + case "theta": + // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thgr": + // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thickapprox": + // ALMOST EQUAL TO + return rune(0x2248), true + case "thicksim": + // TILDE OPERATOR + return rune(0x223c), true + case "thinsp": + // THIN SPACE + return rune(0x2009), true + case "thkap": + // ALMOST EQUAL TO + return rune(0x2248), true + case "thksim": + // TILDE OPERATOR + return rune(0x223c), true + case "thorn": + // LATIN SMALL LETTER THORN + return rune(0xfe), true + case "tilde": + // SMALL TILDE + return rune(0x02dc), true + case "timeint": + // INTEGRAL WITH TIMES SIGN + return rune(0x2a18), true + case "timesb": + // SQUARED TIMES + return rune(0x22a0), true + case "timesbar": + // MULTIPLICATION SIGN WITH UNDERBAR + return rune(0x2a31), true + case "timesd": + // MULTIPLICATION SIGN WITH DOT ABOVE + return rune(0x2a30), true + case "times": + // MULTIPLICATION SIGN + return rune(0xd7), true + case "tint": + // TRIPLE INTEGRAL + return rune(0x222d), true + case "toea": + // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "top": + // DOWN TACK + return rune(0x22a4), true + case "topbot": + // APL FUNCTIONAL SYMBOL I-BEAM + return rune(0x2336), true + case "topcir": + // DOWN TACK WITH CIRCLE BELOW + return rune(0x2af1), true + case "topfork": + // PITCHFORK WITH TEE TOP + return rune(0x2ada), true + case "topf": + // MATHEMATICAL DOUBLE-STRUCK SMALL T + return rune(0x01d565), true + case "tosa": + // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "tprime": + // TRIPLE PRIME + return rune(0x2034), true + case "trade": + // TRADE MARK SIGN + return rune(0x2122), true + case "triS": + // S IN TRIANGLE + return rune(0x29cc), true + case "trianglelefteq": + // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "triangleq": + // DELTA EQUAL TO + return rune(0x225c), true + case "trianglerighteq": + // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "triangle": + // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "triangledown": + // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "triangleleft": + // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "triangleright": + // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "tribar": + // TRIANGLE WITH UNDERBAR + return rune(0x29cb), true + case "tridot": + // WHITE UP-POINTING TRIANGLE WITH DOT + return rune(0x25ec), true + case "tridoto": + // TRIANGLE WITH DOT ABOVE + return rune(0x29ca), true + case "trie": + // DELTA EQUAL TO + return rune(0x225c), true + case "triminus": + // MINUS SIGN IN TRIANGLE + return rune(0x2a3a), true + case "triplus": + // PLUS SIGN IN TRIANGLE + return rune(0x2a39), true + case "trisb": + // TRIANGLE WITH SERIFS AT BOTTOM + return rune(0x29cd), true + case "tritime": + // MULTIPLICATION SIGN IN TRIANGLE + return rune(0x2a3b), true + case "trpezium": + // WHITE TRAPEZIUM + return rune(0x23e2), true + case "tscr": + // MATHEMATICAL SCRIPT SMALL T + return rune(0x01d4c9), true + case "tscy": + // CYRILLIC SMALL LETTER TSE + return rune(0x0446), true + case "tshcy": + // CYRILLIC SMALL LETTER TSHE + return rune(0x045b), true + case "tstrok": + // LATIN SMALL LETTER T WITH STROKE + return rune(0x0167), true + case "tverbar": + // TRIPLE VERTICAL BAR DELIMITER + return rune(0x2980), true + case "twixt": + // BETWEEN + return rune(0x226c), true + case "twoheadleftarrow": + // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "twoheadrightarrow": + // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true + } + + case 'u': + switch name { + case "uAarr": + // UPWARDS TRIPLE ARROW + return rune(0x290a), true + case "uArr": + // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "uHar": + // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x2963), true + case "uacgr": + // GREEK SMALL LETTER UPSILON WITH TONOS + return rune(0x03cd), true + case "uacute": + // LATIN SMALL LETTER U WITH ACUTE + return rune(0xfa), true + case "uarr2": + // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uarr": + // UPWARDS ARROW + return rune(0x2191), true + case "uarrb": + // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "uarrln": + // UPWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2909), true + case "ubrcy": + // CYRILLIC SMALL LETTER SHORT U + return rune(0x045e), true + case "ubreve": + // LATIN SMALL LETTER U WITH BREVE + return rune(0x016d), true + case "ucirc": + // LATIN SMALL LETTER U WITH CIRCUMFLEX + return rune(0xfb), true + case "ucy": + // CYRILLIC SMALL LETTER U + return rune(0x0443), true + case "udarr": + // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "udblac": + // LATIN SMALL LETTER U WITH DOUBLE ACUTE + return rune(0x0171), true + case "udhar": + // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "udiagr": + // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + return rune(0x03b0), true + case "udigr": + // GREEK SMALL LETTER UPSILON WITH DIALYTIKA + return rune(0x03cb), true + case "udrbrk": + // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "udrcub": + // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "udrpar": + // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "ufisht": + // UP FISH TAIL + return rune(0x297e), true + case "ufr": + // MATHEMATICAL FRAKTUR SMALL U + return rune(0x01d532), true + case "ugr": + // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "ugrave": + // LATIN SMALL LETTER U WITH GRAVE + return rune(0xf9), true + case "uharl": + // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "uharr": + // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "uhblk": + // UPPER HALF BLOCK + return rune(0x2580), true + case "ulcorn": + // TOP LEFT CORNER + return rune(0x231c), true + case "ulcorner": + // TOP LEFT CORNER + return rune(0x231c), true + case "ulcrop": + // TOP LEFT CROP + return rune(0x230f), true + case "uldlshar": + // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "ulharb": + // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "ultri": + // UPPER LEFT TRIANGLE + return rune(0x25f8), true + case "umacr": + // LATIN SMALL LETTER U WITH MACRON + return rune(0x016b), true + case "uml": + // DIAERESIS + return rune(0xa8), true + case "uogon": + // LATIN SMALL LETTER U WITH OGONEK + return rune(0x0173), true + case "uopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL U + return rune(0x01d566), true + case "uparrow": + // UPWARDS ARROW + return rune(0x2191), true + case "updownarrow": + // UP DOWN ARROW + return rune(0x2195), true + case "upharpoonleft": + // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "upharpoonright": + // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "upint": + // INTEGRAL WITH OVERBAR + return rune(0x2a1b), true + case "uplus": + // MULTISET UNION + return rune(0x228e), true + case "upsih": + // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "upsilon": + // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upsi": + // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upuparrows": + // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "urcorn": + // TOP RIGHT CORNER + return rune(0x231d), true + case "urcorner": + // TOP RIGHT CORNER + return rune(0x231d), true + case "urcrop": + // TOP RIGHT CROP + return rune(0x230e), true + case "urdrshar": + // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "urharb": + // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "uring": + // LATIN SMALL LETTER U WITH RING ABOVE + return rune(0x016f), true + case "urtrif": + // BLACK UPPER RIGHT TRIANGLE + return rune(0x25e5), true + case "urtri": + // UPPER RIGHT TRIANGLE + return rune(0x25f9), true + case "uscr": + // MATHEMATICAL SCRIPT SMALL U + return rune(0x01d4ca), true + case "utdot": + // UP RIGHT DIAGONAL ELLIPSIS + return rune(0x22f0), true + case "utilde": + // LATIN SMALL LETTER U WITH TILDE + return rune(0x0169), true + case "utrif": + // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "utri": + // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "uuarr": + // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uuml": + // LATIN SMALL LETTER U WITH DIAERESIS + return rune(0xfc), true + case "uwangle": + // OBLIQUE ANGLE OPENING DOWN + return rune(0x29a7), true + } + + case 'v': + switch name { + case "vArr": + // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "vBar": + // SHORT UP TACK WITH UNDERBAR + return rune(0x2ae8), true + case "vBarv": + // SHORT UP TACK ABOVE SHORT DOWN TACK + return rune(0x2ae9), true + case "vDash": + // TRUE + return rune(0x22a8), true + case "vDdash": + // VERTICAL BAR TRIPLE RIGHT TURNSTILE + return rune(0x2ae2), true + case "vangrt": + // RIGHT ANGLE VARIANT WITH SQUARE + return rune(0x299c), true + case "varepsilon": + // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "varkappa": + // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "varnothing": + // EMPTY SET + return rune(0x2205), true + case "varphi": + // GREEK PHI SYMBOL + return rune(0x03d5), true + case "varpi": + // GREEK PI SYMBOL + return rune(0x03d6), true + case "varpropto": + // PROPORTIONAL TO + return rune(0x221d), true + case "varr": + // UP DOWN ARROW + return rune(0x2195), true + case "varrho": + // GREEK RHO SYMBOL + return rune(0x03f1), true + case "varsigma": + // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "varsubsetneq": + // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "varsubsetneqq": + // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "varsupsetneq": + // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "varsupsetneqq": + // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vartheta": + // GREEK THETA SYMBOL + return rune(0x03d1), true + case "vartriangleleft": + // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vartriangleright": + // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vbrtri": + // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "vcy": + // CYRILLIC SMALL LETTER VE + return rune(0x0432), true + case "vdash": + // RIGHT TACK + return rune(0x22a2), true + case "vee": + // LOGICAL OR + return rune(0x2228), true + case "veeBar": + // LOGICAL OR WITH DOUBLE UNDERBAR + return rune(0x2a63), true + case "veebar": + // XOR + return rune(0x22bb), true + case "veeeq": + // EQUIANGULAR TO + return rune(0x225a), true + case "vellip": + // VERTICAL ELLIPSIS + return rune(0x22ee), true + case "vellip4": + // DOTTED FENCE + return rune(0x2999), true + case "vellipv": + // TRIPLE COLON OPERATOR + return rune(0x2af6), true + case "verbar": + // VERTICAL LINE + return rune(0x7c), true + case "vert3": + // TRIPLE VERTICAL BAR BINARY RELATION + return rune(0x2af4), true + case "vert": + // VERTICAL LINE + return rune(0x7c), true + case "vfr": + // MATHEMATICAL FRAKTUR SMALL V + return rune(0x01d533), true + case "vldash": + // LEFT SQUARE BRACKET LOWER CORNER + return rune(0x23a3), true + case "vltri": + // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vnsub": + // SUBSET OF with vertical line + return rune(0x2282), true + case "vnsup": + // SUPERSET OF with vertical line + return rune(0x2283), true + case "vopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL V + return rune(0x01d567), true + case "vprime": + // PRIME + return rune(0x2032), true + case "vprop": + // PROPORTIONAL TO + return rune(0x221d), true + case "vrtri": + // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vscr": + // MATHEMATICAL SCRIPT SMALL V + return rune(0x01d4cb), true + case "vsubnE": + // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "vsubne": + // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "vsupnE": + // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vsupne": + // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "vzigzag": + // VERTICAL ZIGZAG LINE + return rune(0x299a), true + } + + case 'w': + switch name { + case "wcirc": + // LATIN SMALL LETTER W WITH CIRCUMFLEX + return rune(0x0175), true + case "wedbar": + // LOGICAL AND WITH UNDERBAR + return rune(0x2a5f), true + case "wedge": + // LOGICAL AND + return rune(0x2227), true + case "wedgeq": + // ESTIMATES + return rune(0x2259), true + case "weierp": + // SCRIPT CAPITAL P + return rune(0x2118), true + case "wfr": + // MATHEMATICAL FRAKTUR SMALL W + return rune(0x01d534), true + case "wopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL W + return rune(0x01d568), true + case "wp": + // SCRIPT CAPITAL P + return rune(0x2118), true + case "wreath": + // WREATH PRODUCT + return rune(0x2240), true + case "wr": + // WREATH PRODUCT + return rune(0x2240), true + case "wscr": + // MATHEMATICAL SCRIPT SMALL W + return rune(0x01d4cc), true + } + + case 'x': + switch name { + case "xandand": + // TWO LOGICAL AND OPERATOR + return rune(0x2a07), true + case "xbsol": + // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "xcap": + // N-ARY INTERSECTION + return rune(0x22c2), true + case "xcirc": + // LARGE CIRCLE + return rune(0x25ef), true + case "xcup": + // N-ARY UNION + return rune(0x22c3), true + case "xcupdot": + // N-ARY UNION OPERATOR WITH DOT + return rune(0x2a03), true + case "xdtri": + // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "xfr": + // MATHEMATICAL FRAKTUR SMALL X + return rune(0x01d535), true + case "xgr": + // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xhArr": + // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "xharr": + // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "xi": + // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xlArr": + // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "xlarr": + // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "xmap": + // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "xnis": + // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fb), true + case "xodot": + // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "xopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL X + return rune(0x01d569), true + case "xoplus": + // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "xoror": + // TWO LOGICAL OR OPERATOR + return rune(0x2a08), true + case "xotime": + // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "xrArr": + // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "xrarr": + // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "xscr": + // MATHEMATICAL SCRIPT SMALL X + return rune(0x01d4cd), true + case "xsol": + // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "xsqcap": + // N-ARY SQUARE INTERSECTION OPERATOR + return rune(0x2a05), true + case "xsqcup": + // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "xsqu": + // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "xsquf": + // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "xtimes": + // N-ARY TIMES OPERATOR + return rune(0x2a09), true + case "xuplus": + // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "xutri": + // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "xvee": + // N-ARY LOGICAL OR + return rune(0x22c1), true + case "xwedge": + // N-ARY LOGICAL AND + return rune(0x22c0), true + } + + case 'y': + switch name { + case "yacute": + // LATIN SMALL LETTER Y WITH ACUTE + return rune(0xfd), true + case "yacy": + // CYRILLIC SMALL LETTER YA + return rune(0x044f), true + case "ycirc": + // LATIN SMALL LETTER Y WITH CIRCUMFLEX + return rune(0x0177), true + case "ycy": + // CYRILLIC SMALL LETTER YERU + return rune(0x044b), true + case "yen": + // YEN SIGN + return rune(0xa5), true + case "yfr": + // MATHEMATICAL FRAKTUR SMALL Y + return rune(0x01d536), true + case "yicy": + // CYRILLIC SMALL LETTER YI + return rune(0x0457), true + case "yopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL Y + return rune(0x01d56a), true + case "yscr": + // MATHEMATICAL SCRIPT SMALL Y + return rune(0x01d4ce), true + case "yucy": + // CYRILLIC SMALL LETTER YU + return rune(0x044e), true + case "yuml": + // LATIN SMALL LETTER Y WITH DIAERESIS + return rune(0xff), true + } + + case 'z': + switch name { + case "zacute": + // LATIN SMALL LETTER Z WITH ACUTE + return rune(0x017a), true + case "zcaron": + // LATIN SMALL LETTER Z WITH CARON + return rune(0x017e), true + case "zcy": + // CYRILLIC SMALL LETTER ZE + return rune(0x0437), true + case "zdot": + // LATIN SMALL LETTER Z WITH DOT ABOVE + return rune(0x017c), true + case "zeetrf": + // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "zeta": + // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zfr": + // MATHEMATICAL FRAKTUR SMALL Z + return rune(0x01d537), true + case "zgr": + // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zhcy": + // CYRILLIC SMALL LETTER ZHE + return rune(0x0436), true + case "zigrarr": + // RIGHTWARDS SQUIGGLE ARROW + return rune(0x21dd), true + case "zopf": + // MATHEMATICAL DOUBLE-STRUCK SMALL Z + return rune(0x01d56b), true + case "zscr": + // MATHEMATICAL SCRIPT SMALL Z + return rune(0x01d4cf), true + case "zwj": + // ZERO WIDTH JOINER + return rune(0x200d), true + case "zwnj": + // ZERO WIDTH NON-JOINER + return rune(0x200c), true + } + } + return -1, false +} + +/* + ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ +*/ diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 563294309..146c278cb 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -519,8 +519,6 @@ parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) _ = expect(t, .Eq) or_return value := expect(t, .String) or_return - error(t, t.offset, "String: %v\n", value) - attr.key = strings.intern_get(&doc.intern, key.text) attr.val = strings.intern_get(&doc.intern, value.text) diff --git a/core/unicode/tools/generate_entity_table.odin b/core/unicode/tools/generate_entity_table.odin new file mode 100644 index 000000000..075ec1cca --- /dev/null +++ b/core/unicode/tools/generate_entity_table.odin @@ -0,0 +1,287 @@ +package xml_example + +import "core:encoding/xml" +import "core:os" +import "core:path" +import "core:mem" +import "core:strings" +import "core:strconv" +import "core:slice" +import "core:fmt" + +/* + Silent error handler for the parser. +*/ +Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) {} + +OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, }, expected_doctype = "unicode", } + +Entity :: struct { + name: string, + codepoint: rune, + description: string, +} + +generate_encoding_entity_table :: proc() { + using fmt + + filename := path.join(ODIN_ROOT, "tests", "core", "assets", "XML", "unicode.xml") + defer delete(filename) + + generated_filename := path.join(ODIN_ROOT, "core", "encoding", "entity", "generated.odin") + defer delete(generated_filename) + + doc, err := xml.parse(filename, OPTIONS, Error_Handler) + defer xml.destroy(doc) + + if err != .None { + printf("Load/Parse error: %v\n", err) + if err == .File_Error { + printf("\"%v\" not found. Did you run \"tests\\download_assets.py\"?", filename) + } + os.exit(1) + } + + printf("\"%v\" loaded and parsed.\n", filename) + + generated_buf: strings.Builder + defer strings.destroy_builder(&generated_buf) + w := strings.to_writer(&generated_buf) + + charlist, charlist_ok := xml.find_child_by_ident(doc.root, "charlist") + if !charlist_ok { + eprintln("Could not locate top-level `` tag.") + os.exit(1) + } + + printf("Found `` with %v children.\n", len(charlist.children)) + + entity_map: map[string]Entity + names: [dynamic]string + + min_name_length := max(int) + max_name_length := min(int) + shortest_name: string + longest_name: string + + count := 0 + for char in charlist.children { + if char.ident != "character" { + eprintf("Expected ``, got `<%v>`\n", char.ident) + os.exit(1) + } + + if codepoint_string, ok := xml.find_attribute_val_by_key(char, "dec"); !ok { + eprintln("`` attribute not found.") + os.exit(1) + } else { + codepoint := strconv.atoi(codepoint_string) + + desc, desc_ok := xml.find_child_by_ident(char, "description") + description := desc.value if desc_ok else "" + + /* + For us to be interested in this codepoint, it has to have at least one entity. + */ + + nth := 0 + for { + character_entity, entity_ok := xml.find_child_by_ident(char, "entity", nth) + if !entity_ok { break } + + nth += 1 + if name, name_ok := xml.find_attribute_val_by_key(character_entity, "id"); name_ok { + + if len(name) == 0 { + /* + Invalid name. Skip. + */ + continue + } + + if name == "\"\"" { + printf("%#v\n", char) + printf("%#v\n", character_entity) + } + + if len(name) > max_name_length { longest_name = name } + if len(name) < min_name_length { shortest_name = name } + + min_name_length = min(min_name_length, len(name)) + max_name_length = max(max_name_length, len(name)) + + e := Entity{ + name = name, + codepoint = rune(codepoint), + description = description, + } + + if _, seen := entity_map[name]; seen { + continue + } + + entity_map[name] = e + append(&names, name) + count += 1 + } + } + } + } + + /* + Sort by name. + */ + slice.sort(names[:]) + + printf("Found %v unique `&name;` -> rune mappings.\n", count) + printf("Shortest name: %v (%v)\n", shortest_name, min_name_length) + printf("Longest name: %v (%v)\n", longest_name, max_name_length) + + // println(rune_to_string(1234)) + + /* + Generate table. + */ + wprintln(w, "package unicode_entity") + wprintln(w, "") + wprintln(w, GENERATED) + wprintln(w, "") + wprintf (w, TABLE_FILE_PROLOG) + wprintln(w, "") + + wprintf (w, "// `&%v;`\n", shortest_name) + wprintf (w, "XML_NAME_TO_RUNE_MIN_LENGTH :: %v\n", min_name_length) + wprintf (w, "// `&%v;`\n", longest_name) + wprintf (w, "XML_NAME_TO_RUNE_MAX_LENGTH :: %v\n", max_name_length) + wprintln(w, "") + + wprintln(w, +` +/* + Input: + entity_name - a string, like "copy" that describes a user-encoded Unicode entity as used in XML. + + Output: + "decoded" - The decoded rune if found by name, or -1 otherwise. + "ok" - true if found, false if not. + + IMPORTANT: XML processors (including browsers) treat these names as case-sensitive. So do we. +*/ +named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { + /* + Early out if the name is too short or too long. + min as a precaution in case the generated table has a bogus value. + */ + if len(name) < min(1, XML_NAME_TO_RUNE_MIN_LENGTH) || len(name) > XML_NAME_TO_RUNE_MAX_LENGTH { + return -1, false + } + + switch rune(name[0]) { +`) + + prefix := '?' + should_close := false + + for v in names { + if rune(v[0]) != prefix { + if should_close { + wprintln(w, "\t\t}\n") + } + + prefix = rune(v[0]) + wprintf (w, "\tcase '%v':\n", prefix) + wprintln(w, "\t\tswitch name {") + } + + e := entity_map[v] + + wprintf(w, "\t\t\tcase \"%v\": \n", e.name) + wprintf(w, "\t\t\t\t// %v\n", e.description) + wprintf(w, "\t\t\t\treturn %v, true\n", rune_to_string(e.codepoint)) + + should_close = true + } + wprintln(w, "\t\t}") + wprintln(w, "\t}") + wprintln(w, "\treturn -1, false") + wprintln(w, "}\n") + wprintln(w, GENERATED) + + println() + println(strings.to_string(generated_buf)) + println() + + written := os.write_entire_file(generated_filename, transmute([]byte)strings.to_string(generated_buf)) + + if written { + fmt.printf("Successfully written generated \"%v\".", generated_filename) + } else { + fmt.printf("Failed to write generated \"%v\".", generated_filename) + } + + delete(entity_map) + delete(names) + for name in &names { + free(&name) + } +} + +GENERATED :: `/* + ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ DO NOT EDIT ------ GENERATED ------ +*/` + +TABLE_FILE_PROLOG :: `/* + This file is generated from "https://www.w3.org/2003/entities/2007xml/unicode.xml". + + UPDATE: + - Ensure the XML file was downloaded using "tests\core\download_assets.py". + - Run "core/unicode/tools/generate_entity_table.odin" + + Odin unicode generated tables: https://github.com/odin-lang/Odin/tree/master/core/encoding/entity + + Copyright © 2021 World Wide Web Consortium, (Massachusetts Institute of Technology, + European Research Consortium for Informatics and Mathematics, Keio University, Beihang). + + All Rights Reserved. + + This work is distributed under the W3C® Software License [1] in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + [1] http://www.w3.org/Consortium/Legal/copyright-software + + See also: LICENSE_table.md +*/ +` + +rune_to_string :: proc(r: rune) -> (res: string) { + res = fmt.tprintf("%08x", int(r)) + for len(res) > 2 && res[:2] == "00" { + res = res[2:] + } + return fmt.tprintf("rune(0x%v)", res) +} + +is_dotted_name :: proc(name: string) -> (dotted: bool) { + for r in name { + if r == '.' { return true} + } + return false +} + +main :: proc() { + using fmt + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + generate_encoding_entity_table() + + if len(track.allocation_map) > 0 { + println() + for _, v in track.allocation_map { + printf("%v Leaked %v bytes.\n", v.location, v.size) + } + } + println("Done and cleaned up!") +} \ No newline at end of file From 3d72e80ccf0f382f03a1c9407c4728862c5bca91 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 2 Dec 2021 21:07:40 +0100 Subject: [PATCH 011/245] [xml] Implement optional unboxing of CDATA and decoding of tag values. --- core/encoding/entity/entity.odin | 39 ++++++----- .../entity/example/entity_example.odin | 67 +++---------------- core/encoding/entity/example/test.html | 2 + core/encoding/xml/xml_reader.odin | 41 ++++++------ 4 files changed, 56 insertions(+), 93 deletions(-) diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin index e40896819..8742446e6 100644 --- a/core/encoding/entity/entity.odin +++ b/core/encoding/entity/entity.odin @@ -60,16 +60,22 @@ COMMENT_END :: "-->" Default: CDATA and comments are passed through unchanged. */ XML_Decode_Option :: enum u8 { + /* + Do not decode & entities. It decodes by default. + If given, overrides `Decode_CDATA`. + */ + No_Entity_Decode, + /* CDATA is unboxed. */ - CDATA_Unbox, + Unbox_CDATA, /* Unboxed CDATA is decoded as well. - Ignored if `.CDATA_Unbox` is not given. + Ignored if `.Unbox_CDATA` is not given. */ - CDATA_Decode, + Decode_CDATA, /* Comments are stripped. @@ -129,7 +135,7 @@ decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator := } case: - if in_data && .CDATA_Decode not_in options { + if in_data && .Decode_CDATA not_in options { /* Unboxed, but undecoded. */ @@ -145,17 +151,20 @@ decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator := */ write_string(&builder, entity) } else { - if decoded, ok := xml_decode_entity(entity); ok { - write_rune(&builder, decoded) - } else { - /* - Decode failed. Pass through original. - */ - write_string(&builder, "&") - write_string(&builder, entity) - write_string(&builder, ";") + + if .No_Entity_Decode not_in options { + if decoded, ok := xml_decode_entity(entity); ok { + write_rune(&builder, decoded) + continue + } } + /* + Literal passthrough because the decode failed or we want entities not decoded. + */ + write_string(&builder, "&") + write_string(&builder, entity) + write_string(&builder, ";") } } else { write_rune(&builder, t.r) @@ -290,7 +299,7 @@ _handle_xml_special :: proc(t: ^Tokenizer, builder: ^strings.Builder, options: X if string(t.src[t.offset:][:len(CDATA_START)]) == CDATA_START { t.read_offset += len(CDATA_START) - 1 - if .CDATA_Unbox in options && .CDATA_Decode in options { + if .Unbox_CDATA in options && .Decode_CDATA in options { /* We're unboxing _and_ decoding CDATA */ @@ -315,7 +324,7 @@ _handle_xml_special :: proc(t: ^Tokenizer, builder: ^strings.Builder, options: X cdata := string(t.src[offset : t.read_offset]) - if .CDATA_Unbox in options { + if .Unbox_CDATA in options { cdata = cdata[len(CDATA_START):] cdata = cdata[:len(cdata) - len(CDATA_END)] } diff --git a/core/encoding/entity/example/entity_example.odin b/core/encoding/entity/example/entity_example.odin index 8758d9ad9..161a44827 100644 --- a/core/encoding/entity/example/entity_example.odin +++ b/core/encoding/entity/example/entity_example.odin @@ -1,19 +1,11 @@ package unicode_entity_example import "core:encoding/xml" -import "core:encoding/entity" import "core:strings" import "core:mem" import "core:fmt" import "core:time" -OPTIONS :: xml.Options{ - flags = { - .Ignore_Unsupported, .Intern_Comments, - }, - expected_doctype = "", -} - doc_print :: proc(doc: ^xml.Document) { buf: strings.Builder defer strings.destroy_builder(&buf) @@ -29,6 +21,13 @@ _entities :: proc() { DOC :: #load("../../../../tests/core/assets/XML/unicode.xml") + OPTIONS :: xml.Options{ + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "", + } + parse_duration: time.Duration { @@ -50,57 +49,11 @@ _entities :: proc() { _main :: proc() { using fmt - doc, err := xml.parse(#load("test.html")) + options := xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities }} + doc, _ := xml.parse(#load("test.html"), options) + defer xml.destroy(doc) doc_print(doc) - - if false { - val := doc.root.children[1].children[2].value - - println() - replaced, ok := entity.decode_xml(val) - defer delete(replaced) - - printf("Before: '%v', Err: %v\n", val, err) - printf("Passthrough: '%v'\nOK: %v\n", replaced, ok) - println() - } - - if false { - val := doc.root.children[1].children[2].value - - println() - replaced, ok := entity.decode_xml(val, { .CDATA_Unbox }) - defer delete(replaced) - - printf("Before: '%v', Err: %v\n", val, err) - printf("CDATA_Unbox: '%v'\nOK: %v\n", replaced, ok) - println() - } - - if true { - val := doc.root.children[1].children[2].value - - println() - replaced, ok := entity.decode_xml(val, { .CDATA_Unbox, .CDATA_Decode }) - defer delete(replaced) - - printf("Before: '%v', Err: %v\n", val, err) - printf("CDATA_Decode: '%v'\nOK: %v\n", replaced, ok) - println() - } - - if true { - val := doc.root.children[1].children[1].value - - println() - replaced, ok := entity.decode_xml(val, { .Comment_Strip }) - defer delete(replaced) - - printf("Before: '%v', Err: %v\n", val, err) - printf("Comment_Strip: '%v'\nOK: %v\n", replaced, ok) - println() - } } main :: proc() { diff --git a/core/encoding/entity/example/test.html b/core/encoding/entity/example/test.html index 60e32bf03..62a0bb35a 100644 --- a/core/encoding/entity/example/test.html +++ b/core/encoding/entity/example/test.html @@ -16,9 +16,11 @@
Foozle]! © 42&;1234&
+
Foozle]! © 42&;1234&
+
| | | fj ` \ ® ϱ ∳
diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 146c278cb..6f49b8e08 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -18,10 +18,6 @@ package xml - We do NOT support UTF-16. If you have a UTF-16 XML file, please convert it to UTF-8 first. Also, our condolences. - <[!ELEMENT and <[!ATTLIST are not supported, and will be either ignored or return an error depending on the parser options. - TODO: - - Optional CDATA unboxing. - - Optional `>`, ` `, ` ` and other escape substitution in tag bodies. - MAYBE: - XML writer? - Serialize/deserialize Odin types? @@ -31,6 +27,7 @@ package xml */ import "core:strings" +import "core:encoding/entity" import "core:mem" import "core:os" @@ -196,12 +193,6 @@ Error :: enum { Duplicate_Attribute, Conflicting_Options, - - /* - Unhandled TODO: - */ - Unhandled_CDATA_Unboxing, - Unhandled_SGML_Entity_Decoding, } /* @@ -422,8 +413,25 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err /* This should be a tag's body text. */ - body_text := scan_string(t, t.offset) or_return - element.value = strings.intern_get(&doc.intern, body_text) + body_text := scan_string(t, t.offset) or_return + + decode_opts := entity.XML_Decode_Options{ .Comment_Strip } + + if .Decode_SGML_Entities not_in opts.flags { + decode_opts += { .No_Entity_Decode } + } + if .Unbox_CDATA in opts.flags { + decode_opts += { .Unbox_CDATA, .Decode_CDATA } + } + + decoded, decode_err := entity.decode_xml(body_text, decode_opts) + defer delete(decoded) + + if decode_err == .None { + element.value = strings.intern_get(&doc.intern, decoded) + } else { + element.value = strings.intern_get(&doc.intern, body_text) + } } } @@ -488,15 +496,6 @@ validate_options :: proc(options: Options) -> (validated: Options, err: Error) { if .Error_on_Unsupported in validated.flags && .Ignore_Unsupported in validated.flags { return options, .Conflicting_Options } - - if .Unbox_CDATA in validated.flags { - return options, .Unhandled_CDATA_Unboxing - } - - if .Decode_SGML_Entities in validated.flags { - return options, .Unhandled_SGML_Entity_Decoding - } - return validated, .None } From d65d6edb0e1887871c4de6a4e8a1630927153eae Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 5 Dec 2021 02:17:48 +0100 Subject: [PATCH 012/245] [xml] Improve XML tests, test `core:encoding/entity`. --- core/encoding/entity/entity.odin | 7 + .../entity/example/entity_example.odin | 1 + core/encoding/entity/example/test.html | 2 +- tests/core/assets/XML/entities.html | 29 ++ ...-xliff-1.0.xliff => nl_NL-xliff-1.2.xliff} | 0 tests/core/assets/XML/utf8.xml | 2 +- tests/core/encoding/xml/test_core_xml.odin | 426 +++++++++++------- 7 files changed, 291 insertions(+), 176 deletions(-) create mode 100644 tests/core/assets/XML/entities.html rename tests/core/assets/XML/{nl_NL-xliff-1.0.xliff => nl_NL-xliff-1.2.xliff} (100%) diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin index 8742446e6..db1a5ad0b 100644 --- a/core/encoding/entity/entity.odin +++ b/core/encoding/entity/entity.odin @@ -115,7 +115,14 @@ decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator := We don't need to check if we need to write a `<`, because if it isn't CDATA or a comment, it couldn't have been part of an XML tag body to be decoded here. + + Keep in mind that we could already *be* inside a CDATA tag. + If so, write `>` as a literal and continue. */ + if in_data { + write_rune(&builder, '<') + continue + } in_data = _handle_xml_special(&t, &builder, options) or_return case ']': diff --git a/core/encoding/entity/example/entity_example.odin b/core/encoding/entity/example/entity_example.odin index 161a44827..882203f48 100644 --- a/core/encoding/entity/example/entity_example.odin +++ b/core/encoding/entity/example/entity_example.odin @@ -50,6 +50,7 @@ _main :: proc() { using fmt options := xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities }} + doc, _ := xml.parse(#load("test.html"), options) defer xml.destroy(doc) diff --git a/core/encoding/entity/example/test.html b/core/encoding/entity/example/test.html index 62a0bb35a..ebbc6470c 100644 --- a/core/encoding/entity/example/test.html +++ b/core/encoding/entity/example/test.html @@ -22,7 +22,7 @@
- | | | fj ` \ ® ϱ ∳ + | | | fj ` \ ® ϱ ∳ ⁏
\ No newline at end of file diff --git a/tests/core/assets/XML/entities.html b/tests/core/assets/XML/entities.html new file mode 100644 index 000000000..05a6b107e --- /dev/null +++ b/tests/core/assets/XML/entities.html @@ -0,0 +1,29 @@ + + + Entity Reference Test + + + +

Entity Reference Test

+
+ Foozle]! © 42&;1234& +
+ + +
+ Foozle]! © 42&;1234& +
+ +
+ | | | fj ` \ ® ϱ ∳ ⁏ +
+ + \ No newline at end of file diff --git a/tests/core/assets/XML/nl_NL-xliff-1.0.xliff b/tests/core/assets/XML/nl_NL-xliff-1.2.xliff similarity index 100% rename from tests/core/assets/XML/nl_NL-xliff-1.0.xliff rename to tests/core/assets/XML/nl_NL-xliff-1.2.xliff diff --git a/tests/core/assets/XML/utf8.xml b/tests/core/assets/XML/utf8.xml index c9ed3bf69..6e1a897ea 100644 --- a/tests/core/assets/XML/utf8.xml +++ b/tests/core/assets/XML/utf8.xml @@ -4,5 +4,5 @@ <부끄러운:barzle> ရှက်စရာ ဇီးကွက် Owl of Shame - More CDATA Hello, world! Nonsense. + More CDATA Hello, world! Nonsense. \ No newline at end of file diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index c2e0aa172..5cb59e001 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -3,16 +3,16 @@ package test_core_xml import "core:encoding/xml" import "core:testing" import "core:mem" +import "core:strings" +import "core:io" import "core:fmt" +import "core:hash" Silent :: proc(pos: xml.Pos, fmt: string, args: ..any) { // Custom (silent) error handler. } -OPTIONS :: xml.Options{ - flags = { - .Ignore_Unsupported, .Intern_Comments, - }, +OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, }, expected_doctype = "", } @@ -22,76 +22,153 @@ TEST_fail := 0 TEST :: struct { filename: string, options: xml.Options, - expected: struct { - error: xml.Error, - xml_version: string, - xml_encoding: string, - doctype: string, - }, + err: xml.Error, + crc32: u32, } +/* + Relative to ODIN_ROOT +*/ +TEST_FILE_PATH_PREFIX :: "tests/core/assets/XML" + TESTS :: []TEST{ /* First we test that certain files parse without error. */ + { - filename = "assets/XML/utf8.xml", - options = OPTIONS, - expected = { - error = .None, - xml_version = "1.0", - xml_encoding = "utf-8", - doctype = "恥ずべきフクロウ", + /* + + + <恥ずべきフクロウ 올빼미_id="Foozle Hello, world!"]]>Barzle"> + <부끄러운:barzle> + ရှက်စရာ ဇီးကွက် + Owl of Shame + More CDATA Hello, world! Nonsense. + + */ + + /* + Tests UTF-8 idents and values. + Test namespaced ident. + Tests that nested partial CDATA start doesn't trip up parser. + */ + filename = "utf8.xml", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "恥ずべきフクロウ", }, + crc32 = 0x30d82264, }, + { - filename = "assets/XML/nl_NL-qt-ts.ts", - options = OPTIONS, - expected = { - error = .None, - xml_version = "1.0", - xml_encoding = "utf-8", - doctype = "TS", + /* + Same as above. + Unbox CDATA in data tag. + */ + filename = "utf8.xml", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, + }, + expected_doctype = "恥ずべきフクロウ", }, + crc32 = 0x6d38ac58, }, + { - filename = "assets/XML/nl_NL-xliff-1.0.xliff", - options = OPTIONS, - expected = { - error = .None, - xml_version = "1.0", - xml_encoding = "UTF-8", - doctype = "", + /* + Simple Qt TS translation file. + `core:i18n` requires it to be parsed properly. + */ + filename = "nl_NL-qt-ts.ts", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, + }, + expected_doctype = "TS", }, + crc32 = 0x7bce2630, }, + { - filename = "assets/XML/nl_NL-xliff-2.0.xliff", - options = OPTIONS, - expected = { - error = .None, - xml_version = "1.0", - xml_encoding = "utf-8", - doctype = "", + /* + Simple XLiff 1.2 file. + `core:i18n` requires it to be parsed properly. + */ + filename = "nl_NL-xliff-1.2.xliff", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, + }, + expected_doctype = "xliff", }, + crc32 = 0x43f19d61, + }, + + { + /* + Simple XLiff 2.0 file. + `core:i18n` requires it to be parsed properly. + */ + filename = "nl_NL-xliff-2.0.xliff", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, + }, + expected_doctype = "xliff", + }, + crc32 = 0x961e7635, + }, + + { + filename = "entities.html", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, + }, + expected_doctype = "html", + }, + crc32 = 0xdb4a1e79, + }, + + { + filename = "entities.html", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, + }, + expected_doctype = "html", + }, + crc32 = 0x82588917, + }, + + { + filename = "entities.html", + options = { + flags = { + .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, + }, + expected_doctype = "html", + }, + crc32 = 0x5e74d8a6, }, /* Then we test that certain errors are returned as expected. */ { - filename = "assets/XML/utf8.xml", + filename = "utf8.xml", options = { flags = { .Ignore_Unsupported, .Intern_Comments, }, expected_doctype = "Odin", }, - expected = { - error = .Invalid_DocType, - xml_version = "1.0", - xml_encoding = "utf-8", - doctype = "恥ずべきフクロウ", - }, + err = .Invalid_DocType, + crc32 = 0x49b83d0a, }, } @@ -115,6 +192,136 @@ when ODIN_TEST { } } +test_file_path :: proc(filename: string) -> (path: string) { + + path = fmt.tprintf("%v%v/%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename) + temp := transmute([]u8)path + + for r, i in path { + if r == '\\' { + temp[i] = '/' + } + } + return path +} + +doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { + /* + Effectively a clone of the debug printer in the xml package. + We duplicate it here so that the way it prints an XML document to a string is stable. + + This way we can hash the output. If it changes, it means that the document or how it was parsed changed, + not how it was printed. One less source of variability. + */ + print :: proc(writer: io.Writer, doc: ^xml.Document) -> (written: int, err: io.Error) { + if doc == nil { return } + using fmt + + written += wprintf(writer, "[XML Prolog]\n") + + for attr in doc.prolog { + written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val) + } + + written += wprintf(writer, "[Encoding] %v\n", doc.encoding) + + if len(doc.doctype.ident) > 0 { + written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) + + if len(doc.doctype.rest) > 0 { + wprintf(writer, "\t%v\n", doc.doctype.rest) + } + } + + for comment in doc.comments { + written += wprintf(writer, "[Pre-root comment] %v\n", comment) + } + + if doc.root != nil { + wprintln(writer, " --- ") + print_element(writer, doc.root) + wprintln(writer, " --- ") + } + + return written, .None + } + + print_element :: proc(writer: io.Writer, element: ^xml.Element, indent := 0) -> (written: int, err: io.Error) { + if element == nil { return } + using fmt + + tab :: proc(writer: io.Writer, indent: int) { + for _ in 0..=indent { + wprintf(writer, "\t") + } + } + + tab(writer, indent) + + if element.kind == .Element { + wprintf(writer, "<%v>\n", element.ident) + if len(element.value) > 0 { + tab(writer, indent + 1) + wprintf(writer, "[Value] %v\n", element.value) + } + + for attr in element.attribs { + tab(writer, indent + 1) + wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val) + } + + for child in element.children { + print_element(writer, child, indent + 1) + } + } else if element.kind == .Comment { + wprintf(writer, "[COMMENT] %v\n", element.value) + } + + return written, .None + } + + buf: strings.Builder + defer strings.destroy_builder(&buf) + + print(strings.to_writer(&buf), doc) + return strings.clone(strings.to_string(buf)) +} + +@test +run_tests :: proc(t: ^testing.T) { + using fmt + + for test in TESTS { + path := test_file_path(test.filename) + printf("\nTrying to parse %v\n\n", path) + + doc, err := xml.parse(path, test.options, Silent) + defer xml.destroy(doc) + + tree_string := doc_to_string(doc) + tree_bytes := transmute([]u8)tree_string + defer delete(tree_bytes) + + crc32 := hash.crc32(tree_bytes) + + failed := err != test.err + err_msg := tprintf("Expected return value %v, got %v", test.err, err) + expect(t, err == test.err, err_msg) + + failed |= crc32 != test.crc32 + err_msg = tprintf("Expected CRC 0x%08x, got 0x%08x", test.crc32, crc32) + expect(t, crc32 == test.crc32, err_msg) + + if failed { + /* + Don't fully print big trees. + */ + tree_string = tree_string[:min(2_048, len(tree_string))] + println(tree_string) + } + } +} + main :: proc() { t := testing.T{} @@ -132,133 +339,4 @@ main :: proc() { } fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) -} - -@test -run_tests :: proc(t: ^testing.T) { - using fmt - - count := 0 - - for test in TESTS { - printf("Trying to parse %v\n\n", test.filename) - - doc, err := xml.parse(test.filename, test.options, Silent) - defer xml.destroy(doc) - - err_msg := tprintf("Expected return value %v, got %v", test.expected.error, err) - expect(t, err == test.expected.error, err_msg) - - if len(test.expected.xml_version) > 0 { - xml_version := "" - for attr in doc.prolog { - if attr.key == "version" { - xml_version = attr.val - } - } - - err_msg = tprintf("Expected XML version %v, got %v", test.expected.xml_version, xml_version) - expect(t, xml_version == test.expected.xml_version, err_msg) - } - - if len(test.expected.xml_encoding) > 0 { - xml_encoding := "" - for attr in doc.prolog { - if attr.key == "encoding" { - xml_encoding = attr.val - } - } - - err_msg = tprintf("Expected XML encoding %v, got %v", test.expected.xml_encoding, xml_encoding) - expect(t, xml_encoding == test.expected.xml_encoding, err_msg) - } - - err_msg = tprintf("Expected DOCTYPE %v, got %v", test.expected.doctype, doc.doctype.ident) - expect(t, doc.doctype.ident == test.expected.doctype, err_msg) - - /* - File-specific tests. - */ - switch count { - case 0: - expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") - attr := doc.root.attribs[0] - - attr_key_expected := "올빼미_id" - attr_val_expected := "Foozle Hello, world!\"]]>Barzle" - - attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) - expect(t, attr.key == attr_key_expected, attr_err) - - attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) - expect(t, attr.val == attr_val_expected, attr_err) - - expect(t, len(doc.root.children) > 0, "Expected the root tag to have children.") - child := doc.root.children[0] - - first_child_ident := "부끄러운:barzle" - attr_err = tprintf("Expected first child tag's ident to be %v, got %v", first_child_ident, child.ident) - expect(t, child.ident == first_child_ident, attr_err) - - case 2: - expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") - - { - attr := doc.root.attribs[0] - - attr_key_expected := "version" - attr_val_expected := "1.2" - - attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) - expect(t, attr.key == attr_key_expected, attr_err) - - attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) - expect(t, attr.val == attr_val_expected, attr_err) - } - - { - attr := doc.root.attribs[1] - - attr_key_expected := "xmlns" - attr_val_expected := "urn:oasis:names:tc:xliff:document:1.2" - - attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) - expect(t, attr.key == attr_key_expected, attr_err) - - attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) - expect(t, attr.val == attr_val_expected, attr_err) - } - - case 3: - expect(t, len(doc.root.attribs) > 0, "Expected the root tag to have an attribute.") - - { - attr := doc.root.attribs[0] - - attr_key_expected := "xmlns" - attr_val_expected := "urn:oasis:names:tc:xliff:document:2.0" - - attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) - expect(t, attr.key == attr_key_expected, attr_err) - - attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) - expect(t, attr.val == attr_val_expected, attr_err) - } - - { - attr := doc.root.attribs[1] - - attr_key_expected := "version" - attr_val_expected := "2.0" - - attr_err := tprintf("Expected %v, got %v", attr_key_expected, attr.key) - expect(t, attr.key == attr_key_expected, attr_err) - - attr_err = tprintf("Expected %v, got %v", attr_val_expected, attr.val) - expect(t, attr.val == attr_val_expected, attr_err) - } - } - - count += 1 - } } \ No newline at end of file From d7200f61441b6acfc4f0b47e900095f08490da58 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 5 Dec 2021 02:40:13 +0100 Subject: [PATCH 013/245] Improve tests in general. Less spammy core tests: They don't print PASSes now, only logs and failures. `core:image` and `core:encoding/xml` tests also find their assets relative to `ODIN_ROOT` now. --- tests/core/compress/test_core_compress.odin | 9 +- tests/core/crypto/test_core_crypto.odin | 1691 +++++++++--------- tests/core/encoding/json/test_core_json.odin | 9 +- tests/core/encoding/xml/test_core_xml.odin | 43 +- tests/core/hash/test_core_hash.odin | 9 +- tests/core/image/test_core_image.odin | 51 +- tests/core/odin/test_parser.odin | 37 +- tests/core/strings/test_core_strings.odin | 59 +- 8 files changed, 948 insertions(+), 960 deletions(-) diff --git a/tests/core/compress/test_core_compress.odin b/tests/core/compress/test_core_compress.odin index c925c0258..908ef12e4 100644 --- a/tests/core/compress/test_core_compress.odin +++ b/tests/core/compress/test_core_compress.odin @@ -30,18 +30,15 @@ when ODIN_TEST { log :: testing.log } else { expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) TEST_count += 1 if !condition { TEST_fail += 1 - fmt.println(message) + fmt.printf("[%v] %v\n", loc, message) return } - fmt.println(" PASS") } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) } } @@ -51,7 +48,7 @@ main :: proc() { zlib_test(&t) gzip_test(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } @test diff --git a/tests/core/crypto/test_core_crypto.odin b/tests/core/crypto/test_core_crypto.odin index 2ad00be66..6d3a9f8e4 100644 --- a/tests/core/crypto/test_core_crypto.odin +++ b/tests/core/crypto/test_core_crypto.odin @@ -1,15 +1,15 @@ package test_core_crypto /* - Copyright 2021 zhibog - Made available under the BSD-3 license. + Copyright 2021 zhibog + Made available under the BSD-3 license. - List of contributors: - zhibog, dotbmp: Initial implementation. - Jeroen van Rijn: Test runner setup. + List of contributors: + zhibog, dotbmp: Initial implementation. + Jeroen van Rijn: Test runner setup. - Tests for the hashing algorithms within the crypto library. - Where possible, the official test vectors are used to validate the implementation. + Tests for the hashing algorithms within the crypto library. + Where possible, the official test vectors are used to validate the implementation. */ import "core:testing" @@ -41,1065 +41,1062 @@ TEST_count := 0 TEST_fail := 0 when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + } } main :: proc() { - t := testing.T{} - test_md2(&t) - test_md4(&t) - test_md5(&t) - test_sha1(&t) - test_sha224(&t) - test_sha256(&t) - test_sha384(&t) - test_sha512(&t) - test_sha3_224(&t) - test_sha3_256(&t) - test_sha3_384(&t) - test_sha3_512(&t) - test_shake_128(&t) - test_shake_256(&t) - test_keccak_224(&t) - test_keccak_256(&t) - test_keccak_384(&t) - test_keccak_512(&t) - test_whirlpool(&t) - test_gost(&t) - test_streebog_256(&t) - test_streebog_512(&t) - test_blake_224(&t) - test_blake_256(&t) - test_blake_384(&t) - test_blake_512(&t) - test_blake2b(&t) - test_blake2s(&t) - test_ripemd_128(&t) - test_ripemd_160(&t) - test_ripemd_256(&t) - test_ripemd_320(&t) - test_tiger_128(&t) - test_tiger_160(&t) - test_tiger_192(&t) - test_tiger2_128(&t) - test_tiger2_160(&t) - test_tiger2_192(&t) - test_sm3(&t) - test_jh_224(&t) - test_jh_256(&t) - test_jh_384(&t) - test_jh_512(&t) - test_groestl_224(&t) - test_groestl_256(&t) - test_groestl_384(&t) - test_groestl_512(&t) - test_haval_128(&t) - test_haval_160(&t) - test_haval_192(&t) - test_haval_224(&t) - test_haval_256(&t) + t := testing.T{} + test_md2(&t) + test_md4(&t) + test_md5(&t) + test_sha1(&t) + test_sha224(&t) + test_sha256(&t) + test_sha384(&t) + test_sha512(&t) + test_sha3_224(&t) + test_sha3_256(&t) + test_sha3_384(&t) + test_sha3_512(&t) + test_shake_128(&t) + test_shake_256(&t) + test_keccak_224(&t) + test_keccak_256(&t) + test_keccak_384(&t) + test_keccak_512(&t) + test_whirlpool(&t) + test_gost(&t) + test_streebog_256(&t) + test_streebog_512(&t) + test_blake_224(&t) + test_blake_256(&t) + test_blake_384(&t) + test_blake_512(&t) + test_blake2b(&t) + test_blake2s(&t) + test_ripemd_128(&t) + test_ripemd_160(&t) + test_ripemd_256(&t) + test_ripemd_320(&t) + test_tiger_128(&t) + test_tiger_160(&t) + test_tiger_192(&t) + test_tiger2_128(&t) + test_tiger2_160(&t) + test_tiger2_192(&t) + test_sm3(&t) + test_jh_224(&t) + test_jh_256(&t) + test_jh_384(&t) + test_jh_512(&t) + test_groestl_224(&t) + test_groestl_256(&t) + test_groestl_384(&t) + test_groestl_512(&t) + test_haval_128(&t) + test_haval_160(&t) + test_haval_192(&t) + test_haval_224(&t) + test_haval_256(&t) - // "modern" crypto tests - test_chacha20(&t) - test_poly1305(&t) - test_chacha20poly1305(&t) - test_x25519(&t) - test_rand_bytes(&t) + // "modern" crypto tests + test_chacha20(&t) + test_poly1305(&t) + test_chacha20poly1305(&t) + test_x25519(&t) + test_rand_bytes(&t) - bench_modern(&t) + bench_modern(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } TestHash :: struct { - hash: string, - str: string, + hash: string, + str: string, } hex_string :: proc(bytes: []byte, allocator := context.temp_allocator) -> string { - lut: [16]byte = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} - buf := make([]byte, len(bytes) * 2, allocator) - for i := 0; i < len(bytes); i += 1 { - buf[i * 2 + 0] = lut[bytes[i] >> 4 & 0xf] - buf[i * 2 + 1] = lut[bytes[i] & 0xf] - } - return string(buf) + lut: [16]byte = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} + buf := make([]byte, len(bytes) * 2, allocator) + for i := 0; i < len(bytes); i += 1 { + buf[i * 2 + 0] = lut[bytes[i] >> 4 & 0xf] + buf[i * 2 + 1] = lut[bytes[i] & 0xf] + } + return string(buf) } @(test) test_md2 :: proc(t: ^testing.T) { - // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1319 - test_vectors := [?]TestHash { - TestHash{"8350e5a3e24c153df2275c9f80692773", ""}, - TestHash{"32ec01ec4a6dac72c0ab96fb34c0b5d1", "a"}, - TestHash{"da853b0d3f88d99b30283a69e6ded6bb", "abc"}, - TestHash{"ab4f496bfb2a530b219ff33031fe06b0", "message digest"}, - TestHash{"4e8ddff3650292ab5a4108c3aa47940b", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"da33def2a42df13975352846c30338cd", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"d5976f79d83d3a0dc9806c3c66f3efd8", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := md2.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1319 + test_vectors := [?]TestHash { + TestHash{"8350e5a3e24c153df2275c9f80692773", ""}, + TestHash{"32ec01ec4a6dac72c0ab96fb34c0b5d1", "a"}, + TestHash{"da853b0d3f88d99b30283a69e6ded6bb", "abc"}, + TestHash{"ab4f496bfb2a530b219ff33031fe06b0", "message digest"}, + TestHash{"4e8ddff3650292ab5a4108c3aa47940b", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"da33def2a42df13975352846c30338cd", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"d5976f79d83d3a0dc9806c3c66f3efd8", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := md2.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_md4 :: proc(t: ^testing.T) { - // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1320 - test_vectors := [?]TestHash { - TestHash{"31d6cfe0d16ae931b73c59d7e0c089c0", ""}, - TestHash{"bde52cb31de33e46245e05fbdbd6fb24", "a"}, - TestHash{"a448017aaf21d8525fc10ae87aa6729d", "abc"}, - TestHash{"d9130a8164549fe818874806e1c7014b", "message digest"}, - TestHash{"d79e1c308aa5bbcdeea8ed63df412da9", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"043f8582f241db351ce627e153e7f0e4", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"e33b4ddc9c38f2199c3e7b164fcc0536", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := md4.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1320 + test_vectors := [?]TestHash { + TestHash{"31d6cfe0d16ae931b73c59d7e0c089c0", ""}, + TestHash{"bde52cb31de33e46245e05fbdbd6fb24", "a"}, + TestHash{"a448017aaf21d8525fc10ae87aa6729d", "abc"}, + TestHash{"d9130a8164549fe818874806e1c7014b", "message digest"}, + TestHash{"d79e1c308aa5bbcdeea8ed63df412da9", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"043f8582f241db351ce627e153e7f0e4", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"e33b4ddc9c38f2199c3e7b164fcc0536", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := md4.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_md5 :: proc(t: ^testing.T) { - // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1321 - test_vectors := [?]TestHash { - TestHash{"d41d8cd98f00b204e9800998ecf8427e", ""}, - TestHash{"0cc175b9c0f1b6a831c399e269772661", "a"}, - TestHash{"900150983cd24fb0d6963f7d28e17f72", "abc"}, - TestHash{"f96b697d7cb7938d525a2f31aaf161d0", "message digest"}, - TestHash{"c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"d174ab98d277d9f5a5611c2c9f419d9f", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := md5.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Official test vectors from https://datatracker.ietf.org/doc/html/rfc1321 + test_vectors := [?]TestHash { + TestHash{"d41d8cd98f00b204e9800998ecf8427e", ""}, + TestHash{"0cc175b9c0f1b6a831c399e269772661", "a"}, + TestHash{"900150983cd24fb0d6963f7d28e17f72", "abc"}, + TestHash{"f96b697d7cb7938d525a2f31aaf161d0", "message digest"}, + TestHash{"c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"d174ab98d277d9f5a5611c2c9f419d9f", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := md5.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha1 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"da39a3ee5e6b4b0d3255bfef95601890afd80709", ""}, - TestHash{"a9993e364706816aba3e25717850c26c9cd0d89d", "abc"}, - TestHash{"f9537c23893d2014f365adf8ffe33b8eb0297ed1", "abcdbcdecdefdefgefghfghighijhi"}, - TestHash{"346fb528a24b48f563cb061470bcfd23740427ad", "jkijkljklmklmnlmnomnopnopq"}, - TestHash{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a"}, - TestHash{"c729c8996ee0a6f74f4f3248e8957edf704fb624", "01234567012345670123456701234567"}, - TestHash{"84983e441c3bd26ebaae4aa1f95129e5e54670f1", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha1.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"da39a3ee5e6b4b0d3255bfef95601890afd80709", ""}, + TestHash{"a9993e364706816aba3e25717850c26c9cd0d89d", "abc"}, + TestHash{"f9537c23893d2014f365adf8ffe33b8eb0297ed1", "abcdbcdecdefdefgefghfghighijhi"}, + TestHash{"346fb528a24b48f563cb061470bcfd23740427ad", "jkijkljklmklmnlmnomnopnopq"}, + TestHash{"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "a"}, + TestHash{"c729c8996ee0a6f74f4f3248e8957edf704fb624", "01234567012345670123456701234567"}, + TestHash{"84983e441c3bd26ebaae4aa1f95129e5e54670f1", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha1.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha224 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""}, - TestHash{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"}, - TestHash{"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha2.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""}, + TestHash{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"}, + TestHash{"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha2.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha256 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""}, - TestHash{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc"}, - TestHash{"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha2.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""}, + TestHash{"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", "abc"}, + TestHash{"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha2.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha384 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", ""}, - TestHash{"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "abc"}, - TestHash{"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha2.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", ""}, + TestHash{"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", "abc"}, + TestHash{"3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha2.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha512 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", ""}, - TestHash{"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "abc"}, - TestHash{"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha2.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", ""}, + TestHash{"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", "abc"}, + TestHash{"204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha2.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha3_224 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", ""}, - TestHash{"e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc"}, - TestHash{"10241ac5187380bd501192e4e56b5280908727dd8fe0d10d4e5ad91e", "abcdbcdecdefdefgefghfghighijhi"}, - TestHash{"fd645fe07d814c397e85e85f92fe58b949f55efa4d3468b2468da45a", "jkijkljklmklmnlmnomnopnopq"}, - TestHash{"9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b", "a"}, - TestHash{"6961f694b2ff3ed6f0c830d2c66da0c5e7ca9445f7c0dca679171112", "01234567012345670123456701234567"}, - TestHash{"8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"543e6868e1666c1a643630df77367ae5a62a85070a51c14cbf665cbc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha3.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", ""}, + TestHash{"e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc"}, + TestHash{"10241ac5187380bd501192e4e56b5280908727dd8fe0d10d4e5ad91e", "abcdbcdecdefdefgefghfghighijhi"}, + TestHash{"fd645fe07d814c397e85e85f92fe58b949f55efa4d3468b2468da45a", "jkijkljklmklmnlmnomnopnopq"}, + TestHash{"9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b", "a"}, + TestHash{"6961f694b2ff3ed6f0c830d2c66da0c5e7ca9445f7c0dca679171112", "01234567012345670123456701234567"}, + TestHash{"8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"543e6868e1666c1a643630df77367ae5a62a85070a51c14cbf665cbc", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha3.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha3_256 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", ""}, - TestHash{"3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc"}, - TestHash{"565ada1ced21278cfaffdde00dea0107964121ac25e4e978abc59412be74550a", "abcdbcdecdefdefgefghfghighijhi"}, - TestHash{"8cc1709d520f495ce972ece48b0d2e1f74ec80d53bc5c47457142158fae15d98", "jkijkljklmklmnlmnomnopnopq"}, - TestHash{"80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b", "a"}, - TestHash{"e4786de5f88f7d374b7288f225ea9f2f7654da200bab5d417e1fb52d49202767", "01234567012345670123456701234567"}, - TestHash{"41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha3.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", ""}, + TestHash{"3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc"}, + TestHash{"565ada1ced21278cfaffdde00dea0107964121ac25e4e978abc59412be74550a", "abcdbcdecdefdefgefghfghighijhi"}, + TestHash{"8cc1709d520f495ce972ece48b0d2e1f74ec80d53bc5c47457142158fae15d98", "jkijkljklmklmnlmnomnopnopq"}, + TestHash{"80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b", "a"}, + TestHash{"e4786de5f88f7d374b7288f225ea9f2f7654da200bab5d417e1fb52d49202767", "01234567012345670123456701234567"}, + TestHash{"41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha3.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha3_384 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", ""}, - TestHash{"ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25", "abc"}, - TestHash{"9aa92dbb716ebb573def0d5e3cdd28d6add38ada310b602b8916e690a3257b7144e5ddd3d0dbbc559c48480d34d57a9a", "abcdbcdecdefdefgefghfghighijhi"}, - TestHash{"77c90323d7392bcdee8a3e7f74f19f47b7d1b1a825ac6a2d8d882a72317879cc26597035f1fc24fe65090b125a691282", "jkijkljklmklmnlmnomnopnopq"}, - TestHash{"1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9", "a"}, - TestHash{"51072590ad4c51b27ff8265590d74f92de7cc55284168e414ca960087c693285b08a283c6b19d77632994cb9eb93f1be", "01234567012345670123456701234567"}, - TestHash{"991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha3.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", ""}, + TestHash{"ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25", "abc"}, + TestHash{"9aa92dbb716ebb573def0d5e3cdd28d6add38ada310b602b8916e690a3257b7144e5ddd3d0dbbc559c48480d34d57a9a", "abcdbcdecdefdefgefghfghighijhi"}, + TestHash{"77c90323d7392bcdee8a3e7f74f19f47b7d1b1a825ac6a2d8d882a72317879cc26597035f1fc24fe65090b125a691282", "jkijkljklmklmnlmnomnopnopq"}, + TestHash{"1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9", "a"}, + TestHash{"51072590ad4c51b27ff8265590d74f92de7cc55284168e414ca960087c693285b08a283c6b19d77632994cb9eb93f1be", "01234567012345670123456701234567"}, + TestHash{"991c665755eb3a4b6bbdfb75c78a492e8c56a22c5c4d7e429bfdbc32b9d4ad5aa04a1f076e62fea19eef51acd0657c22", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha3.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sha3_512 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", ""}, - TestHash{"b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", "abc"}, - TestHash{"9f9a327944a35988d67effc4fa748b3c07744f736ac70b479d8e12a3d10d6884d00a7ef593690305462e9e9030a67c51636fd346fd8fa0ee28a5ac2aee103d2e", "abcdbcdecdefdefgefghfghighijhi"}, - TestHash{"dbb124a0deda966eb4d199d0844fa0beb0770ea1ccddabcd335a7939a931ac6fb4fa6aebc6573f462ced2e4e7178277803be0d24d8bc2864626d9603109b7891", "jkijkljklmklmnlmnomnopnopq"}, - TestHash{"697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a", "a"}, - TestHash{"5679e353bc8eeea3e801ca60448b249bcfd3ac4a6c3abe429a807bcbd4c9cd12da87a5a9dc74fde64c0d44718632cae966b078397c6f9ec155c6a238f2347cf1", "01234567012345670123456701234567"}, - TestHash{"04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, - } - for v, _ in test_vectors { - computed := sha3.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", ""}, + TestHash{"b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0", "abc"}, + TestHash{"9f9a327944a35988d67effc4fa748b3c07744f736ac70b479d8e12a3d10d6884d00a7ef593690305462e9e9030a67c51636fd346fd8fa0ee28a5ac2aee103d2e", "abcdbcdecdefdefgefghfghighijhi"}, + TestHash{"dbb124a0deda966eb4d199d0844fa0beb0770ea1ccddabcd335a7939a931ac6fb4fa6aebc6573f462ced2e4e7178277803be0d24d8bc2864626d9603109b7891", "jkijkljklmklmnlmnomnopnopq"}, + TestHash{"697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a", "a"}, + TestHash{"5679e353bc8eeea3e801ca60448b249bcfd3ac4a6c3abe429a807bcbd4c9cd12da87a5a9dc74fde64c0d44718632cae966b078397c6f9ec155c6a238f2347cf1", "01234567012345670123456701234567"}, + TestHash{"04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + } + for v, _ in test_vectors { + computed := sha3.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_shake_128 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"7f9c2ba4e88f827d616045507605853e", ""}, - TestHash{"f4202e3c5852f9182a0430fd8144f0a7", "The quick brown fox jumps over the lazy dog"}, - TestHash{"853f4538be0db9621a6cea659a06c110", "The quick brown fox jumps over the lazy dof"}, - } - for v, _ in test_vectors { - computed := shake.hash_128(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"7f9c2ba4e88f827d616045507605853e", ""}, + TestHash{"f4202e3c5852f9182a0430fd8144f0a7", "The quick brown fox jumps over the lazy dog"}, + TestHash{"853f4538be0db9621a6cea659a06c110", "The quick brown fox jumps over the lazy dof"}, + } + for v, _ in test_vectors { + computed := shake.hash_128(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_shake_256 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f", ""}, - TestHash{"2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca", "The quick brown fox jumps over the lazy dog"}, - TestHash{"46b1ebb2e142c38b9ac9081bef72877fe4723959640fa57119b366ce6899d401", "The quick brown fox jumps over the lazy dof"}, - } - for v, _ in test_vectors { - computed := shake.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f", ""}, + TestHash{"2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca", "The quick brown fox jumps over the lazy dog"}, + TestHash{"46b1ebb2e142c38b9ac9081bef72877fe4723959640fa57119b366ce6899d401", "The quick brown fox jumps over the lazy dof"}, + } + for v, _ in test_vectors { + computed := shake.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_keccak_224 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", ""}, - TestHash{"c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8", "abc"}, - } - for v, _ in test_vectors { - computed := keccak.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", ""}, + TestHash{"c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8", "abc"}, + } + for v, _ in test_vectors { + computed := keccak.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_keccak_256 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", ""}, - TestHash{"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", "abc"}, - } - for v, _ in test_vectors { - computed := keccak.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", ""}, + TestHash{"4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45", "abc"}, + } + for v, _ in test_vectors { + computed := keccak.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_keccak_384 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", ""}, - TestHash{"f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e", "abc"}, - } - for v, _ in test_vectors { - computed := keccak.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", ""}, + TestHash{"f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e", "abc"}, + } + for v, _ in test_vectors { + computed := keccak.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_keccak_512 :: proc(t: ^testing.T) { - // Test vectors from - // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf - // https://www.di-mgt.com.au/sha_testvectors.html - test_vectors := [?]TestHash { - TestHash{"0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", ""}, - TestHash{"18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96", "abc"}, - } - for v, _ in test_vectors { - computed := keccak.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf + // https://www.di-mgt.com.au/sha_testvectors.html + test_vectors := [?]TestHash { + TestHash{"0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", ""}, + TestHash{"18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96", "abc"}, + } + for v, _ in test_vectors { + computed := keccak.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_whirlpool :: proc(t: ^testing.T) { - // Test vectors from - // https://web.archive.org/web/20171129084214/http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html - test_vectors := [?]TestHash { - TestHash{"19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", ""}, - TestHash{"8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a", "a"}, - TestHash{"33e24e6cbebf168016942df8a7174048f9cebc45cbd829c3b94b401a498acb11c5abcca7f2a1238aaf534371e87a4e4b19758965d5a35a7cad87cf5517043d97", "ab"}, - TestHash{"4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5", "abc"}, - TestHash{"bda164f0b930c43a1bacb5df880b205d15ac847add35145bf25d991ae74f0b72b1ac794f8aacda5fcb3c47038c954742b1857b5856519de4d1e54bfa2fa4eac5", "abcd"}, - TestHash{"5d745e26ccb20fe655d39c9e7f69455758fbae541cb892b3581e4869244ab35b4fd6078f5d28b1f1a217452a67d9801033d92724a221255a5e377fe9e9e5f0b2", "abcde"}, - TestHash{"a73e425459567308ba5f9eb2ae23570d0d0575eb1357ecf6ac88d4e0358b0ac3ea2371261f5d4c070211784b525911b9eec0ad968429bb7c7891d341cff4e811", "abcdef"}, - TestHash{"08b388f68fd3eb51906ac3d3c699b8e9c3ac65d7ceb49d2e34f8a482cbc3082bc401cead90e85a97b8647c948bf35e448740b79659f3bee42145f0bd653d1f25", "abcdefg"}, - TestHash{"1f1a84d30612820243afe2022712f9dac6d07c4c8bb41b40eacab0184c8d82275da5bcadbb35c7ca1960ff21c90acbae8c14e48d9309e4819027900e882c7ad9", "abcdefgh"}, - TestHash{"11882bc9a31ac1cf1c41dcd9fd6fdd3ccdb9b017fc7f4582680134f314d7bb49af4c71f5a920bc0a6a3c1ff9a00021bf361d9867fe636b0bc1da1552e4237de4", "abcdefghi"}, - TestHash{"717163de24809ffcf7ff6d5aba72b8d67c2129721953c252a4ddfb107614be857cbd76a9d5927de14633d6bdc9ddf335160b919db5c6f12cb2e6549181912eef", "abcdefghij"}, - TestHash{"b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35", "The quick brown fox jumps over the lazy dog"}, - TestHash{"c27ba124205f72e6847f3e19834f925cc666d0974167af915bb462420ed40cc50900d85a1f923219d832357750492d5c143011a76988344c2635e69d06f2d38c", "The quick brown fox jumps over the lazy eog"}, - } - for v, _ in test_vectors { - computed := whirlpool.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://web.archive.org/web/20171129084214/http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html + test_vectors := [?]TestHash { + TestHash{"19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", ""}, + TestHash{"8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a", "a"}, + TestHash{"33e24e6cbebf168016942df8a7174048f9cebc45cbd829c3b94b401a498acb11c5abcca7f2a1238aaf534371e87a4e4b19758965d5a35a7cad87cf5517043d97", "ab"}, + TestHash{"4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5", "abc"}, + TestHash{"bda164f0b930c43a1bacb5df880b205d15ac847add35145bf25d991ae74f0b72b1ac794f8aacda5fcb3c47038c954742b1857b5856519de4d1e54bfa2fa4eac5", "abcd"}, + TestHash{"5d745e26ccb20fe655d39c9e7f69455758fbae541cb892b3581e4869244ab35b4fd6078f5d28b1f1a217452a67d9801033d92724a221255a5e377fe9e9e5f0b2", "abcde"}, + TestHash{"a73e425459567308ba5f9eb2ae23570d0d0575eb1357ecf6ac88d4e0358b0ac3ea2371261f5d4c070211784b525911b9eec0ad968429bb7c7891d341cff4e811", "abcdef"}, + TestHash{"08b388f68fd3eb51906ac3d3c699b8e9c3ac65d7ceb49d2e34f8a482cbc3082bc401cead90e85a97b8647c948bf35e448740b79659f3bee42145f0bd653d1f25", "abcdefg"}, + TestHash{"1f1a84d30612820243afe2022712f9dac6d07c4c8bb41b40eacab0184c8d82275da5bcadbb35c7ca1960ff21c90acbae8c14e48d9309e4819027900e882c7ad9", "abcdefgh"}, + TestHash{"11882bc9a31ac1cf1c41dcd9fd6fdd3ccdb9b017fc7f4582680134f314d7bb49af4c71f5a920bc0a6a3c1ff9a00021bf361d9867fe636b0bc1da1552e4237de4", "abcdefghi"}, + TestHash{"717163de24809ffcf7ff6d5aba72b8d67c2129721953c252a4ddfb107614be857cbd76a9d5927de14633d6bdc9ddf335160b919db5c6f12cb2e6549181912eef", "abcdefghij"}, + TestHash{"b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35", "The quick brown fox jumps over the lazy dog"}, + TestHash{"c27ba124205f72e6847f3e19834f925cc666d0974167af915bb462420ed40cc50900d85a1f923219d832357750492d5c143011a76988344c2635e69d06f2d38c", "The quick brown fox jumps over the lazy eog"}, + } + for v, _ in test_vectors { + computed := whirlpool.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_gost :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", ""}, - TestHash{"e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", "a"}, - TestHash{"b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c", "abc"}, - TestHash{"bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0", "message digest"}, - TestHash{"9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76", "The quick brown fox jumps over the lazy dog"}, - TestHash{"73b70a39497de53a6e08c67b6d4db853540f03e9389299d9b0156ef7e85d0f61", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"6bc7b38989b28cf93ae8842bf9d752905910a7528a61e5bce0782de43e610c90", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - TestHash{"2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", "This is message, length=32 bytes"}, - TestHash{"c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", "Suppose the original message has length = 50 bytes"}, - } - for v, _ in test_vectors { - computed := gost.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", ""}, + TestHash{"e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", "a"}, + TestHash{"b285056dbf18d7392d7677369524dd14747459ed8143997e163b2986f92fd42c", "abc"}, + TestHash{"bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0", "message digest"}, + TestHash{"9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76", "The quick brown fox jumps over the lazy dog"}, + TestHash{"73b70a39497de53a6e08c67b6d4db853540f03e9389299d9b0156ef7e85d0f61", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"6bc7b38989b28cf93ae8842bf9d752905910a7528a61e5bce0782de43e610c90", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + TestHash{"2cefc2f7b7bdc514e18ea57fa74ff357e7fa17d652c75f69cb1be7893ede48eb", "This is message, length=32 bytes"}, + TestHash{"c3730c5cbccacf915ac292676f21e8bd4ef75331d9405e5f1a61dc3130a65011", "Suppose the original message has length = 50 bytes"}, + } + for v, _ in test_vectors { + computed := gost.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_streebog_256 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb", ""}, - TestHash{"3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4", "The quick brown fox jumps over the lazy dog"}, - TestHash{"36816a824dcbe7d6171aa58500741f2ea2757ae2e1784ab72c5c3c6c198d71da", "The quick brown fox jumps over the lazy dog."}, - } - for v, _ in test_vectors { - computed := streebog.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb", ""}, + TestHash{"3e7dea7f2384b6c5a3d0e24aaa29c05e89ddd762145030ec22c71a6db8b2c1f4", "The quick brown fox jumps over the lazy dog"}, + TestHash{"36816a824dcbe7d6171aa58500741f2ea2757ae2e1784ab72c5c3c6c198d71da", "The quick brown fox jumps over the lazy dog."}, + } + for v, _ in test_vectors { + computed := streebog.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_streebog_512 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a", ""}, - TestHash{"d2b793a0bb6cb5904828b5b6dcfb443bb8f33efc06ad09368878ae4cdc8245b97e60802469bed1e7c21a64ff0b179a6a1e0bb74d92965450a0adab69162c00fe", "The quick brown fox jumps over the lazy dog"}, - TestHash{"fe0c42f267d921f940faa72bd9fcf84f9f1bd7e9d055e9816e4c2ace1ec83be82d2957cd59b86e123d8f5adee80b3ca08a017599a9fc1a14d940cf87c77df070", "The quick brown fox jumps over the lazy dog."}, - } - for v, _ in test_vectors { - computed := streebog.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a", ""}, + TestHash{"d2b793a0bb6cb5904828b5b6dcfb443bb8f33efc06ad09368878ae4cdc8245b97e60802469bed1e7c21a64ff0b179a6a1e0bb74d92965450a0adab69162c00fe", "The quick brown fox jumps over the lazy dog"}, + TestHash{"fe0c42f267d921f940faa72bd9fcf84f9f1bd7e9d055e9816e4c2ace1ec83be82d2957cd59b86e123d8f5adee80b3ca08a017599a9fc1a14d940cf87c77df070", "The quick brown fox jumps over the lazy dog."}, + } + for v, _ in test_vectors { + computed := streebog.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake_224 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"7dc5313b1c04512a174bd6503b89607aecbee0903d40a8a569c94eed", ""}, - TestHash{"304c27fdbf308aea06955e331adc6814223a21fccd24c09fde9eda7b", "ube"}, - TestHash{"cfb6848add73e1cb47994c4765df33b8f973702705a30a71fe4747a3", "BLAKE"}, - } - for v, _ in test_vectors { - computed := blake.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"7dc5313b1c04512a174bd6503b89607aecbee0903d40a8a569c94eed", ""}, + TestHash{"304c27fdbf308aea06955e331adc6814223a21fccd24c09fde9eda7b", "ube"}, + TestHash{"cfb6848add73e1cb47994c4765df33b8f973702705a30a71fe4747a3", "BLAKE"}, + } + for v, _ in test_vectors { + computed := blake.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake_256 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a", ""}, - TestHash{"e802fe2a73fbe5853408f051d040aeb3a76a4d7a0fc5c3415d1af090f76a2c81", "ube"}, - TestHash{"07663e00cf96fbc136cf7b1ee099c95346ba3920893d18cc8851f22ee2e36aa6", "BLAKE"}, - } - for v, _ in test_vectors { - computed := blake.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a", ""}, + TestHash{"e802fe2a73fbe5853408f051d040aeb3a76a4d7a0fc5c3415d1af090f76a2c81", "ube"}, + TestHash{"07663e00cf96fbc136cf7b1ee099c95346ba3920893d18cc8851f22ee2e36aa6", "BLAKE"}, + } + for v, _ in test_vectors { + computed := blake.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake_384 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"c6cbd89c926ab525c242e6621f2f5fa73aa4afe3d9e24aed727faaadd6af38b620bdb623dd2b4788b1c8086984af8706", ""}, - TestHash{"8f22f120b2b99dd4fd32b98c8c83bd87abd6413f7317be936b1997511247fc68ae781c6f42113224ccbc1567b0e88593", "ube"}, - TestHash{"f28742f7243990875d07e6afcff962edabdf7e9d19ddea6eae31d094c7fa6d9b00c8213a02ddf1e2d9894f3162345d85", "BLAKE"}, - } - for v, _ in test_vectors { - computed := blake.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"c6cbd89c926ab525c242e6621f2f5fa73aa4afe3d9e24aed727faaadd6af38b620bdb623dd2b4788b1c8086984af8706", ""}, + TestHash{"8f22f120b2b99dd4fd32b98c8c83bd87abd6413f7317be936b1997511247fc68ae781c6f42113224ccbc1567b0e88593", "ube"}, + TestHash{"f28742f7243990875d07e6afcff962edabdf7e9d19ddea6eae31d094c7fa6d9b00c8213a02ddf1e2d9894f3162345d85", "BLAKE"}, + } + for v, _ in test_vectors { + computed := blake.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake_512 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"a8cfbbd73726062df0c6864dda65defe58ef0cc52a5625090fa17601e1eecd1b628e94f396ae402a00acc9eab77b4d4c2e852aaaa25a636d80af3fc7913ef5b8", ""}, - TestHash{"49a24ca8f230936f938c19484d46b58f13ea4448ddadafecdf01419b1e1dd922680be2de84069187973ab61b10574da2ee50cbeaade68ea9391c8ec041b76be0", "ube"}, - TestHash{"7bf805d0d8de36802b882e65d0515aa7682a2be97a9d9ec1399f4be2eff7de07684d7099124c8ac81c1c7c200d24ba68c6222e75062e04feb0e9dd589aa6e3b7", "BLAKE"}, - } - for v, _ in test_vectors { - computed := blake.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"a8cfbbd73726062df0c6864dda65defe58ef0cc52a5625090fa17601e1eecd1b628e94f396ae402a00acc9eab77b4d4c2e852aaaa25a636d80af3fc7913ef5b8", ""}, + TestHash{"49a24ca8f230936f938c19484d46b58f13ea4448ddadafecdf01419b1e1dd922680be2de84069187973ab61b10574da2ee50cbeaade68ea9391c8ec041b76be0", "ube"}, + TestHash{"7bf805d0d8de36802b882e65d0515aa7682a2be97a9d9ec1399f4be2eff7de07684d7099124c8ac81c1c7c200d24ba68c6222e75062e04feb0e9dd589aa6e3b7", "BLAKE"}, + } + for v, _ in test_vectors { + computed := blake.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake2b :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", ""}, - TestHash{"a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "The quick brown fox jumps over the lazy dog"}, - } - for v, _ in test_vectors { - computed := blake2b.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", ""}, + TestHash{"a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "The quick brown fox jumps over the lazy dog"}, + } + for v, _ in test_vectors { + computed := blake2b.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_blake2s :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", ""}, - TestHash{"606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "The quick brown fox jumps over the lazy dog"}, - } - for v, _ in test_vectors { - computed := blake2s.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", ""}, + TestHash{"606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "The quick brown fox jumps over the lazy dog"}, + } + for v, _ in test_vectors { + computed := blake2s.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_ripemd_128 :: proc(t: ^testing.T) { - // Test vectors from - // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html - test_vectors := [?]TestHash { - TestHash{"cdf26213a150dc3ecb610f18f6b38b46", ""}, - TestHash{"86be7afa339d0fc7cfc785e72f578d33", "a"}, - TestHash{"c14a12199c66e4ba84636b0f69144c77", "abc"}, - TestHash{"9e327b3d6e523062afc1132d7df9d1b8", "message digest"}, - TestHash{"fd2aa607f71dc8f510714922b371834e", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"a1aa0689d0fafa2ddc22e88b49133a06", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"d1e959eb179c911faea4624c60c5c702", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors { - computed := ripemd.hash_128(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + test_vectors := [?]TestHash { + TestHash{"cdf26213a150dc3ecb610f18f6b38b46", ""}, + TestHash{"86be7afa339d0fc7cfc785e72f578d33", "a"}, + TestHash{"c14a12199c66e4ba84636b0f69144c77", "abc"}, + TestHash{"9e327b3d6e523062afc1132d7df9d1b8", "message digest"}, + TestHash{"fd2aa607f71dc8f510714922b371834e", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"a1aa0689d0fafa2ddc22e88b49133a06", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"d1e959eb179c911faea4624c60c5c702", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors { + computed := ripemd.hash_128(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_ripemd_160 :: proc(t: ^testing.T) { - // Test vectors from - // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html - test_vectors := [?]TestHash { - TestHash{"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, - TestHash{"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, - TestHash{"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, - TestHash{"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, - TestHash{"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors { - computed := ripemd.hash_160(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + test_vectors := [?]TestHash { + TestHash{"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, + TestHash{"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, + TestHash{"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, + TestHash{"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, + TestHash{"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors { + computed := ripemd.hash_160(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_ripemd_256 :: proc(t: ^testing.T) { - // Test vectors from - // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html - test_vectors := [?]TestHash { - TestHash{"02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", ""}, - TestHash{"f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925", "a"}, - TestHash{"afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65", "abc"}, - TestHash{"87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", "message digest"}, - TestHash{"649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors { - computed := ripemd.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + test_vectors := [?]TestHash { + TestHash{"02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", ""}, + TestHash{"f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925", "a"}, + TestHash{"afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65", "abc"}, + TestHash{"87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", "message digest"}, + TestHash{"649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors { + computed := ripemd.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_ripemd_320 :: proc(t: ^testing.T) { - // Test vectors from - // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html - test_vectors := [?]TestHash { - TestHash{"22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", ""}, - TestHash{"ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d", "a"}, - TestHash{"de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d", "abc"}, - TestHash{"3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197", "message digest"}, - TestHash{"cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors { - computed := ripemd.hash_320(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + // Test vectors from + // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html + test_vectors := [?]TestHash { + TestHash{"22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", ""}, + TestHash{"ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d", "a"}, + TestHash{"de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d", "abc"}, + TestHash{"3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197", "message digest"}, + TestHash{"cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors { + computed := ripemd.hash_320(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger_128 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"3293ac630c13f0245f92bbb1766e1616", ""}, - TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc", "a"}, - TestHash{"2aab1484e8c158f2bfb8c5ff41b57a52", "abc"}, - TestHash{"d981f8cb78201a950dcf3048751e441c", "message digest"}, - TestHash{"1714a472eee57d30040412bfcc55032a", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"8dcea680a17583ee502ba38a3c368651", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"1c14795529fd9f207a958f84c52f11e8", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - TestHash{"6d12a41e72e644f017b6f0e2f7b44c62", "The quick brown fox jumps over the lazy dog"}, - } - for v, _ in test_vectors { - computed := tiger.hash_128(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"3293ac630c13f0245f92bbb1766e1616", ""}, + TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc", "a"}, + TestHash{"2aab1484e8c158f2bfb8c5ff41b57a52", "abc"}, + TestHash{"d981f8cb78201a950dcf3048751e441c", "message digest"}, + TestHash{"1714a472eee57d30040412bfcc55032a", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"8dcea680a17583ee502ba38a3c368651", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"1c14795529fd9f207a958f84c52f11e8", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + TestHash{"6d12a41e72e644f017b6f0e2f7b44c62", "The quick brown fox jumps over the lazy dog"}, + } + for v, _ in test_vectors { + computed := tiger.hash_128(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger_160 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"3293ac630c13f0245f92bbb1766e16167a4e5849", ""}, - TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc613e247f", "a"}, - TestHash{"2aab1484e8c158f2bfb8c5ff41b57a525129131c", "abc"}, - TestHash{"d981f8cb78201a950dcf3048751e441c517fca1a", "message digest"}, - TestHash{"1714a472eee57d30040412bfcc55032a0b11602f", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3a71c631e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"8dcea680a17583ee502ba38a3c368651890ffbcc", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"1c14795529fd9f207a958f84c52f11e887fa0cab", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - TestHash{"6d12a41e72e644f017b6f0e2f7b44c6285f06dd5", "The quick brown fox jumps over the lazy dog"}, - } - for v, _ in test_vectors { - computed := tiger.hash_160(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"3293ac630c13f0245f92bbb1766e16167a4e5849", ""}, + TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc613e247f", "a"}, + TestHash{"2aab1484e8c158f2bfb8c5ff41b57a525129131c", "abc"}, + TestHash{"d981f8cb78201a950dcf3048751e441c517fca1a", "message digest"}, + TestHash{"1714a472eee57d30040412bfcc55032a0b11602f", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3a71c631e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"8dcea680a17583ee502ba38a3c368651890ffbcc", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"1c14795529fd9f207a958f84c52f11e887fa0cab", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + TestHash{"6d12a41e72e644f017b6f0e2f7b44c6285f06dd5", "The quick brown fox jumps over the lazy dog"}, + } + for v, _ in test_vectors { + computed := tiger.hash_160(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger_192 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", ""}, - TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809", "a"}, - TestHash{"2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93", "abc"}, - TestHash{"d981f8cb78201a950dcf3048751e441c517fca1aa55a29f6", "message digest"}, - TestHash{"1714a472eee57d30040412bfcc55032a0b11602ff37beee9", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3a71c631e7b53f78e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"8dcea680a17583ee502ba38a3c368651890ffbccdc49a8cc", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - TestHash{"1c14795529fd9f207a958f84c52f11e887fa0cabdfd91bfd", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - TestHash{"6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "The quick brown fox jumps over the lazy dog"}, - } - for v, _ in test_vectors { - computed := tiger.hash_192(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", ""}, + TestHash{"77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809", "a"}, + TestHash{"2aab1484e8c158f2bfb8c5ff41b57a525129131c957b5f93", "abc"}, + TestHash{"d981f8cb78201a950dcf3048751e441c517fca1aa55a29f6", "message digest"}, + TestHash{"1714a472eee57d30040412bfcc55032a0b11602ff37beee9", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"0f7bf9a19b9c58f2b7610df7e84f0ac3a71c631e7b53f78e", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"8dcea680a17583ee502ba38a3c368651890ffbccdc49a8cc", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"1c14795529fd9f207a958f84c52f11e887fa0cabdfd91bfd", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + TestHash{"6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "The quick brown fox jumps over the lazy dog"}, + } + for v, _ in test_vectors { + computed := tiger.hash_192(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger2_128 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"4441be75f6018773c206c22745374b92", ""}, - TestHash{"976abff8062a2e9dcea3a1ace966ed9c", "The quick brown fox jumps over the lazy dog"}, - TestHash{"09c11330283a27efb51930aa7dc1ec62", "The quick brown fox jumps over the lazy cog"}, - } - for v, _ in test_vectors { - computed := tiger2.hash_128(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"4441be75f6018773c206c22745374b92", ""}, + TestHash{"976abff8062a2e9dcea3a1ace966ed9c", "The quick brown fox jumps over the lazy dog"}, + TestHash{"09c11330283a27efb51930aa7dc1ec62", "The quick brown fox jumps over the lazy cog"}, + } + for v, _ in test_vectors { + computed := tiger2.hash_128(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger2_160 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"4441be75f6018773c206c22745374b924aa8313f", ""}, - TestHash{"976abff8062a2e9dcea3a1ace966ed9c19cb8555", "The quick brown fox jumps over the lazy dog"}, - TestHash{"09c11330283a27efb51930aa7dc1ec624ff738a8", "The quick brown fox jumps over the lazy cog"}, - } - for v, _ in test_vectors { - computed := tiger2.hash_160(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"4441be75f6018773c206c22745374b924aa8313f", ""}, + TestHash{"976abff8062a2e9dcea3a1ace966ed9c19cb8555", "The quick brown fox jumps over the lazy dog"}, + TestHash{"09c11330283a27efb51930aa7dc1ec624ff738a8", "The quick brown fox jumps over the lazy cog"}, + } + for v, _ in test_vectors { + computed := tiger2.hash_160(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_tiger2_192 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"4441be75f6018773c206c22745374b924aa8313fef919f41", ""}, - TestHash{"976abff8062a2e9dcea3a1ace966ed9c19cb85558b4976d8", "The quick brown fox jumps over the lazy dog"}, - TestHash{"09c11330283a27efb51930aa7dc1ec624ff738a8d9bdd3df", "The quick brown fox jumps over the lazy cog"}, - } - for v, _ in test_vectors { - computed := tiger2.hash_192(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"4441be75f6018773c206c22745374b924aa8313fef919f41", ""}, + TestHash{"976abff8062a2e9dcea3a1ace966ed9c19cb85558b4976d8", "The quick brown fox jumps over the lazy dog"}, + TestHash{"09c11330283a27efb51930aa7dc1ec624ff738a8d9bdd3df", "The quick brown fox jumps over the lazy cog"}, + } + for v, _ in test_vectors { + computed := tiger2.hash_192(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_sm3 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", ""}, - TestHash{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc"}, - TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"}, - TestHash{"5fdfe814b8573ca021983970fc79b2218c9570369b4859684e2e4c3fc76cb8ea", "The quick brown fox jumps over the lazy dog"}, - TestHash{"ca27d14a42fc04c1e5ecf574a95a8c2d70ecb5805e9b429026ccac8f28b20098", "The quick brown fox jumps over the lazy cog"}, - } - for v, _ in test_vectors { - computed := sm3.hash(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", ""}, + TestHash{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc"}, + TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"}, + TestHash{"5fdfe814b8573ca021983970fc79b2218c9570369b4859684e2e4c3fc76cb8ea", "The quick brown fox jumps over the lazy dog"}, + TestHash{"ca27d14a42fc04c1e5ecf574a95a8c2d70ecb5805e9b429026ccac8f28b20098", "The quick brown fox jumps over the lazy cog"}, + } + for v, _ in test_vectors { + computed := sm3.hash(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_jh_224 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"2c99df889b019309051c60fecc2bd285a774940e43175b76b2626630", ""}, - TestHash{"e715f969fb61b203a97e494aab92d91a9cec52f0933436b0d63bf722", "a"}, - TestHash{"c2b1967e635bd55b6a4d36f863ac4a877be302251d68692873007281", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := jh.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"2c99df889b019309051c60fecc2bd285a774940e43175b76b2626630", ""}, + TestHash{"e715f969fb61b203a97e494aab92d91a9cec52f0933436b0d63bf722", "a"}, + TestHash{"c2b1967e635bd55b6a4d36f863ac4a877be302251d68692873007281", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := jh.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_jh_256 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"46e64619c18bb0a92a5e87185a47eef83ca747b8fcc8e1412921357e326df434", ""}, - TestHash{"d52c0c130a1bc0ae5136375637a52773e150c71efe1c968df8956f6745b05386", "a"}, - TestHash{"fc4214867025a8af94c614353b3553b10e561ae749fc18c40e5fd44a7a4ecd1b", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := jh.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"46e64619c18bb0a92a5e87185a47eef83ca747b8fcc8e1412921357e326df434", ""}, + TestHash{"d52c0c130a1bc0ae5136375637a52773e150c71efe1c968df8956f6745b05386", "a"}, + TestHash{"fc4214867025a8af94c614353b3553b10e561ae749fc18c40e5fd44a7a4ecd1b", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := jh.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_jh_384 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"2fe5f71b1b3290d3c017fb3c1a4d02a5cbeb03a0476481e25082434a881994b0ff99e078d2c16b105ad069b569315328", ""}, - TestHash{"77de897ca4fd5dadfbcbd1d8d4ea3c3c1426855e38661325853e92b069f3fe156729f6bbb9a5892c7c18a77f1cb9d0bb", "a"}, - TestHash{"6f73d9b9b8ed362f8180fb26020725b40bd6ca75b3b947405f26c4c37a885ce028876dc42e379d2faf6146fed3ea0e42", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := jh.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"2fe5f71b1b3290d3c017fb3c1a4d02a5cbeb03a0476481e25082434a881994b0ff99e078d2c16b105ad069b569315328", ""}, + TestHash{"77de897ca4fd5dadfbcbd1d8d4ea3c3c1426855e38661325853e92b069f3fe156729f6bbb9a5892c7c18a77f1cb9d0bb", "a"}, + TestHash{"6f73d9b9b8ed362f8180fb26020725b40bd6ca75b3b947405f26c4c37a885ce028876dc42e379d2faf6146fed3ea0e42", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := jh.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_jh_512 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"90ecf2f76f9d2c8017d979ad5ab96b87d58fc8fc4b83060f3f900774faa2c8fabe69c5f4ff1ec2b61d6b316941cedee117fb04b1f4c5bc1b919ae841c50eec4f", ""}, - TestHash{"f12c87e986daff17c481c81a99a39b603ca6bafcd320c5735523b97cb9a26f7681bad62ffad9aad0e21160a05f773fb0d1434ca4cbcb0483f480a171ada1561b", "a"}, - TestHash{"bafb8e710b35eabeb1a48220c4b0987c2c985b6e73b7b31d164bfb9d67c94d99d7bc43b474a25e647cd6cc36334b6a00a5f2a85fae74907fd2885c6168132fe7", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := jh.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"90ecf2f76f9d2c8017d979ad5ab96b87d58fc8fc4b83060f3f900774faa2c8fabe69c5f4ff1ec2b61d6b316941cedee117fb04b1f4c5bc1b919ae841c50eec4f", ""}, + TestHash{"f12c87e986daff17c481c81a99a39b603ca6bafcd320c5735523b97cb9a26f7681bad62ffad9aad0e21160a05f773fb0d1434ca4cbcb0483f480a171ada1561b", "a"}, + TestHash{"bafb8e710b35eabeb1a48220c4b0987c2c985b6e73b7b31d164bfb9d67c94d99d7bc43b474a25e647cd6cc36334b6a00a5f2a85fae74907fd2885c6168132fe7", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := jh.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_groestl_224 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"f2e180fb5947be964cd584e22e496242c6a329c577fc4ce8c36d34c3", ""}, - TestHash{"2dfa5bd326c23c451b1202d99e6cee98a98c45927e1a31077f538712", "a"}, - TestHash{"c8a3e7274d599900ae673419683c3626a2e49ed57308ed2687508bef", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := groestl.hash_224(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"f2e180fb5947be964cd584e22e496242c6a329c577fc4ce8c36d34c3", ""}, + TestHash{"2dfa5bd326c23c451b1202d99e6cee98a98c45927e1a31077f538712", "a"}, + TestHash{"c8a3e7274d599900ae673419683c3626a2e49ed57308ed2687508bef", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := groestl.hash_224(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_groestl_256 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"1a52d11d550039be16107f9c58db9ebcc417f16f736adb2502567119f0083467", ""}, - TestHash{"3645c245bb31223ad93c80885b719aa40b4bed0a9d9d6e7c11fe99e59ca350b5", "a"}, - TestHash{"2679d98913bee62e57fdbdde97ddb328373548c6b24fc587cc3d08f2a02a529c", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := groestl.hash_256(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"1a52d11d550039be16107f9c58db9ebcc417f16f736adb2502567119f0083467", ""}, + TestHash{"3645c245bb31223ad93c80885b719aa40b4bed0a9d9d6e7c11fe99e59ca350b5", "a"}, + TestHash{"2679d98913bee62e57fdbdde97ddb328373548c6b24fc587cc3d08f2a02a529c", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := groestl.hash_256(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_groestl_384 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"ac353c1095ace21439251007862d6c62f829ddbe6de4f78e68d310a9205a736d8b11d99bffe448f57a1cfa2934f044a5", ""}, - TestHash{"13fce7bd9fc69b67cc12c77e765a0a97794c585f89df39fbff32408e060d7d9225c7e80fd87da647686888bda896c342", "a"}, - TestHash{"1c446cd70a6de52c9db386f5305aae029fe5a4120bc6230b7cd3a5e1ef1949cc8e6d2548c24cd7347b5ba512628a62f6", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := groestl.hash_384(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"ac353c1095ace21439251007862d6c62f829ddbe6de4f78e68d310a9205a736d8b11d99bffe448f57a1cfa2934f044a5", ""}, + TestHash{"13fce7bd9fc69b67cc12c77e765a0a97794c585f89df39fbff32408e060d7d9225c7e80fd87da647686888bda896c342", "a"}, + TestHash{"1c446cd70a6de52c9db386f5305aae029fe5a4120bc6230b7cd3a5e1ef1949cc8e6d2548c24cd7347b5ba512628a62f6", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := groestl.hash_384(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_groestl_512 :: proc(t: ^testing.T) { - test_vectors := [?]TestHash { - TestHash{"6d3ad29d279110eef3adbd66de2a0345a77baede1557f5d099fce0c03d6dc2ba8e6d4a6633dfbd66053c20faa87d1a11f39a7fbe4a6c2f009801370308fc4ad8", ""}, - TestHash{"9ef345a835ee35d6d0d462ce45f722d84b5ca41fde9c81a98a22cfb4f7425720511b03a258cdc055bf8e9179dc9bdb5d88bed906c71125d4cf0cd39d3d7bebc7", "a"}, - TestHash{"862849fd911852cd54beefa88759db4cead0ef8e36aaf15398303c5c4cbc016d9b4c42b32081cbdcba710d2693e7663d244fae116ec29ffb40168baf44f944e7", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, - } - for v, _ in test_vectors { - computed := groestl.hash_512(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors := [?]TestHash { + TestHash{"6d3ad29d279110eef3adbd66de2a0345a77baede1557f5d099fce0c03d6dc2ba8e6d4a6633dfbd66053c20faa87d1a11f39a7fbe4a6c2f009801370308fc4ad8", ""}, + TestHash{"9ef345a835ee35d6d0d462ce45f722d84b5ca41fde9c81a98a22cfb4f7425720511b03a258cdc055bf8e9179dc9bdb5d88bed906c71125d4cf0cd39d3d7bebc7", "a"}, + TestHash{"862849fd911852cd54beefa88759db4cead0ef8e36aaf15398303c5c4cbc016d9b4c42b32081cbdcba710d2693e7663d244fae116ec29ffb40168baf44f944e7", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, + } + for v, _ in test_vectors { + computed := groestl.hash_512(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_haval_128 :: proc(t: ^testing.T) { - test_vectors_3 := [?]TestHash { - TestHash{"c68f39913f901f3ddf44c707357a7d70", ""}, - TestHash{"0cd40739683e15f01ca5dbceef4059f1", "a"}, - TestHash{"9e40ed883fb63e985d299b40cda2b8f2", "abc"}, - TestHash{"3caf4a79e81adcd6d1716bcc1cef4573", "message digest"}, - TestHash{"dc502247fb3eb8376109eda32d361d82", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"44068770868768964d1f2c3bff4aa3d8", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors_3 { - computed := haval.hash_128_3(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_4 := [?]TestHash { - TestHash{"ee6bbf4d6a46a679b3a856c88538bb98", ""}, - TestHash{"5cd07f03330c3b5020b29ba75911e17d", "a"}, - } - for v, _ in test_vectors_4 { - computed := haval.hash_128_4(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_5 := [?]TestHash { - TestHash{"184b8482a0c050dca54b59c7f05bf5dd", ""}, - TestHash{"f23fbe704be8494bfa7a7fb4f8ab09e5", "a"}, - } - for v, _ in test_vectors_5 { - computed := haval.hash_128_5(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors_3 := [?]TestHash { + TestHash{"c68f39913f901f3ddf44c707357a7d70", ""}, + TestHash{"0cd40739683e15f01ca5dbceef4059f1", "a"}, + TestHash{"9e40ed883fb63e985d299b40cda2b8f2", "abc"}, + TestHash{"3caf4a79e81adcd6d1716bcc1cef4573", "message digest"}, + TestHash{"dc502247fb3eb8376109eda32d361d82", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"44068770868768964d1f2c3bff4aa3d8", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors_3 { + computed := haval.hash_128_3(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_4 := [?]TestHash { + TestHash{"ee6bbf4d6a46a679b3a856c88538bb98", ""}, + TestHash{"5cd07f03330c3b5020b29ba75911e17d", "a"}, + } + for v, _ in test_vectors_4 { + computed := haval.hash_128_4(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_5 := [?]TestHash { + TestHash{"184b8482a0c050dca54b59c7f05bf5dd", ""}, + TestHash{"f23fbe704be8494bfa7a7fb4f8ab09e5", "a"}, + } + for v, _ in test_vectors_5 { + computed := haval.hash_128_5(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_haval_160 :: proc(t: ^testing.T) { - test_vectors_3 := [?]TestHash { - TestHash{"d353c3ae22a25401d257643836d7231a9a95f953", ""}, - TestHash{"4da08f514a7275dbc4cece4a347385983983a830", "a"}, - TestHash{"b21e876c4d391e2a897661149d83576b5530a089", "abc"}, - TestHash{"43a47f6f1c016207f08be8115c0977bf155346da", "message digest"}, - TestHash{"eba9fa6050f24c07c29d1834a60900ea4e32e61b", "abcdefghijklmnopqrstuvwxyz"}, - TestHash{"c30bce448cf8cfe957c141e90c0a063497cdfeeb", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, - } - for v, _ in test_vectors_3 { - computed := haval.hash_160_3(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_4 := [?]TestHash { - TestHash{"1d33aae1be4146dbaaca0b6e70d7a11f10801525", ""}, - TestHash{"e0a5be29627332034d4dd8a910a1a0e6fe04084d", "a"}, - } - for v, _ in test_vectors_4 { - computed := haval.hash_160_4(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_5 := [?]TestHash { - TestHash{"255158cfc1eed1a7be7c55ddd64d9790415b933b", ""}, - TestHash{"f5147df7abc5e3c81b031268927c2b5761b5a2b5", "a"}, - } - for v, _ in test_vectors_5 { - computed := haval.hash_160_5(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors_3 := [?]TestHash { + TestHash{"d353c3ae22a25401d257643836d7231a9a95f953", ""}, + TestHash{"4da08f514a7275dbc4cece4a347385983983a830", "a"}, + TestHash{"b21e876c4d391e2a897661149d83576b5530a089", "abc"}, + TestHash{"43a47f6f1c016207f08be8115c0977bf155346da", "message digest"}, + TestHash{"eba9fa6050f24c07c29d1834a60900ea4e32e61b", "abcdefghijklmnopqrstuvwxyz"}, + TestHash{"c30bce448cf8cfe957c141e90c0a063497cdfeeb", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, + TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + } + for v, _ in test_vectors_3 { + computed := haval.hash_160_3(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_4 := [?]TestHash { + TestHash{"1d33aae1be4146dbaaca0b6e70d7a11f10801525", ""}, + TestHash{"e0a5be29627332034d4dd8a910a1a0e6fe04084d", "a"}, + } + for v, _ in test_vectors_4 { + computed := haval.hash_160_4(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_5 := [?]TestHash { + TestHash{"255158cfc1eed1a7be7c55ddd64d9790415b933b", ""}, + TestHash{"f5147df7abc5e3c81b031268927c2b5761b5a2b5", "a"}, + } + for v, _ in test_vectors_5 { + computed := haval.hash_160_5(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_haval_192 :: proc(t: ^testing.T) { - test_vectors_3 := [?]TestHash { - TestHash{"e9c48d7903eaf2a91c5b350151efcb175c0fc82de2289a4e", ""}, - TestHash{"b359c8835647f5697472431c142731ff6e2cddcacc4f6e08", "a"}, - } - for v, _ in test_vectors_3 { - computed := haval.hash_192_3(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_4 := [?]TestHash { - TestHash{"4a8372945afa55c7dead800311272523ca19d42ea47b72da", ""}, - TestHash{"856c19f86214ea9a8a2f0c4b758b973cce72a2d8ff55505c", "a"}, - } - for v, _ in test_vectors_4 { - computed := haval.hash_192_4(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_5 := [?]TestHash { - TestHash{"4839d0626f95935e17ee2fc4509387bbe2cc46cb382ffe85", ""}, - TestHash{"5ffa3b3548a6e2cfc06b7908ceb5263595df67cf9c4b9341", "a"}, - } - for v, _ in test_vectors_5 { - computed := haval.hash_192_5(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors_3 := [?]TestHash { + TestHash{"e9c48d7903eaf2a91c5b350151efcb175c0fc82de2289a4e", ""}, + TestHash{"b359c8835647f5697472431c142731ff6e2cddcacc4f6e08", "a"}, + } + for v, _ in test_vectors_3 { + computed := haval.hash_192_3(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_4 := [?]TestHash { + TestHash{"4a8372945afa55c7dead800311272523ca19d42ea47b72da", ""}, + TestHash{"856c19f86214ea9a8a2f0c4b758b973cce72a2d8ff55505c", "a"}, + } + for v, _ in test_vectors_4 { + computed := haval.hash_192_4(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_5 := [?]TestHash { + TestHash{"4839d0626f95935e17ee2fc4509387bbe2cc46cb382ffe85", ""}, + TestHash{"5ffa3b3548a6e2cfc06b7908ceb5263595df67cf9c4b9341", "a"}, + } + for v, _ in test_vectors_5 { + computed := haval.hash_192_5(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_haval_224 :: proc(t: ^testing.T) { - test_vectors_3 := [?]TestHash { - TestHash{"c5aae9d47bffcaaf84a8c6e7ccacd60a0dd1932be7b1a192b9214b6d", ""}, - TestHash{"731814ba5605c59b673e4caae4ad28eeb515b3abc2b198336794e17b", "a"}, - } - for v, _ in test_vectors_3 { - computed := haval.hash_224_3(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_4 := [?]TestHash { - TestHash{"3e56243275b3b81561750550e36fcd676ad2f5dd9e15f2e89e6ed78e", ""}, - TestHash{"742f1dbeeaf17f74960558b44f08aa98bdc7d967e6c0ab8f799b3ac1", "a"}, - } - for v, _ in test_vectors_4 { - computed := haval.hash_224_4(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_5 := [?]TestHash { - TestHash{"4a0513c032754f5582a758d35917ac9adf3854219b39e3ac77d1837e", ""}, - TestHash{"67b3cb8d4068e3641fa4f156e03b52978b421947328bfb9168c7655d", "a"}, - } - for v, _ in test_vectors_5 { - computed := haval.hash_224_5(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors_3 := [?]TestHash { + TestHash{"c5aae9d47bffcaaf84a8c6e7ccacd60a0dd1932be7b1a192b9214b6d", ""}, + TestHash{"731814ba5605c59b673e4caae4ad28eeb515b3abc2b198336794e17b", "a"}, + } + for v, _ in test_vectors_3 { + computed := haval.hash_224_3(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_4 := [?]TestHash { + TestHash{"3e56243275b3b81561750550e36fcd676ad2f5dd9e15f2e89e6ed78e", ""}, + TestHash{"742f1dbeeaf17f74960558b44f08aa98bdc7d967e6c0ab8f799b3ac1", "a"}, + } + for v, _ in test_vectors_4 { + computed := haval.hash_224_4(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_5 := [?]TestHash { + TestHash{"4a0513c032754f5582a758d35917ac9adf3854219b39e3ac77d1837e", ""}, + TestHash{"67b3cb8d4068e3641fa4f156e03b52978b421947328bfb9168c7655d", "a"}, + } + for v, _ in test_vectors_5 { + computed := haval.hash_224_5(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } @(test) test_haval_256 :: proc(t: ^testing.T) { - test_vectors_3 := [?]TestHash { - TestHash{"4f6938531f0bc8991f62da7bbd6f7de3fad44562b8c6f4ebf146d5b4e46f7c17", ""}, - TestHash{"47c838fbb4081d9525a0ff9b1e2c05a98f625714e72db289010374e27db021d8", "a"}, - } - for v, _ in test_vectors_3 { - computed := haval.hash_256_3(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_4 := [?]TestHash { - TestHash{"c92b2e23091e80e375dadce26982482d197b1a2521be82da819f8ca2c579b99b", ""}, - TestHash{"e686d2394a49b44d306ece295cf9021553221db132b36cc0ff5b593d39295899", "a"}, - } - for v, _ in test_vectors_4 { - computed := haval.hash_256_4(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } - test_vectors_5 := [?]TestHash { - TestHash{"be417bb4dd5cfb76c7126f4f8eeb1553a449039307b1a3cd451dbfdc0fbbe330", ""}, - TestHash{"de8fd5ee72a5e4265af0a756f4e1a1f65c9b2b2f47cf17ecf0d1b88679a3e22f", "a"}, - } - for v, _ in test_vectors_5 { - computed := haval.hash_256_5(v.str) - computed_str := hex_string(computed[:]) - expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) - } + test_vectors_3 := [?]TestHash { + TestHash{"4f6938531f0bc8991f62da7bbd6f7de3fad44562b8c6f4ebf146d5b4e46f7c17", ""}, + TestHash{"47c838fbb4081d9525a0ff9b1e2c05a98f625714e72db289010374e27db021d8", "a"}, + } + for v, _ in test_vectors_3 { + computed := haval.hash_256_3(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_4 := [?]TestHash { + TestHash{"c92b2e23091e80e375dadce26982482d197b1a2521be82da819f8ca2c579b99b", ""}, + TestHash{"e686d2394a49b44d306ece295cf9021553221db132b36cc0ff5b593d39295899", "a"}, + } + for v, _ in test_vectors_4 { + computed := haval.hash_256_4(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } + test_vectors_5 := [?]TestHash { + TestHash{"be417bb4dd5cfb76c7126f4f8eeb1553a449039307b1a3cd451dbfdc0fbbe330", ""}, + TestHash{"de8fd5ee72a5e4265af0a756f4e1a1f65c9b2b2f47cf17ecf0d1b88679a3e22f", "a"}, + } + for v, _ in test_vectors_5 { + computed := haval.hash_256_5(v.str) + computed_str := hex_string(computed[:]) + expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) + } } diff --git a/tests/core/encoding/json/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin index 4f415c008..6f2e8c35a 100644 --- a/tests/core/encoding/json/test_core_json.odin +++ b/tests/core/encoding/json/test_core_json.odin @@ -12,18 +12,15 @@ when ODIN_TEST { log :: testing.log } else { expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) TEST_count += 1 if !condition { TEST_fail += 1 - fmt.println(message) + fmt.printf("[%v] %v\n", loc, message) return } - fmt.println(" PASS") } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) } } @@ -33,7 +30,7 @@ main :: proc() { parse_json(&t) marshal_json(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } @test diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index 5cb59e001..f9f7a2992 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -173,23 +173,20 @@ TESTS :: []TEST{ } when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + } } test_file_path :: proc(filename: string) -> (path: string) { @@ -229,7 +226,7 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) if len(doc.doctype.rest) > 0 { - wprintf(writer, "\t%v\n", doc.doctype.rest) + wprintf(writer, "\t%v\n", doc.doctype.rest) } } @@ -238,9 +235,9 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { } if doc.root != nil { - wprintln(writer, " --- ") - print_element(writer, doc.root) - wprintln(writer, " --- ") + wprintln(writer, " --- ") + print_element(writer, doc.root) + wprintln(writer, " --- ") } return written, .None @@ -293,7 +290,7 @@ run_tests :: proc(t: ^testing.T) { for test in TESTS { path := test_file_path(test.filename) - printf("\nTrying to parse %v\n\n", path) + log(t, fmt.tprintf("Trying to parse %v", path)) doc, err := xml.parse(path, test.options, Silent) defer xml.destroy(doc) @@ -323,7 +320,7 @@ run_tests :: proc(t: ^testing.T) { } main :: proc() { - t := testing.T{} + t := testing.T{} track: mem.Tracking_Allocator mem.tracking_allocator_init(&track, context.allocator) @@ -338,5 +335,5 @@ main :: proc() { } } - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } \ No newline at end of file diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index 8baa604b6..b81af01a5 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -14,18 +14,15 @@ when ODIN_TEST { log :: testing.log } else { expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) TEST_count += 1 if !condition { TEST_fail += 1 - fmt.println(" FAIL:", message) + fmt.printf("[%v] %v", loc, message) return } - fmt.println(" PASS") } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) } } @@ -34,7 +31,7 @@ main :: proc() { test_benchmark_runner(&t) test_xxhash_vectors(&t) test_crc64_vectors(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } /* diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 155b69298..48d9ca1d2 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -25,38 +25,49 @@ import "core:time" import "core:runtime" -WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false) -TEST_SUITE_PATH :: "assets/PNG" +WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false) +TEST_FILE_PATH_PREFIX :: "tests/core/assets/PNG" TEST_count := 0 TEST_fail := 0 when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + } } + I_Error :: image.Error main :: proc() { t := testing.T{} png_test(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) +} + +test_file_path :: proc(filename: string, extension := "png") -> (path: string) { + + path = fmt.tprintf("%v%v/%v.%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename, extension) + temp := transmute([]u8)path + + for r, i in path { + if r == '\\' { + temp[i] = '/' + } + } + return path } PNG_Test :: struct { @@ -1461,7 +1472,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { context = runtime.default_context() for file in suite { - test_file := fmt.tprintf("%v/%v.png", TEST_SUITE_PATH, file.file) + test_file := test_file_path(file.file) img: ^png.Image err: png.Error diff --git a/tests/core/odin/test_parser.odin b/tests/core/odin/test_parser.odin index 90d913d10..53711d3ec 100644 --- a/tests/core/odin/test_parser.odin +++ b/tests/core/odin/test_parser.odin @@ -10,34 +10,29 @@ TEST_count := 0 TEST_fail := 0 when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + } } - main :: proc() { - t := testing.T{} - test_parse_demo(&t) + t := testing.T{} + test_parse_demo(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } - @test test_parse_demo :: proc(t: ^testing.T) { pkg, ok := parser.parse_package_from_path("examples/demo") diff --git a/tests/core/strings/test_core_strings.odin b/tests/core/strings/test_core_strings.odin index fc1518349..c5436f5c1 100644 --- a/tests/core/strings/test_core_strings.odin +++ b/tests/core/strings/test_core_strings.odin @@ -8,56 +8,53 @@ TEST_count := 0 TEST_fail := 0 when ODIN_TEST { - expect :: testing.expect - log :: testing.log + expect :: testing.expect + log :: testing.log } else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - fmt.printf("[%v] ", loc) - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.println(message) - return - } - fmt.println(" PASS") - } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) - } + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + } } main :: proc() { - t := testing.T{} - test_index_any_small_string_not_found(&t) - test_index_any_larger_string_not_found(&t) - test_index_any_small_string_found(&t) - test_index_any_larger_string_found(&t) + t := testing.T{} + test_index_any_small_string_not_found(&t) + test_index_any_larger_string_not_found(&t) + test_index_any_small_string_found(&t) + test_index_any_larger_string_found(&t) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) } @test test_index_any_small_string_not_found :: proc(t: ^testing.T) { - index := strings.index_any(".", "/:\"") - log(t, index) - expect(t, index == -1, "index_any should be negative") + index := strings.index_any(".", "/:\"") + log(t, index) + expect(t, index == -1, "index_any should be negative") } @test test_index_any_larger_string_not_found :: proc(t: ^testing.T) { - index := strings.index_any("aaaaaaaa.aaaaaaaa", "/:\"") - expect(t, index == -1, "index_any should be negative") + index := strings.index_any("aaaaaaaa.aaaaaaaa", "/:\"") + expect(t, index == -1, "index_any should be negative") } @test test_index_any_small_string_found :: proc(t: ^testing.T) { - index := strings.index_any(".", "/:.\"") - expect(t, index == 0, "index_any should be 0") + index := strings.index_any(".", "/:.\"") + expect(t, index == 0, "index_any should be 0") } @test test_index_any_larger_string_found :: proc(t: ^testing.T) { - index := strings.index_any("aaaaaaaa:aaaaaaaa", "/:\"") - expect(t, index == 8, "index_any should be 8") + index := strings.index_any("aaaaaaaa:aaaaaaaa", "/:\"") + expect(t, index == 8, "index_any should be 8") } From 7ec88d24302dcdea38ac09996a2279f4de4f6a25 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 5 Dec 2021 21:06:33 +0100 Subject: [PATCH 014/245] [xml] Add option. --- .../entity/example/entity_example.odin | 4 +- core/encoding/xml/example/xml_example.odin | 53 +++++++++++-------- core/encoding/xml/xml_reader.odin | 26 +++++++-- tests/core/encoding/xml/test_core_xml.odin | 10 ++-- 4 files changed, 59 insertions(+), 34 deletions(-) diff --git a/core/encoding/entity/example/entity_example.odin b/core/encoding/entity/example/entity_example.odin index 882203f48..6fc377f9d 100644 --- a/core/encoding/entity/example/entity_example.odin +++ b/core/encoding/entity/example/entity_example.odin @@ -64,8 +64,8 @@ main :: proc() { mem.tracking_allocator_init(&track, context.allocator) context.allocator = mem.tracking_allocator(&track) - _main() - //_entities() + // _main() + _entities() if len(track.allocation_map) > 0 { println() diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index 085252e92..daa3c5dab 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -2,35 +2,40 @@ package xml_example import "core:encoding/xml" import "core:os" -import "core:path" import "core:mem" import "core:fmt" - -/* - Silent error handler for the parser. -*/ -Error_Handler :: proc(pos: xml.Pos, fmt: string, args: ..any) {} - -OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, }, expected_doctype = "unicode", } +import "core:time" +import "core:strings" +import "core:hash" example :: proc() { using fmt - filename := path.join(ODIN_ROOT, "tests", "core", "assets", "XML", "unicode.xml") - defer delete(filename) + doc: ^xml.Document + err: xml.Error - doc, err := xml.parse(filename, OPTIONS, Error_Handler) + DOC :: #load("../../../../tests/core/assets/XML/unicode.xml") + + parse_duration: time.Duration + { + time.SCOPED_TICK_DURATION(&parse_duration) + doc, err = xml.parse(DOC, xml.Options{flags={.Ignore_Unsupported}}) + } defer xml.destroy(doc) + ms := time.duration_milliseconds(parse_duration) + speed := (f64(1000.0) / ms) * f64(len(DOC)) / 1_024.0 / 1_024.0 + fmt.printf("Parse time: %v bytes in %.2f ms (%.2f MiB/s).\n", len(DOC), ms, speed) + if err != .None { printf("Load/Parse error: %v\n", err) if err == .File_Error { - printf("\"%v\" not found. Did you run \"tests\\download_assets.py\"?", filename) + println("\"unicode.xml\" not found. Did you run \"tests\\download_assets.py\"?") } os.exit(1) } - printf("\"%v\" loaded and parsed.\n", filename) + println("\"unicode.xml\" loaded and parsed.") charlist, charlist_ok := xml.find_child_by_ident(doc.root, "charlist") if !charlist_ok { @@ -40,17 +45,19 @@ example :: proc() { printf("Found `` with %v children.\n", len(charlist.children)) - for char in charlist.children { - if char.ident != "character" { - eprintf("Expected ``, got `<%v>`\n", char.ident) - os.exit(1) - } + crc32 := doc_hash(doc) + printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32) +} - if _, ok := xml.find_attribute_val_by_key(char, "dec"); !ok { - eprintln("`` attribute not found.") - os.exit(1) - } - } +doc_hash :: proc(doc: ^xml.Document, print := false) -> (crc32: u32) { + buf: strings.Builder + defer strings.destroy_builder(&buf) + w := strings.to_writer(&buf) + + xml.print(w, doc) + tree := strings.to_string(buf) + if print { fmt.println(tree) } + return hash.crc32(transmute([]u8)tree) } main :: proc() { diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 6f49b8e08..b169bd57a 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -71,6 +71,12 @@ Option_Flag :: enum { This option decodes them when encountered. */ Decode_SGML_Entities, + + /* + If a tag body has a comment, it will be stripped unless this option is given. + */ + Keep_Tag_Body_Comments, + } Option_Flags :: bit_set[Option_Flag; u8] @@ -413,15 +419,29 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err /* This should be a tag's body text. */ - body_text := scan_string(t, t.offset) or_return + body_text := scan_string(t, t.offset) or_return + needs_processing := .Unbox_CDATA in opts.flags + needs_processing |= .Decode_SGML_Entities in opts.flags - decode_opts := entity.XML_Decode_Options{ .Comment_Strip } + if !needs_processing { + element.value = strings.intern_get(&doc.intern, body_text) + continue + } + + decode_opts := entity.XML_Decode_Options{} + if .Keep_Tag_Body_Comments not_in opts.flags { + decode_opts += { .Comment_Strip } + } if .Decode_SGML_Entities not_in opts.flags { decode_opts += { .No_Entity_Decode } } + if .Unbox_CDATA in opts.flags { - decode_opts += { .Unbox_CDATA, .Decode_CDATA } + decode_opts += { .Unbox_CDATA } + if .Decode_SGML_Entities in opts.flags { + decode_opts += { .Decode_CDATA } + } } decoded, decode_err := entity.decode_xml(body_text, decode_opts) diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index f9f7a2992..7669afe97 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -8,9 +8,7 @@ import "core:io" import "core:fmt" import "core:hash" -Silent :: proc(pos: xml.Pos, fmt: string, args: ..any) { - // Custom (silent) error handler. -} +Silent :: proc(pos: xml.Pos, format: string, args: ..any) {} OPTIONS :: xml.Options{ flags = { .Ignore_Unsupported, .Intern_Comments, }, expected_doctype = "", @@ -75,7 +73,7 @@ TESTS :: []TEST{ }, expected_doctype = "恥ずべきフクロウ", }, - crc32 = 0x6d38ac58, + crc32 = 0xad31d8e8, }, { @@ -131,7 +129,7 @@ TESTS :: []TEST{ }, expected_doctype = "html", }, - crc32 = 0xdb4a1e79, + crc32 = 0x573c1033, }, { @@ -306,7 +304,7 @@ run_tests :: proc(t: ^testing.T) { expect(t, err == test.err, err_msg) failed |= crc32 != test.crc32 - err_msg = tprintf("Expected CRC 0x%08x, got 0x%08x", test.crc32, crc32) + err_msg = tprintf("Expected CRC 0x%08x, got 0x%08x, with options %v", test.crc32, crc32, test.options) expect(t, crc32 == test.crc32, err_msg) if failed { From 6e61abc7d06f22129f93110a9f652c3eec21f0c6 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 6 Dec 2021 12:04:59 +0100 Subject: [PATCH 015/245] [xml] Initial optimization. --- core/encoding/xml/xml_reader.odin | 68 +++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index b169bd57a..0315b0e05 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -26,6 +26,7 @@ package xml Jeroen van Rijn: Initial implementation. */ +import "core:bytes" import "core:strings" import "core:encoding/entity" import "core:mem" @@ -39,6 +40,12 @@ DEFAULT_Options :: Options{ } Option_Flag :: enum { + /* + If the caller says that input may be modified, we can perform in-situ parsing. + If this flag isn't provided, the XML parser first duplicates the input so that it can. + */ + Input_May_Be_Modified, + /* Document MUST start with ` (doc: ^Document, err: Error) { + data := data context.allocator = allocator opts := validate_options(options) or_return + /* + If `.Input_May_Be_Modified` is not specified, we duplicate the input so that we can modify it in-place. + */ + if .Input_May_Be_Modified not_in opts.flags { + data = bytes.clone(data) + } + t := &Tokenizer{} init(t, string(data), path, error_handler) doc = new(Document) doc.allocator = allocator doc.tokenizer = t + doc.input = data - strings.intern_init(&doc.intern, allocator, allocator) + // strings.intern_init(&doc.intern, allocator, allocator) - err = .Unexpected_Token - element, parent: ^Element + err = .Unexpected_Token + element, parent: ^Element tag_is_open := false @@ -292,8 +313,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err case: if .Error_on_Unsupported in opts.flags { error(t, t.offset, "Unhandled: (doc: ^Document, err: Error) { context.allocator = allocator + options := options data, data_ok := os.read_entire_file(filename) - defer delete(data) - if !data_ok { return {}, .File_Error } + options.flags += { .Input_May_Be_Modified } + return parse_from_slice(data, options, filename, error_handler, allocator) } @@ -499,10 +517,16 @@ destroy :: proc(doc: ^Document) { if doc == nil { return } free_element(doc.root) - strings.intern_destroy(&doc.intern) delete(doc.prolog) delete(doc.comments) + delete(doc.input) + + for s in doc.strings_to_free { + delete(s) + } + delete(doc.strings_to_free) + free(doc) } @@ -538,8 +562,8 @@ parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) _ = expect(t, .Eq) or_return value := expect(t, .String) or_return - attr.key = strings.intern_get(&doc.intern, key.text) - attr.val = strings.intern_get(&doc.intern, value.text) + attr.key = key.text + attr.val = value.text err = .None return @@ -651,7 +675,7 @@ parse_doctype :: proc(doc: ^Document) -> (err: Error) { t := doc.tokenizer tok := expect(t, .Ident) or_return - doc.doctype.ident = strings.intern_get(&doc.intern, tok.text) + doc.doctype.ident = tok.text skip_whitespace(t) offset := t.offset @@ -660,6 +684,6 @@ parse_doctype :: proc(doc: ^Document) -> (err: Error) { /* -1 because the current offset is that of the closing tag, so the rest of the DOCTYPE tag ends just before it. */ - doc.doctype.rest = strings.intern_get(&doc.intern, string(t.src[offset : t.offset - 1])) + doc.doctype.rest = string(t.src[offset : t.offset - 1]) return .None } \ No newline at end of file From 7f6c6945aef7b26632093fa36b56b2951cb27165 Mon Sep 17 00:00:00 2001 From: Despacito696969 <56641258+Despacito696969@users.noreply.github.com> Date: Tue, 5 Apr 2022 20:17:47 +0200 Subject: [PATCH 016/245] Fix for `slice_to_components` Using `slice_to_components` wouldn't compile because `s.data` is type of `rawptr` and return type is `^T` --- core/mem/mem.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 817c0ea5f..d3dcf3a3d 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -166,7 +166,7 @@ slice_data_cast :: proc "contextless" ($T: typeid/[]$A, slice: $S/[]$B) -> T { slice_to_components :: proc "contextless" (slice: $E/[]$T) -> (data: ^T, len: int) { s := transmute(Raw_Slice)slice - return s.data, s.len + return (^T)(s.data), s.len } buffer_from_slice :: proc "contextless" (backing: $T/[]$E) -> [dynamic]E { From 698fcb7813dd391de76a5663ee64c48ce4f7d067 Mon Sep 17 00:00:00 2001 From: hikari Date: Wed, 6 Apr 2022 18:44:43 +0300 Subject: [PATCH 017/245] mem: replace size procedures with constants --- core/mem/mem.odin | 11 ++++++----- core/odin/printer/printer.odin | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 817c0ea5f..a5252d950 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -3,6 +3,12 @@ package mem import "core:runtime" import "core:intrinsics" +Byte :: 1 +Kilobyte :: 1024 * Byte +Megabyte :: 1024 * Kilobyte +Gigabyte :: 1024 * Megabyte +Terabyte :: 1024 * Gigabyte + set :: proc "contextless" (data: rawptr, value: byte, len: int) -> rawptr { return runtime.memset(data, i32(value), len) } @@ -192,11 +198,6 @@ any_to_bytes :: proc "contextless" (val: any) -> []byte { } -kilobytes :: proc "contextless" (x: int) -> int { return (x) * 1024 } -megabytes :: proc "contextless" (x: int) -> int { return kilobytes(x) * 1024 } -gigabytes :: proc "contextless" (x: int) -> int { return megabytes(x) * 1024 } -terabytes :: proc "contextless" (x: int) -> int { return gigabytes(x) * 1024 } - is_power_of_two :: proc "contextless" (x: uintptr) -> bool { if x <= 0 { return false diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin index abda44fa2..807cc99bd 100644 --- a/core/odin/printer/printer.odin +++ b/core/odin/printer/printer.odin @@ -151,7 +151,7 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string { fix_lines(p) - builder := strings.make_builder(0, mem.megabytes(5), p.allocator) + builder := strings.make_builder(0, 5 * mem.Megabyte, p.allocator) last_line := 0 From ad90f416a59be22dbf8fca89890a70407dc5826c Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 7 Apr 2022 12:24:53 +0300 Subject: [PATCH 018/245] runtime: fix typo --- core/runtime/core.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/runtime/core.odin b/core/runtime/core.odin index a5a190a9c..4ab21d8cf 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -565,7 +565,7 @@ __init_context :: proc "contextless" (c: ^Context) { return } - // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contexless" calling convention + // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contextless" calling convention c.allocator.procedure = default_allocator_proc c.allocator.data = nil From c4a7739d13d386743a53ebe3371e8061310ea2cb Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 7 Apr 2022 19:28:24 +0300 Subject: [PATCH 019/245] sys/windows: add a couple macros --- core/sys/windows/util.odin | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/sys/windows/util.odin b/core/sys/windows/util.odin index d464007d3..f448f6bc5 100644 --- a/core/sys/windows/util.odin +++ b/core/sys/windows/util.odin @@ -15,6 +15,14 @@ HIWORD :: #force_inline proc "contextless" (x: DWORD) -> WORD { return WORD(x >> 16) } +GET_X_LPARAM :: #force_inline proc "contextless" (lp: LPARAM) -> c_int { + return cast(c_int)cast(c_short)LOWORD(cast(DWORD)lp) +} + +GET_Y_LPARAM :: #force_inline proc "contextless" (lp: LPARAM) -> c_int { + return cast(c_int)cast(c_short)HIWORD(cast(DWORD)lp) +} + utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 { if len(s) < 1 { return nil From 15b440c4f1878a27f6cc2f2bf1249022f237fe7d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 4 Apr 2022 15:39:42 +0200 Subject: [PATCH 020/245] [image] Add QOI load/save. Additionally: - Firm up PNG loader with some additional checks. - Add helper functions to `core:image` to expand grayscale to RGB(A), and so on. TODO: Possibly replace PNG's post-processing steps with calls to the new helper functions. --- core/compress/common.odin | 4 - core/image/common.odin | 830 +++++++++++++++++++++++++- core/image/png/helpers.odin | 13 +- core/image/png/png.odin | 75 ++- core/image/qoi/qoi.odin | 407 +++++++++++++ tests/core/image/test_core_image.odin | 2 +- 6 files changed, 1270 insertions(+), 61 deletions(-) create mode 100644 core/image/qoi/qoi.odin diff --git a/core/compress/common.odin b/core/compress/common.odin index 58aeac25b..f4e378269 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -128,7 +128,6 @@ Deflate_Error :: enum { BType_3, } - // General I/O context for ZLIB, LZW, etc. Context_Memory_Input :: struct #packed { input_data: []u8, @@ -151,7 +150,6 @@ when size_of(rawptr) == 8 { #assert(size_of(Context_Memory_Input) == 52) } - Context_Stream_Input :: struct #packed { input_data: []u8, input: io.Stream, @@ -185,8 +183,6 @@ Context_Stream_Input :: struct #packed { This simplifies end-of-stream handling where bits may be left in the bit buffer. */ -// TODO: Make these return compress.Error errors. - input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Error) { return i64(len(z.input_data)), nil } diff --git a/core/image/common.odin b/core/image/common.odin index adaa094d8..2e7bca17e 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -15,6 +15,32 @@ import "core:mem" import "core:compress" import "core:runtime" +/* + 67_108_864 pixels max by default. + + For QOI, the Worst case scenario means all pixels will be encoded as RGBA literals, costing 5 bytes each. + This caps memory usage at 320 MiB. + + The tunable is limited to 4_294_836_225 pixels maximum, or 4 GiB per 8-bit channel. + It is not advised to tune it this large. + + The 64 Megapixel default is considered to be a decent upper bound you won't run into in practice, + except in very specific circumstances. + +*/ +MAX_DIMENSIONS :: min(#config(MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535) + +// Color +RGB_Pixel :: [3]u8 +RGBA_Pixel :: [4]u8 +RGB_Pixel_16 :: [3]u16 +RGBA_Pixel_16 :: [4]u16 +// Grayscale +G_Pixel :: [1]u8 +GA_Pixel :: [2]u8 +G_Pixel_16 :: [1]u16 +GA_Pixel_16 :: [2]u16 + Image :: struct { width: int, height: int, @@ -26,15 +52,17 @@ Image :: struct { For convenience, we return them as u16 so we don't need to switch on the type in our viewer, and can just test against nil. */ - background: Maybe([3]u16), - + background: Maybe(RGB_Pixel_16), metadata: Image_Metadata, } Image_Metadata :: union { ^PNG_Info, + ^QOI_Info, } + + /* IMPORTANT: `.do_not_expand_*` options currently skip handling of the `alpha_*` options, therefore Gray+Alpha will be returned as such even if you add `.alpha_drop_if_present`, @@ -46,13 +74,13 @@ Image_Metadata :: union { /* Image_Option: `.info` - This option behaves as `.return_ihdr` and `.do_not_decompress_image` and can be used + This option behaves as `.return_metadata` and `.do_not_decompress_image` and can be used to gather an image's dimensions and color information. `.return_header` - Fill out img.sidecar.header with the image's format-specific header struct. + Fill out img.metadata.header with the image's format-specific header struct. If we only care about the image specs, we can set `.return_header` + - `.do_not_decompress_image`, or `.info`, which works as if both of these were set. + `.do_not_decompress_image`, or `.info`. `.return_metadata` Returns all chunks not needed to decode the data. @@ -88,7 +116,7 @@ Image_Option: `.alpha_premultiply` If the image has an alpha channel, returns image data as follows: - RGB *= A, Gray = Gray *= A + RGB *= A, Gray = Gray *= A `.blend_background` If a bKGD chunk is present in a PNG, we normally just set `img.background` @@ -103,24 +131,29 @@ Image_Option: */ Option :: enum { + // LOAD OPTIONS info = 0, do_not_decompress_image, return_header, return_metadata, - alpha_add_if_missing, - alpha_drop_if_present, - alpha_premultiply, - blend_background, + alpha_add_if_missing, // Ignored for QOI. Always returns RGBA8. + alpha_drop_if_present, // Unimplemented for QOI. Returns error. + alpha_premultiply, // Unimplemented for QOI. Returns error. + blend_background, // Ignored for non-PNG formats // Unimplemented do_not_expand_grayscale, do_not_expand_indexed, do_not_expand_channels, + + // SAVE OPTIONS + qoi_all_channels_linear, // QOI, informative info. If not set, defaults to sRGB with linear alpha. } Options :: distinct bit_set[Option] Error :: union #shared_nil { General_Image_Error, PNG_Error, + QOI_Error, compress.Error, compress.General_Error, @@ -134,8 +167,13 @@ General_Image_Error :: enum { Invalid_Image_Dimensions, Image_Dimensions_Too_Large, Image_Does_Not_Adhere_to_Spec, + Invalid_Input_Image, + Invalid_Output, } +/* + PNG-specific definitions +*/ PNG_Error :: enum { None = 0, Invalid_PNG_Signature, @@ -147,7 +185,9 @@ PNG_Error :: enum { IDAT_Size_Too_Large, PLTE_Encountered_Unexpectedly, PLTE_Invalid_Length, + PLTE_Missing, TRNS_Encountered_Unexpectedly, + TNRS_Invalid_Length, BKGD_Invalid_Length, Unknown_Color_Type, Invalid_Color_Bit_Depth_Combo, @@ -158,9 +198,6 @@ PNG_Error :: enum { Invalid_Chunk_Length, } -/* - PNG-specific structs -*/ PNG_Info :: struct { header: PNG_IHDR, chunks: [dynamic]PNG_Chunk, @@ -223,7 +260,7 @@ PNG_Chunk_Type :: enum u32be { */ iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T', - CbGI = 'C' << 24 | 'b' << 16 | 'H' << 8 | 'I', + CgBI = 'C' << 24 | 'g' << 16 | 'B' << 8 | 'I', } PNG_IHDR :: struct #packed { @@ -251,16 +288,44 @@ PNG_Interlace_Method :: enum u8 { } /* - Functions to help with image buffer calculations + QOI-specific definitions */ +QOI_Error :: enum { + None = 0, + Invalid_QOI_Signature, + Invalid_Number_Of_Channels, // QOI allows 3 or 4 channel data. + Invalid_Bit_Depth, // QOI supports only 8-bit images, error only returned from writer. + Invalid_Color_Space, // QOI allows 0 = sRGB or 1 = linear. + Corrupt, // More data than pixels to decode into, for example. + Missing_Or_Corrupt_Trailer, // Image seemed to have decoded okay, but trailer is missing or corrupt. +} + +QOI_Magic :: u32be(0x716f6966) // "qoif" + +QOI_Color_Space :: enum u8 { + sRGB = 0, + Linear = 1, +} + +QOI_Header :: struct #packed { + magic: u32be, + width: u32be, + height: u32be, + channels: u8, + color_space: QOI_Color_Space, +} +#assert(size_of(QOI_Header) == 14) + +QOI_Info :: struct { + header: QOI_Header, +} + +// Function to help with image buffer calculations compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) { size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height return } -/* - For when you have an RGB(A) image, but want a particular channel. -*/ Channel :: enum u8 { R = 1, G = 2, @@ -268,7 +333,13 @@ Channel :: enum u8 { A = 4, } +// When you have an RGB(A) image, but want a particular channel. return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok: bool) { + // Were we actually given a valid image? + if img == nil { + return nil, false + } + ok = false t: bytes.Buffer @@ -298,7 +369,7 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok o = o[1:] } case 16: - buffer_size := compute_buffer_size(img.width, img.height, 2, 8) + buffer_size := compute_buffer_size(img.width, img.height, 1, 16) t = bytes.Buffer{} resize(&t.buf, buffer_size) @@ -326,3 +397,724 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok return res, true } + +// Does the image have 1 or 2 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_grayscale_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + // Are we a Gray or Gray + Alpha image? + if img.channels != 1 && img.channels != 2 { + return false + } + + // Do we have an acceptable bit depth? + if img.depth != 8 && img.depth != 16 { + return false + } + + // This returns 0 if any of the inputs is zero. + bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth) + + // If the dimenions are invalid or the buffer size doesn't match the image characteristics, bail. + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + return true +} + +// Does the image have 3 or 4 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_color_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + // Are we an RGB or RGBA image? + if img.channels != 3 && img.channels != 4 { + return false + } + + // Do we have an acceptable bit depth? + if img.depth != 8 && img.depth != 16 { + return false + } + + // This returns 0 if any of the inputs is zero. + bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth) + + // If the dimenions are invalid or the buffer size doesn't match the image characteristics, bail. + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + return true +} + +// Does the image have 1..4 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + return is_valid_color_image(img) || is_valid_grayscale_image(img) +} + +Alpha_Key :: union { + GA_Pixel, + RGBA_Pixel, + GA_Pixel_16, + RGBA_Pixel_16, +} + +/* + Add alpha channel if missing, in-place. + + Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA). + Any other number of channels will be considered an error, returning `false` without modifying the image. + If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha). + + If an image doesn't already have an alpha channel: + If the optional `alpha_key` is provided, it will be resolved as follows: + - For RGB, if pix = key.rgb -> pix = {0, 0, 0, key.a} + - For Gray, if pix = key.r -> pix = {0, key.g} + Otherwise, an opaque alpha channel will be added. +*/ +alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_image(img) { + return false + } + + // We should now have a valid Image with 1..4 channels. Do we already have alpha? + if img.channels == 2 || img.channels == 4 { + // We're done. + return true + } + + channels := img.channels + 1 + bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth) + + buf := bytes.Buffer{} + + // Can we allocate the return buffer? + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch channels { + case 2: + // Turn Gray into Gray + Alpha + inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]GA_Pixel, buf.buf[:]) + + if key, key_ok := alpha_key.(GA_Pixel); key_ok { + // We have keyed alpha. + o: GA_Pixel + for p in inp { + if p == key.r { + o = GA_Pixel{0, key.g} + } else { + o = GA_Pixel{p.r, 255} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := GA_Pixel{0, 255} + for p in inp { + o.r = p.r + out[0] = o + out = out[1:] + } + } + + case 4: + // Turn RGB into RGBA + inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + if key, key_ok := alpha_key.(RGBA_Pixel); key_ok { + // We have keyed alpha. + o: RGBA_Pixel + for p in inp { + if p == key.rgb { + o = RGBA_Pixel{0, 0, 0, key.a} + } else { + o = RGBA_Pixel{p.r, p.g, p.b, 255} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := RGBA_Pixel{0, 0, 0, 255} + for p in inp { + o.rgb = p + out[0] = o + out = out[1:] + } + } + case: + // We shouldn't get here. + unreachable() + } + case 16: + switch channels { + case 2: + // Turn Gray into Gray + Alpha + inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]GA_Pixel_16, buf.buf[:]) + + if key, key_ok := alpha_key.(GA_Pixel_16); key_ok { + // We have keyed alpha. + o: GA_Pixel_16 + for p in inp { + if p == key.r { + o = GA_Pixel_16{0, key.g} + } else { + o = GA_Pixel_16{p.r, 65535} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := GA_Pixel_16{0, 65535} + for p in inp { + o.r = p.r + out[0] = o + out = out[1:] + } + } + + case 4: + // Turn RGB into RGBA + inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + if key, key_ok := alpha_key.(RGBA_Pixel_16); key_ok { + // We have keyed alpha. + o: RGBA_Pixel_16 + for p in inp { + if p == key.rgb { + o = RGBA_Pixel_16{0, 0, 0, key.a} + } else { + o = RGBA_Pixel_16{p.r, p.g, p.b, 65535} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := RGBA_Pixel_16{0, 0, 0, 65535} + for p in inp { + o.rgb = p + out[0] = o + out = out[1:] + } + } + case: + // We shouldn't get here. + unreachable() + } + } + + // If we got here, that means we've now got a buffer with the alpha channel added. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = channels + return true +} +alpha_apply_keyed_alpha :: alpha_add_if_missing + +/* + Drop alpha channel if present, in-place. + + Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA). + Any other number of channels will be considered an error, returning `false` without modifying the image. + + Of the `options`, the following are considered: + `.alpha_premultiply` + If the image has an alpha channel, returns image data as follows: + RGB *= A, Gray = Gray *= A + + `.blend_background` + If `img.background` is set, it'll be blended in like this: + RGB = (1 - A) * Background + A * RGB + + If an image has 1 (Gray) or 3 (RGB) channels, it'll return early without modifying the image, + with one exception: `alpha_key` and `img.background` are present, and `.blend_background` is set. + + In this case a keyed alpha pixel will be replaced with the background color. +*/ +alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_image(img) { + return false + } + + // Do we have a background to blend? + will_it_blend := false + switch v in img.background { + case RGB_Pixel_16: will_it_blend = true if .blend_background in options else false + } + + // Do we have keyed alpha? + keyed := false + switch v in alpha_key { + case GA_Pixel: keyed = true if img.channels == 1 && img.depth == 8 else false + case RGBA_Pixel: keyed = true if img.channels == 3 && img.depth == 8 else false + case GA_Pixel_16: keyed = true if img.channels == 1 && img.depth == 16 else false + case RGBA_Pixel_16: keyed = true if img.channels == 3 && img.depth == 16 else false + } + + // We should now have a valid Image with 1..4 channels. Do we have alpha? + if img.channels == 1 || img.channels == 3 { + if !(will_it_blend && keyed) { + // We're done + return true + } + } + + // # of destination channels + channels := 1 if img.channels < 3 else 3 + + bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth) + buf := bytes.Buffer{} + + // Can we allocate the return buffer? + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch img.channels { + case 1: // Gray to Gray, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel, buf.buf[:]) + + key := alpha_key.(GA_Pixel).r + bg := G_Pixel{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = u8(temp_bg.r >> 8) + } + + for p in inp { + out[0] = bg if p == key else p + out = out[1:] + } + + case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background. + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := f32(0.0) + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = f32(temp_bg.r >> 8) + } + + for p in inp { + a := f32(p.g) / 255.0 + c := ((1.0 - a) * bg + a * f32(p.r)) + out[0] = u8(c) + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.g) / 255.0 + c := f32(p.r) * a + out[0] = u8(c) + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.r + out = out[1:] + } + } + + case 3: // RGB to RGB, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + key := alpha_key.(RGBA_Pixel) + bg := RGB_Pixel{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, squash down to 8 bits. + bg = {u8(temp_bg.r >> 8), u8(temp_bg.g >> 8), u8(temp_bg.b >> 8)} + } + + for p in inp { + out[0] = bg if p == key.rgb else p + out = out[1:] + } + + case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply. + inp := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := [3]f32{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = {f32(temp_bg.r >> 8), f32(temp_bg.g >> 8), f32(temp_bg.b >> 8)} + } + + for p in inp { + a := f32(p.a) / 255.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := ((1.0 - a) * bg + a * rgb) + + out[0] = {u8(c.r), u8(c.g), u8(c.b)} + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.a) / 255.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := rgb * a + + out[0] = {u8(c.r), u8(c.g), u8(c.b)} + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.rgb + out = out[1:] + } + } + } + + case 16: + switch img.channels { + case 1: // Gray to Gray, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:]) + + key := alpha_key.(GA_Pixel_16).r + bg := G_Pixel_16{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel. + bg = temp_bg.r + } + + for p in inp { + out[0] = bg if p == key else p + out = out[1:] + } + + case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background. + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := f32(0.0) + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel. + bg = f32(temp_bg.r) + } + + for p in inp { + a := f32(p.g) / 65535.0 + c := ((1.0 - a) * bg + a * f32(p.r)) + out[0] = u16(c) + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.g) / 65535.0 + c := f32(p.r) * a + out[0] = u16(c) + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.r + out = out[1:] + } + } + + case 3: // RGB to RGB, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + key := alpha_key.(RGBA_Pixel_16) + bg := img.background.(RGB_Pixel_16) + + for p in inp { + out[0] = bg if p == key.rgb else p + out = out[1:] + } + + case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply. + inp := mem.slice_data_cast([]RGBA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := [3]f32{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, convert to [3]f32 to blend. + bg = {f32(temp_bg.r), f32(temp_bg.g), f32(temp_bg.b)} + } + + for p in inp { + a := f32(p.a) / 65535.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := ((1.0 - a) * bg + a * rgb) + + out[0] = {u16(c.r), u16(c.g), u16(c.b)} + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.a) / 65535.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := rgb * a + + out[0] = {u16(c.r), u16(c.g), u16(c.b)} + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.rgb + out = out[1:] + } + } + } + + case: + unreachable() + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = channels + return true +} + +// Apply palette to 8-bit single-channel image and return an 8-bit RGB image, in-place. +// If the image given is not a valid 8-bit single channel image, the procedure will return `false` early. +apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if img == nil || img.channels != 1 || img.depth != 8 { + return false + } + + bytes_expected := compute_buffer_size(img.width, img.height, 1, 8) + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + // Apply the palette + for p, i in img.pixels.buf { + out[i] = palette[p] + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = 3 + return true +} + +// Apply palette to 8-bit single-channel image and return an 8-bit RGBA image, in-place. +// If the image given is not a valid 8-bit single channel image, the procedure will return `false` early. +apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if img == nil || img.channels != 1 || img.depth != 8 { + return false + } + + bytes_expected := compute_buffer_size(img.width, img.height, 1, 8) + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + // Apply the palette + for p, i in img.pixels.buf { + out[i] = palette[p] + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = 4 + return true +} +apply_palette :: proc{apply_palette_rgb, apply_palette_rgba} + + +// Replicates grayscale values into RGB(A) 8- or 16-bit images as appropriate. +// Returns early with `false` if already an RGB(A) image. +expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_grayscale_image(img) { + return false + } + + // We should have 1 or 2 channels of 8- or 16 bits now. We need to turn that into 3 or 4. + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch img.channels { + case 1: // Turn Gray into RGB + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + for p in img.pixels.buf { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case 16: + switch img.channels { + case 1: // Turn Gray into RGB + inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + for p in inp { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case: + unreachable() + } + + + // If we got here, that means we've now got a buffer with the extra alpha channel. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels += 2 + return true +} + +/* + Helper functions to read and write data from/to a Context, etc. +*/ +@(optimization_mode="speed") +read_data :: proc(z: $C, $T: typeid) -> (res: T, err: compress.General_Error) { + if r, e := compress.read_data(z, T); e != .None { + return {}, .Stream_Too_Short + } else { + return r, nil + } +} + +@(optimization_mode="speed") +read_u8 :: proc(z: $C) -> (res: u8, err: compress.General_Error) { + if r, e := compress.read_u8(z); e != .None { + return {}, .Stream_Too_Short + } else { + return r, nil + } +} + +write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Error) { + if len(data) == 0 { + return nil + } else if len(data) == 1 { + if bytes.buffer_write_byte(buf, data[0]) != nil { + return compress.General_Error.Resize_Failed + } + } else if n, _ := bytes.buffer_write(buf, data); n != len(data) { + return compress.General_Error.Resize_Failed + } + return nil +} \ No newline at end of file diff --git a/core/image/png/helpers.odin b/core/image/png/helpers.odin index c64e6f471..0ebf0b20b 100644 --- a/core/image/png/helpers.odin +++ b/core/image/png/helpers.odin @@ -242,17 +242,16 @@ srgb :: proc(c: image.PNG_Chunk) -> (res: sRGB, ok: bool) { } plte :: proc(c: image.PNG_Chunk) -> (res: PLTE, ok: bool) { - if c.header.type != .PLTE { + if c.header.type != .PLTE || c.header.length % 3 != 0 || c.header.length > 768 { return {}, false } - i := 0; j := 0; ok = true - for j < int(c.header.length) { - res.entries[i] = {c.data[j], c.data[j+1], c.data[j+2]} - i += 1; j += 3 + plte := mem.slice_data_cast([]image.RGB_Pixel, c.data[:]) + for color, i in plte { + res.entries[i] = color } - res.used = u16(i) - return + res.used = u16(len(plte)) + return res, true } splt :: proc(c: image.PNG_Chunk) -> (res: sPLT, ok: bool) { diff --git a/core/image/png/png.odin b/core/image/png/png.odin index bff0afde3..55d69e7c7 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -25,16 +25,13 @@ import "core:io" import "core:mem" import "core:intrinsics" -/* - 67_108_864 pixels max by default. - Maximum allowed dimensions are capped at 65535 * 65535. -*/ -MAX_DIMENSIONS :: min(#config(PNG_MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535) +import "core:fmt" + + +// Limit chunk sizes. +// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes. +// The total number of pixels defaults to 64 Megapixel and can be tuned in image/common.odin. -/* - Limit chunk sizes. - By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes. -*/ _MAX_IDAT_DEFAULT :: ( 8192 /* Width */ * 8192 /* Height */ * 2 /* 16-bit */) + 8192 /* Filter bytes */ _MAX_IDAT :: (65535 /* Width */ * 65535 /* Height */ * 2 /* 16-bit */) + 65535 /* Filter bytes */ @@ -64,7 +61,7 @@ Row_Filter :: enum u8 { Paeth = 4, } -PLTE_Entry :: [3]u8 +PLTE_Entry :: image.RGB_Pixel PLTE :: struct #packed { entries: [256]PLTE_Entry, @@ -259,7 +256,7 @@ read_header :: proc(ctx: ^$C) -> (image.PNG_IHDR, Error) { header := (^image.PNG_IHDR)(raw_data(c.data))^ // Validate IHDR using header - if width == 0 || height == 0 || u128(width) * u128(height) > MAX_DIMENSIONS { + if width == 0 || height == 0 || u128(width) * u128(height) > image.MAX_DIMENSIONS { return {}, .Invalid_Image_Dimensions } @@ -366,6 +363,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options -= {.info} } + if .return_header in options && .return_metadata in options { + options -= {.return_header} + } + if .alpha_drop_if_present in options && .alpha_add_if_missing in options { return {}, compress.General_Error.Incompatible_Options } @@ -392,7 +393,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a idat_length := u64(0) - c: image.PNG_Chunk + c: image.PNG_Chunk ch: image.PNG_Chunk_Header e: io.Error @@ -473,6 +474,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } info.header = h + if .return_header in options && .return_metadata not_in options && .do_not_decompress_image not_in options { + return img, nil + } + case .PLTE: seen_plte = true // PLTE must appear before IDAT and can't appear for color types 0, 4. @@ -540,9 +545,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a seen_iend = true case .bKGD: - - // TODO: Make sure that 16-bit bKGD + tRNS chunks return u16 instead of u16be - c = read_chunk(ctx) or_return seen_bkgd = true if .return_metadata in options { @@ -594,23 +596,39 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a */ final_image_channels += 1 - seen_trns = true + + if .Paletted in header.color_type { + if len(c.data) > 256 { + fmt.printf("[PLTE] tRNS length: %v\n", len(c.data)) + return img, .TNRS_Invalid_Length + } + } else if .Color in header.color_type { + if len(c.data) != 6 { + fmt.printf("[COLOR] tRNS length: %v\n", len(c.data)) + return img, .TNRS_Invalid_Length + } + } else if len(c.data) != 2 { + fmt.printf("[GRAY] tRNS length: %v\n", len(c.data)) + return img, .TNRS_Invalid_Length + } + if info.header.bit_depth < 8 && .Paletted not_in info.header.color_type { // Rescale tRNS data so key matches intensity - dsc := depth_scale_table + dsc := depth_scale_table scale := dsc[info.header.bit_depth] if scale != 1 { key := mem.slice_data_cast([]u16be, c.data)[0] * u16be(scale) c.data = []u8{0, u8(key & 255)} } } + trns = c - case .iDOT, .CbGI: + case .iDOT, .CgBI: /* iPhone PNG bastardization that doesn't adhere to spec with broken IDAT chunk. - We're not going to add support for it. If you have the misfortunte of coming + We're not going to add support for it. If you have the misfortune of coming across one of these files, use a utility to defry it. */ return img, .Image_Does_Not_Adhere_to_Spec @@ -635,6 +653,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, .IDAT_Missing } + if .Paletted in header.color_type && !seen_plte { + return img, .PLTE_Missing + } + /* Calculate the expected output size, to help `inflate` make better decisions about the output buffer. We'll also use it to check the returned buffer size is what we expected it to be. @@ -683,15 +705,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return {}, defilter_error } - /* - Now we'll handle the relocoring of paletted images, handling of tRNS chunks, - and we'll expand grayscale images to RGB(A). - - For the sake of convenience we return only RGB(A) images. In the future we - may supply an option to return Gray/Gray+Alpha as-is, in which case RGB(A) - will become the default. - */ - if .Paletted in header.color_type && .do_not_expand_indexed in options { return img, nil } @@ -699,7 +712,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, nil } - + /* + Now we're going to optionally apply various post-processing stages, + to for example expand grayscale, apply a palette, premultiply alpha, etc. + */ raw_image_channels := img.channels out_image_channels := 3 @@ -1204,7 +1220,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, nil } - filter_paeth :: #force_inline proc(left, up, up_left: u8) -> u8 { aa, bb, cc := i16(left), i16(up), i16(up_left) p := aa + bb - cc diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin new file mode 100644 index 000000000..c157e8099 --- /dev/null +++ b/core/image/qoi/qoi.odin @@ -0,0 +1,407 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + + +// package qoi implements a QOI image reader +// +// The QOI specification is at https://qoiformat.org. +package qoi + +import "core:mem" +import "core:image" +import "core:compress" +import "core:bytes" +import "core:os" + +Error :: image.Error +General :: compress.General_Error +Image :: image.Image +Options :: image.Options + +RGB_Pixel :: image.RGB_Pixel +RGBA_Pixel :: image.RGBA_Pixel + +save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if img == nil { + return .Invalid_Input_Image + } + + if output == nil { + return .Invalid_Output + } + + pixels := img.width * img.height + if pixels == 0 || pixels > image.MAX_DIMENSIONS { + return .Invalid_Input_Image + } + + // QOI supports only 8-bit images with 3 or 4 channels. + if img.depth != 8 || img.channels < 3 || img.channels > 4 { + return .Invalid_Input_Image + } + + if img.channels * pixels != len(img.pixels.buf) { + return .Invalid_Input_Image + } + + written := 0 + + // Calculate and allocate maximum size. We'll reclaim space to actually written output at the end. + max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be) + + if !resize(&output.buf, max_size) { + return General.Resize_Failed + } + + header := image.QOI_Header{ + magic = image.QOI_Magic, + width = u32be(img.width), + height = u32be(img.height), + channels = u8(img.channels), + color_space = .Linear if .qoi_all_channels_linear in options else .sRGB, + } + header_bytes := transmute([size_of(image.QOI_Header)]u8)header + + copy(output.buf[written:], header_bytes[:]) + written += size_of(image.QOI_Header) + + /* + Encode loop starts here. + */ + seen: [64]RGBA_Pixel + pix := RGBA_Pixel{0, 0, 0, 255} + prev := pix + + seen[qoi_hash(pix)] = pix + + input := img.pixels.buf[:] + run := u8(0) + + for len(input) > 0 { + if img.channels == 4 { + pix = (^RGBA_Pixel)(raw_data(input))^ + } else { + pix.rgb = (^RGB_Pixel)(raw_data(input))^ + } + input = input[img.channels:] + + if pix == prev { + run += 1 + // As long as the pixel matches the last one, accumulate the run total. + // If we reach the max run length or the end of the image, write the run. + if run == 62 || len(input) == 0 { + // Encode and write run + output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1) + written += 1 + run = 0 + } + } else { + if run > 0 { + // The pixel differs from the previous one, but we still need to write the pending run. + // Encode and write run + output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1) + written += 1 + run = 0 + } + + index := qoi_hash(pix) + + if seen[index] == pix { + // Write indexed pixel + output.buf[written] = u8(QOI_Opcode_Tag.INDEX) | index + written += 1 + } else { + // Add pixel to index + seen[index] = pix + + // If the alpha matches the previous pixel's alpha, we don't need to write a full RGBA literal. + if pix.a == prev.a { + // Delta + d := pix.rgb - prev.rgb + + // DIFF, biased and modulo 256 + _d := d + 2 + + // LUMA, biased and modulo 256 + _l := RGB_Pixel{ d.r - d.g + 8, d.g + 32, d.b - d.g + 8 } + + if _d.r < 4 && _d.g < 4 && _d.b < 4 { + // Delta is between -2 and 1 inclusive + output.buf[written] = u8(QOI_Opcode_Tag.DIFF) | _d.r << 4 | _d.g << 2 | _d.b + written += 1 + } else if _l.r < 16 && _l.g < 64 && _l.b < 16 { + // Biased luma is between {-8..7, -32..31, -8..7} + output.buf[written ] = u8(QOI_Opcode_Tag.LUMA) | _l.g + output.buf[written + 1] = _l.r << 4 | _l.b + written += 2 + } else { + // Write RGB literal + output.buf[written] = u8(QOI_Opcode_Tag.RGB) + pix_bytes := transmute([4]u8)pix + copy(output.buf[written + 1:], pix_bytes[:3]) + written += 4 + } + } else { + // Write RGBA literal + output.buf[written] = u8(QOI_Opcode_Tag.RGBA) + pix_bytes := transmute([4]u8)pix + copy(output.buf[written + 1:], pix_bytes[:]) + written += 5 + } + } + } + prev = pix + } + + trailer := []u8{0, 0, 0, 0, 0, 0, 0, 1} + copy(output.buf[written:], trailer[:]) + written += len(trailer) + + resize(&output.buf, written) + return nil +} + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else General.Cannot_Open_File +} + +save :: proc{save_to_memory, save_to_file} + +load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + ctx := &compress.Context_Memory_Input{ + input_data = slice, + } + + img, err = load_from_context(ctx, options, allocator) + return img, err +} + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename) + defer delete(data) + + if ok { + return load_from_slice(data, options) + } else { + img = new(Image) + return img, compress.General_Error.File_Not_Found + } +} + +@(optimization_mode="speed") +load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + options := options + + if .alpha_drop_if_present in options || .alpha_premultiply in options { + // TODO: Implement. + // As stated in image/common, unimplemented options are ignored. + } + + if .info in options { + options |= {.return_metadata, .do_not_decompress_image} + options -= {.info} + } + + if .return_header in options && .return_metadata in options { + options -= {.return_header} + } + + header := image.read_data(ctx, image.QOI_Header) or_return + if header.magic != image.QOI_Magic { + return img, .Invalid_QOI_Signature + } + + if img == nil { + img = new(Image) + } + + if .return_metadata in options { + info := new(image.QOI_Info) + info.header = header + img.metadata = info + } + + if header.channels != 3 && header.channels != 4 { + return img, .Invalid_Number_Of_Channels + } + + if header.color_space != .sRGB && header.color_space != .Linear { + return img, .Invalid_Color_Space + } + + if header.width == 0 || header.height == 0 { + return img, .Invalid_Image_Dimensions + } + + total_pixels := header.width * header.height + if total_pixels > image.MAX_DIMENSIONS { + return img, .Image_Dimensions_Too_Large + } + + img.width = int(header.width) + img.height = int(header.height) + img.channels = 4 + img.depth = 8 + + if .do_not_decompress_image in options { + return + } + + bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), 4, 8) + + if !resize(&img.pixels.buf, bytes_needed) { + return img, mem.Allocator_Error.Out_Of_Memory + } + pixels := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) + + /* + Decode loop starts here. + */ + seen: [64]RGBA_Pixel + pix := RGBA_Pixel{0, 0, 0, 255} + seen[qoi_hash(pix)] = pix + + decode: for len(pixels) > 0 { + data := image.read_u8(ctx) or_return + + tag := QOI_Opcode_Tag(data) + #partial switch tag { + case .RGB: + pix.rgb = image.read_data(ctx, RGB_Pixel) or_return + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .RGBA: + pix = image.read_data(ctx, RGBA_Pixel) or_return + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case: + // 2-bit tag + tag = QOI_Opcode_Tag(data & QOI_Opcode_Mask) + #partial switch tag { + case .INDEX: + pix = seen[data & 63] + + case .DIFF: + diff_r := ((data >> 4) & 3) - 2 + diff_g := ((data >> 2) & 3) - 2 + diff_b := ((data >> 0) & 3) - 2 + + pix += {diff_r, diff_g, diff_b, 0} + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .LUMA: + data2 := image.read_u8(ctx) or_return + + diff_g := (data & 63) - 32 + diff_r := diff_g - 8 + ((data2 >> 4) & 15) + diff_b := diff_g - 8 + (data2 & 15) + + pix += {diff_r, diff_g, diff_b, 0} + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .RUN: + if length := int(data & 63) + 1; length > len(pixels) { + return img, .Corrupt + } else { + #no_bounds_check for i in 0.. (index: u8) { + i1 := u16(pixel.r) * 3 + i2 := u16(pixel.g) * 5 + i3 := u16(pixel.b) * 7 + i4 := u16(pixel.a) * 11 + + return u8((i1 + i2 + i3 + i4) & 63) +} \ No newline at end of file diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 52005d915..38291db6b 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1500,7 +1500,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { passed &= dims_pass hash := hash.crc32(pixels) - error = fmt.tprintf("%v test %v hash is %08x, expected %08x.", file.file, count, hash, test.hash) + error = fmt.tprintf("%v test %v hash is %08x, expected %08x with %v.", file.file, count, hash, test.hash, test.options) expect(t, test.hash == hash, error) passed &= test.hash == hash From ab9457346d2eefb63a30993701377eb0ecb108ab Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 12 Apr 2022 18:26:10 +0200 Subject: [PATCH 021/245] [PNG] Remove debug printf. --- core/image/png/png.odin | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 55d69e7c7..ba888cb78 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -25,9 +25,6 @@ import "core:io" import "core:mem" import "core:intrinsics" -import "core:fmt" - - // Limit chunk sizes. // By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes. // The total number of pixels defaults to 64 Megapixel and can be tuned in image/common.odin. @@ -600,16 +597,13 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a if .Paletted in header.color_type { if len(c.data) > 256 { - fmt.printf("[PLTE] tRNS length: %v\n", len(c.data)) return img, .TNRS_Invalid_Length } } else if .Color in header.color_type { if len(c.data) != 6 { - fmt.printf("[COLOR] tRNS length: %v\n", len(c.data)) return img, .TNRS_Invalid_Length } } else if len(c.data) != 2 { - fmt.printf("[GRAY] tRNS length: %v\n", len(c.data)) return img, .TNRS_Invalid_Length } From bf712e93557cd4f05433c00bb7a61dc48621b404 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 12 Apr 2022 19:23:48 +0200 Subject: [PATCH 022/245] [QOI] Add support for RGB images (previously loader always output RGBA). Also add QOI to CI test suite by roundtripping 8-bit RGB(A) through QOI and checking the hashes match. --- core/image/qoi/qoi.odin | 29 ++++++++++++----------- tests/core/image/test_core_image.odin | 34 +++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index c157e8099..fdbaab686 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -210,11 +210,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a context.allocator = allocator options := options - if .alpha_drop_if_present in options || .alpha_premultiply in options { - // TODO: Implement. - // As stated in image/common, unimplemented options are ignored. - } - if .info in options { options |= {.return_metadata, .do_not_decompress_image} options -= {.info} @@ -258,19 +253,19 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a img.width = int(header.width) img.height = int(header.height) - img.channels = 4 + img.channels = 4 if .alpha_add_if_missing in options else int(header.channels) img.depth = 8 if .do_not_decompress_image in options { + img.channels = int(header.channels) return } - bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), 4, 8) + bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) if !resize(&img.pixels.buf, bytes_needed) { return img, mem.Allocator_Error.Out_Of_Memory } - pixels := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) /* Decode loop starts here. @@ -278,6 +273,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a seen: [64]RGBA_Pixel pix := RGBA_Pixel{0, 0, 0, 255} seen[qoi_hash(pix)] = pix + pixels := img.pixels.buf[:] decode: for len(pixels) > 0 { data := image.read_u8(ctx) or_return @@ -330,13 +326,13 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } case .RUN: - if length := int(data & 63) + 1; length > len(pixels) { + if length := int(data & 63) + 1; (length * img.channels) > len(pixels) { return img, .Corrupt } else { - #no_bounds_check for i in 0.. (subtotal: int) { passed &= dims_pass - hash := hash.crc32(pixels) - error = fmt.tprintf("%v test %v hash is %08x, expected %08x with %v.", file.file, count, hash, test.hash, test.options) - expect(t, test.hash == hash, error) + png_hash := hash.crc32(pixels) + error = fmt.tprintf("%v test %v hash is %08x, expected %08x with %v.", file.file, count, png_hash, test.hash, test.options) + expect(t, test.hash == png_hash, error) + + passed &= test.hash == png_hash + + // Roundtrip through QOI to test the QOI encoder and decoder. + if passed && img.depth == 8 && (img.channels == 3 || img.channels == 4) { + qoi_buffer: bytes.Buffer + defer bytes.buffer_destroy(&qoi_buffer) + qoi_save_err := qoi.save(&qoi_buffer, img) + + error = fmt.tprintf("%v test %v QOI save failed with %v.", file.file, count, qoi_save_err) + expect(t, qoi_save_err == nil, error) + + if qoi_save_err == nil { + qoi_img, qoi_load_err := qoi.load(qoi_buffer.buf[:]) + defer qoi.destroy(qoi_img) + + error = fmt.tprintf("%v test %v QOI load failed with %v.", file.file, count, qoi_load_err) + expect(t, qoi_load_err == nil, error) + + qoi_hash := hash.crc32(qoi_img.pixels.buf[:]) + error = fmt.tprintf("%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options) + expect(t, qoi_hash == png_hash, error) + } + } - passed &= test.hash == hash if .return_metadata in test.options { if v, ok := img.metadata.(^image.PNG_Info); ok { From 8310436350e7d2104c5b94c6f3909f9f517df502 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 13 Apr 2022 00:03:36 +0200 Subject: [PATCH 023/245] [varint] Clear up doc.odin. --- core/encoding/varint/doc.odin | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/core/encoding/varint/doc.odin b/core/encoding/varint/doc.odin index dd068b261..5e4708a59 100644 --- a/core/encoding/varint/doc.odin +++ b/core/encoding/varint/doc.odin @@ -4,24 +4,25 @@ Author of this Odin package: Jeroen van Rijn Example: - ```odin - import "core:encoding/varint" - import "core:fmt" + ```odin + import "core:encoding/varint" + import "core:fmt" - main :: proc() { - buf: [varint.LEB128_MAX_BYTES]u8 + main :: proc() { + buf: [varint.LEB128_MAX_BYTES]u8 - value := u128(42) + value := u128(42) - encode_size, encode_err := varint.encode_uleb128(buf[:], value) - assert(encode_size == 1 && encode_err == .None) + encode_size, encode_err := varint.encode_uleb128(buf[:], value) + assert(encode_size == 1 && encode_err == .None) - fmt.println(buf[:encode_size]) + fmt.printf("Encoded as %v\n", buf[:encode_size]) + decoded_val, decode_size, decode_err := varint.decode_uleb128(buf[:]) - decoded_val, decode_size, decode_err := varint.decode_uleb128(buf[:encode_size]) - assert(decoded_val == value && decode_size == encode_size && decode_err == .None) - } - ``` + assert(decoded_val == value && decode_size == encode_size && decode_err == .None) + fmt.printf("Decoded as %v, using %v byte%v\n", decoded_val, decode_size, "" if decode_size == 1 else "s") + } + ``` */ package varint \ No newline at end of file From a040be957ff3db94a1f35f73d4fc1b207ec1c526 Mon Sep 17 00:00:00 2001 From: Andrea Piseri Date: Wed, 13 Apr 2022 10:55:16 +0200 Subject: [PATCH 024/245] Fix tail recursion in `_quick_sort_general` The `if` statement should have been a `for` loop, in order to allow recursively sorting the subarrays with quicksort, and not resort to shell sort after one step. --- core/slice/sort_private.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/slice/sort_private.odin b/core/slice/sort_private.odin index 7abd2f1ce..d93d74bf9 100644 --- a/core/slice/sort_private.odin +++ b/core/slice/sort_private.odin @@ -150,7 +150,7 @@ _quick_sort_general :: proc(data: $T/[]$E, a, b, max_depth: int, call: $P, $KIND a, b, max_depth := a, b, max_depth - if b-a > 12 { // only use shell sort for lengths <= 12 + for b-a > 12 { // only use shell sort for lengths <= 12 if max_depth == 0 { heap_sort(data, a, b, call) return From 51db46551edb16eaa1396bbc3d8374dc1500154e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Apr 2022 15:03:47 +0100 Subject: [PATCH 025/245] Add MetalKit; Add NSApplication NSMenu NSMenuItem; Improve Metal classes --- vendor/darwin/Foundation/NSApplication.odin | 95 +++++++ vendor/darwin/Foundation/NSMenu.odin | 103 ++++++++ vendor/darwin/Foundation/NSNumber.odin | 6 +- vendor/darwin/Foundation/NSObject.odin | 5 +- vendor/darwin/Foundation/NSString.odin | 4 + vendor/darwin/Foundation/NSTypes.odin | 7 + vendor/darwin/Foundation/NSWindow.odin | 87 ++++++- vendor/darwin/Foundation/objc.odin | 73 ++++++ vendor/darwin/Metal/MetalClasses.odin | 14 +- vendor/darwin/MetalKit/MetalKit.odin | 259 ++++++++++++++++++++ 10 files changed, 637 insertions(+), 16 deletions(-) create mode 100644 vendor/darwin/Foundation/NSApplication.odin create mode 100644 vendor/darwin/Foundation/NSMenu.odin create mode 100644 vendor/darwin/Foundation/objc.odin create mode 100644 vendor/darwin/MetalKit/MetalKit.odin diff --git a/vendor/darwin/Foundation/NSApplication.odin b/vendor/darwin/Foundation/NSApplication.odin new file mode 100644 index 000000000..2fc4e6356 --- /dev/null +++ b/vendor/darwin/Foundation/NSApplication.odin @@ -0,0 +1,95 @@ +package objc_Foundation + +import "core:intrinsics" + +ActivationPolicy :: enum UInteger { + Regular = 0, + Accessory = 1, + Prohibited = 2, +} + +ApplicationDelegate :: struct { + willFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification), + didFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification), + shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application), + + user_data: rawptr, +} + +@(objc_class="NSApplication") +Application :: struct {using _: Object} + +@(objc_type=Application, objc_name="sharedApplication", objc_is_class_method=true) +Application_sharedApplication :: proc() -> ^Application { + return msgSend(^Application, Application, "sharedApplication") +} + +@(objc_type=Application, objc_name="setDelegate") +Application_setDelegate :: proc(self: ^Application, delegate: ^ApplicationDelegate) { + willFinishLaunching :: proc "c" (self: ^Value, _: SEL, notification: ^Notification) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->willFinishLaunching(notification) + } + didFinishLaunching :: proc "c" (self: ^Value, _: SEL, notification: ^Notification) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->didFinishLaunching(notification) + } + shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->shouldTerminateAfterLastWindowClosed(application) + } + + wrapper := Value.valueWithPointer(delegate) + + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationWillFinishLaunching:"), auto_cast willFinishLaunching, "v@:@") + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationDidFinishLaunching:"), auto_cast didFinishLaunching, "v@:@") + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationShouldTerminateAfterLastWindowClosed:"), auto_cast shouldTerminateAfterLastWindowClosed, "B@:@") + + msgSend(nil, self, "setDelegate:", wrapper) +} + +@(objc_type=Application, objc_name="setActivationPolicy") +Application_setActivationPolicy :: proc(self: ^Application, activationPolicy: ActivationPolicy) -> BOOL { + return msgSend(BOOL, self, "setActivationPolicy:", activationPolicy) +} + +@(objc_type=Application, objc_name="activateIgnoringOtherApps") +Application_activateIgnoringOtherApps :: proc(self: ^Application, ignoreOtherApps: BOOL) { + msgSend(nil, self, "activateIgnoringOtherApps:", ignoreOtherApps) +} + +@(objc_type=Application, objc_name="setMainMenu") +Application_setMainMenu :: proc(self: ^Application, menu: ^Menu) { + msgSend(nil, self, "setMainMenu:", menu) +} + +@(objc_type=Application, objc_name="windows") +Application_windows :: proc(self: ^Application) -> ^Array { + return msgSend(^Array, self, "windows") +} + +@(objc_type=Application, objc_name="run") +Application_run :: proc(self: ^Application) { + msgSend(nil, self, "run") +} + + +@(objc_type=Application, objc_name="terminate") +Application_terminate :: proc(self: ^Application, sender: ^Object) { + msgSend(nil, self, "terminate:", sender) +} + + + +@(objc_class="NSRunningApplication") +RunningApplication :: struct {using _: Object} + +@(objc_type=RunningApplication, objc_name="currentApplication", objc_is_class_method=true) +RunningApplication_currentApplication :: proc() -> ^RunningApplication { + return msgSend(^RunningApplication, RunningApplication, "currentApplication") +} + +@(objc_type=RunningApplication, objc_name="localizedName") +RunningApplication_localizedName :: proc(self: ^RunningApplication) -> ^String { + return msgSend(^String, self, "localizedName") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSMenu.odin b/vendor/darwin/Foundation/NSMenu.odin new file mode 100644 index 000000000..964e3061d --- /dev/null +++ b/vendor/darwin/Foundation/NSMenu.odin @@ -0,0 +1,103 @@ +package objc_Foundation + +import "core:builtin" +import "core:intrinsics" + +KeyEquivalentModifierFlag :: enum UInteger { + CapsLock = 16, // Set if Caps Lock key is pressed. + Shift = 17, // Set if Shift key is pressed. + Control = 18, // Set if Control key is pressed. + Option = 19, // Set if Option or Alternate key is pressed. + Command = 20, // Set if Command key is pressed. + NumericPad = 21, // Set if any key in the numeric keypad is pressed. + Help = 22, // Set if the Help key is pressed. + Function = 23, // Set if any function key is pressed. +} +KeyEquivalentModifierMask :: distinct bit_set[KeyEquivalentModifierFlag; UInteger] + +// Used to retrieve only the device-independent modifier flags, allowing applications to mask off the device-dependent modifier flags, including event coalescing information. +KeyEventModifierFlagDeviceIndependentFlagsMask := transmute(KeyEquivalentModifierMask)_KeyEventModifierFlagDeviceIndependentFlagsMask +@(private) _KeyEventModifierFlagDeviceIndependentFlagsMask := UInteger(0xffff0000) + + +MenuItemCallback :: proc "c" (unused: rawptr, name: SEL, sender: ^Object) + + +@(objc_class="NSMenuItem") +MenuItem :: struct {using _: Object} + +@(objc_type=MenuItem, objc_name="alloc", objc_is_class_method=true) +MenuItem_alloc :: proc() -> ^MenuItem { + return msgSend(^MenuItem, MenuItem, "alloc") +} +@(objc_type=MenuItem, objc_name="registerActionCallback", objc_is_class_method=true) +MenuItem_registerActionCallback :: proc(name: cstring, callback: MenuItemCallback) -> SEL { + s := string(name) + n := len(s) + sel: SEL + if n > 0 && s[n-1] != ':' { + col_name := intrinsics.alloca(n+2, 1) + builtin.copy(col_name[:n], s) + col_name[n] = ':' + col_name[n+1] = 0 + sel = sel_registerName(cstring(col_name)) + } else { + sel = sel_registerName(name) + } + if callback != nil { + class_addMethod(intrinsics.objc_find_class("NSObject"), sel, auto_cast callback, "v@:@") + } + return sel +} + +@(objc_type=MenuItem, objc_name="init") +MenuItem_init :: proc(self: ^MenuItem) -> ^MenuItem { + return msgSend(^MenuItem, self, "init") +} + +@(objc_type=MenuItem, objc_name="setKeyEquivalentModifierMask") +MenuItem_setKeyEquivalentModifierMask :: proc(self: ^MenuItem, modifierMask: KeyEquivalentModifierMask) { + msgSend(nil, self, "setKeyEquivalentModifierMask:", modifierMask) +} + +@(objc_type=MenuItem, objc_name="keyEquivalentModifierMask") +MenuItem_keyEquivalentModifierMask :: proc(self: ^MenuItem) -> KeyEquivalentModifierMask { + return msgSend(KeyEquivalentModifierMask, self, "keyEquivalentModifierMask") +} + +@(objc_type=MenuItem, objc_name="setSubmenu") +MenuItem_setSubmenu :: proc(self: ^MenuItem, submenu: ^Menu) { + msgSend(nil, self, "setSubmenu:", submenu) +} + + + + +@(objc_class="NSMenu") +Menu :: struct {using _: Object} + +@(objc_type=Menu, objc_name="alloc", objc_is_class_method=true) +Menu_alloc :: proc() -> ^Menu { + return msgSend(^Menu, Menu, "alloc") +} + +@(objc_type=Menu, objc_name="init") +Menu_init :: proc(self: ^Menu) -> ^Menu { + return msgSend(^Menu, self, "init") +} + +@(objc_type=Menu, objc_name="initWithTitle") +Menu_initWithTitle :: proc(self: ^Menu, title: ^String) -> ^Menu { + return msgSend(^Menu, self, "initWithTitle:", title) +} + + +@(objc_type=Menu, objc_name="addItem") +Menu_addItem :: proc(self: ^Menu, item: ^MenuItem) { + msgSend(nil, self, "addItem:", item) +} + +@(objc_type=Menu, objc_name="addItemWithTitle") +Menu_addItemWithTitle :: proc(self: ^Menu, title: ^String, selector: SEL, keyEquivalent: ^String) -> ^MenuItem { + return msgSend(^MenuItem, self, "addItemWithTitle:action:keyEquivalent:", title, selector, keyEquivalent) +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSNumber.odin b/vendor/darwin/Foundation/NSNumber.odin index 9201557a3..d459e673f 100644 --- a/vendor/darwin/Foundation/NSNumber.odin +++ b/vendor/darwin/Foundation/NSNumber.odin @@ -48,17 +48,17 @@ Value_getValue :: proc(self: ^Value, value: rawptr, size: UInteger) { @(objc_type=Value, objc_name="objCType") -Value_objCType :: proc(self: ^Value) -> cstring { +Value_objCType :: proc "c" (self: ^Value) -> cstring { return msgSend(cstring, self, "objCType") } @(objc_type=Value, objc_name="isEqualToValue") -Value_isEqualToValue :: proc(self, other: ^Value) -> BOOL { +Value_isEqualToValue :: proc "c" (self, other: ^Value) -> BOOL { return msgSend(BOOL, self, "isEqualToValue:", other) } @(objc_type=Value, objc_name="pointerValue") -Value_pointerValue :: proc(self: ^Value) -> rawptr { +Value_pointerValue :: proc "c" (self: ^Value) -> rawptr { return msgSend(rawptr, self, "pointerValue") } diff --git a/vendor/darwin/Foundation/NSObject.odin b/vendor/darwin/Foundation/NSObject.odin index 1ce17f2f5..6ec5939ee 100644 --- a/vendor/darwin/Foundation/NSObject.odin +++ b/vendor/darwin/Foundation/NSObject.odin @@ -53,7 +53,10 @@ autorelease :: proc(self: ^Object) { retainCount :: proc(self: ^Object) -> UInteger { return msgSend(UInteger, self, "retainCount") } - +@(objc_type=Object, objc_name="class") +class :: proc(self: ^Object) -> Class { + return msgSend(Class, self, "class") +} @(objc_type=Object, objc_name="hash") hash :: proc(self: ^Object) -> UInteger { diff --git a/vendor/darwin/Foundation/NSString.odin b/vendor/darwin/Foundation/NSString.odin index 45b5df37b..18e392415 100644 --- a/vendor/darwin/Foundation/NSString.odin +++ b/vendor/darwin/Foundation/NSString.odin @@ -49,6 +49,10 @@ StringCompareOption :: enum UInteger { unichar :: distinct u16 +@(link_prefix="NS", default_calling_convention="c") +foreign Foundation { + StringFromClass :: proc(cls: Class) -> ^String --- +} AT :: MakeConstantString MakeConstantString :: proc "c" (#const c: cstring) -> ^String { diff --git a/vendor/darwin/Foundation/NSTypes.odin b/vendor/darwin/Foundation/NSTypes.odin index 47f75630f..ef895d449 100644 --- a/vendor/darwin/Foundation/NSTypes.odin +++ b/vendor/darwin/Foundation/NSTypes.odin @@ -33,3 +33,10 @@ ComparisonResult :: enum Integer { } NotFound :: IntegerMax + +Float :: distinct (f32 when size_of(uint) == 4 else f64) + +Size :: struct { + width: Float, + height: Float, +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSWindow.odin b/vendor/darwin/Foundation/NSWindow.odin index dec5a160c..3c7c17023 100644 --- a/vendor/darwin/Foundation/NSWindow.odin +++ b/vendor/darwin/Foundation/NSWindow.odin @@ -7,18 +7,75 @@ Rect :: struct { width, height: f64, } +WindowStyleFlag :: enum NS.UInteger { + Titled = 0, + Closable = 1, + Miniaturizable = 2, + Resizable = 3, + TexturedBackground = 8, + UnifiedTitleAndToolbar = 12, + FullScreen = 14, + FullSizeContentView = 15, + UtilityWindow = 4, + DocModalWindow = 6, + NonactivatingPanel = 7, + HUDWindow = 13, +} +WindowStyleMask :: distinct bit_set[WindowStyleFlag; NS.UInteger] +WindowStyleMaskBorderless :: WindowStyleMask{} +WindowStyleMaskTitled :: WindowStyleMask{.Titled} +WindowStyleMaskClosable :: WindowStyleMask{.Closable} +WindowStyleMaskMiniaturizable :: WindowStyleMask{.Miniaturizable} +WindowStyleMaskResizable :: WindowStyleMask{.Resizable} +WindowStyleMaskTexturedBackground :: WindowStyleMask{.TexturedBackground} +WindowStyleMaskUnifiedTitleAndToolbar :: WindowStyleMask{.UnifiedTitleAndToolbar} +WindowStyleMaskFullScreen :: WindowStyleMask{.FullScreen} +WindowStyleMaskFullSizeContentView :: WindowStyleMask{.FullSizeContentView} +WindowStyleMaskUtilityWindow :: WindowStyleMask{.UtilityWindow} +WindowStyleMaskDocModalWindow :: WindowStyleMask{.DocModalWindow} +WindowStyleMaskNonactivatingPanel :: WindowStyleMask{.NonactivatingPanel} +WindowStyleMaskHUDWindow :: WindowStyleMask{.HUDWindow} + +BackingStoreType :: enum NS.UInteger { + Retained = 0, + Nonretained = 1, + Buffered = 2, +} + @(objc_class="NSColor") Color :: struct {using _: Object} @(objc_class="CALayer") Layer :: struct { using _: NS.Object } +@(objc_type=Layer, objc_name="contentsScale") +Layer_contentsScale :: proc(self: ^Layer) -> Float { + return msgSend(Float, self, "contentsScale") +} +@(objc_type=Layer, objc_name="setContentsScale") +Layer_setContentsScale :: proc(self: ^Layer, scale: Float) { + msgSend(nil, self, "setContentsScale:", scale) +} +@(objc_type=Layer, objc_name="frame") +Layer_frame :: proc(self: ^Layer) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Layer, objc_name="addSublayer") +Layer_addSublayer :: proc(self: ^Layer, layer: ^Layer) { + msgSend(nil, self, "addSublayer:", layer) +} + @(objc_class="NSResponder") Responder :: struct {using _: Object} @(objc_class="NSView") View :: struct {using _: Responder} + +@(objc_type=View, objc_name="initWithFrame") +View_initWithFrame :: proc(self: ^View, frame: Rect) -> ^View { + return msgSend(^View, self, "initWithFrame:", frame) +} @(objc_type=View, objc_name="layer") View_layer :: proc(self: ^View) -> ^Layer { return msgSend(^Layer, self, "layer") @@ -27,10 +84,6 @@ View_layer :: proc(self: ^View) -> ^Layer { View_setLayer :: proc(self: ^View, layer: ^Layer) { msgSend(nil, self, "setLayer:", layer) } -@(objc_type=View, objc_name="setSubLayer") -View_setSubLayer :: proc(self: ^View, layer: ^Layer) { - msgSend(nil, self, "setSubLayer:", layer) -} @(objc_type=View, objc_name="wantsLayer") View_wantsLayer :: proc(self: ^View) -> BOOL { return msgSend(BOOL, self, "wantsLayer") @@ -40,14 +93,26 @@ View_setWantsLayer :: proc(self: ^View, wantsLayer: BOOL) { msgSend(nil, self, "setWantsLayer:", wantsLayer) } - @(objc_class="NSWindow") Window :: struct {using _: Responder} +@(objc_type=Window, objc_name="alloc", objc_is_class_method=true) +Window_alloc :: proc() -> ^Window { + return msgSend(^Window, Window, "alloc") +} + +@(objc_type=Window, objc_name="initWithContentRect") +Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: bool) -> ^Window { + return msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", contentRect, styleMask, backing, doDefer) +} @(objc_type=Window, objc_name="contentView") Window_contentView :: proc(self: ^Window) -> ^View { return msgSend(^View, self, "contentView") } +@(objc_type=Window, objc_name="setContentView") +Window_setContentView :: proc(self: ^Window, content_view: ^View) { + msgSend(nil, self, "setContentView:", content_view) +} @(objc_type=Window, objc_name="frame") Window_frame :: proc(self: ^Window) -> Rect { return msgSend(Rect, self, "frame") @@ -72,3 +137,15 @@ Window_backgroundColor :: proc(self: ^Window) -> ^NS.Color { Window_setBackgroundColor :: proc(self: ^Window, color: ^NS.Color) { msgSend(nil, self, "setBackgroundColor:", color) } +@(objc_type=Window, objc_name="makeKeyAndOrderFront") +Window_makeKeyAndOrderFront :: proc(self: ^Window, key: ^NS.Object) { + msgSend(nil, self, "makeKeyAndOrderFront:", key) +} +@(objc_type=Window, objc_name="setTitle") +Window_setTitle :: proc(self: ^Window, title: ^NS.String) { + msgSend(nil, self, "setTitle:", title) +} +@(objc_type=Window, objc_name="close") +Window_close :: proc(self: ^Window) { + msgSend(nil, self, "close") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/objc.odin b/vendor/darwin/Foundation/objc.odin new file mode 100644 index 000000000..7db82df73 --- /dev/null +++ b/vendor/darwin/Foundation/objc.odin @@ -0,0 +1,73 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +import "core:intrinsics" +import "core:c" + +IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id + +foreign Foundation { + objc_lookUpClass :: proc "c" (name: cstring) -> Class --- + sel_registerName :: proc "c" (name: cstring) -> SEL --- + objc_allocateClassPair :: proc "c" (superclass: Class, name: cstring, extraBytes: uint) --- + + class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL --- +} + + +@(objc_class="NSZone") +Zone :: struct {using _: Object} + +@(link_prefix="NS") +foreign Foundation { + AllocateObject :: proc "c" (aClass: Class, extraBytes: UInteger, zone: ^Zone) -> id --- + DeallocateObject :: proc "c" (object: id) --- +} + +Method :: ^objc_method +objc_method :: struct { + method_name: SEL, + method_types: cstring, + method_imp: IMP, +} +objc_method_list :: struct {} + +objc_ivar :: struct {} +objc_ivar_list :: struct {} + +objc_cache :: struct { + mask: u32, + occupied: u32, + buckets: [1]Method, +} + +objc_protocol_list :: struct { + next: ^objc_protocol_list, + count: c.int, + list: [1]^Protocol, +} + +@(objc_class="Protocol") +Protocol :: struct{using _: intrinsics.objc_object} + +objc_object_internals :: struct { + isa: ^objc_class_internals, +} + + +objc_class_internals :: struct { + isa: Class, + super_class: Class, + name: cstring, + version: c.long, + info: c.long, + instance_size: c.long, + ivars: ^objc_ivar_list, + + methodLists: ^^objc_method_list, + + cache: rawptr, + protocols: rawptr, + +} \ No newline at end of file diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 56d40f5f2..29653f015 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -4474,16 +4474,16 @@ TextureDescriptor_storageMode :: #force_inline proc(self: ^TextureDescriptor) -> TextureDescriptor_swizzle :: #force_inline proc(self: ^TextureDescriptor) -> TextureSwizzleChannels { return msgSend(TextureSwizzleChannels, self, "swizzle") } -@(objc_type=TextureDescriptor, objc_name="texture2DDescriptor", objc_is_class_method=true) -TextureDescriptor_texture2DDescriptor :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, height: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { +@(objc_type=TextureDescriptor, objc_name="texture2DDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_texture2DDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, height: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "texture2DDescriptorWithPixelFormat:width:height:mipmapped:", pixelFormat, width, height, mipmapped) } -@(objc_type=TextureDescriptor, objc_name="textureBufferDescriptor", objc_is_class_method=true) -TextureDescriptor_textureBufferDescriptor :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, resourceOptions: ResourceOptions, usage: TextureUsage) -> ^TextureDescriptor { +@(objc_type=TextureDescriptor, objc_name="textureBufferDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_textureBufferDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, resourceOptions: ResourceOptions, usage: TextureUsage) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "textureBufferDescriptorWithPixelFormat:width:resourceOptions:usage:", pixelFormat, width, resourceOptions, usage) } -@(objc_type=TextureDescriptor, objc_name="textureCubeDescriptor", objc_is_class_method=true) -TextureDescriptor_textureCubeDescriptor :: #force_inline proc(pixelFormat: PixelFormat, size: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { +@(objc_type=TextureDescriptor, objc_name="textureCubeDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_textureCubeDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, size: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { return msgSend(^TextureDescriptor, TextureDescriptor, "textureCubeDescriptorWithPixelFormat:size:mipmapped:", pixelFormat, size, mipmapped) } @(objc_type=TextureDescriptor, objc_name="textureType") @@ -7683,7 +7683,7 @@ RenderCommandEncoder_drawPrimitivesWithInstanceCount :: #force_inline proc(self: msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:instanceCount:", primitiveType, vertexStart, vertexCount, instanceCount) } @(objc_type=RenderCommandEncoder, objc_name="drawPrimitivesWithInstances") -RenderCommandEncoder_drawPrimitivesWithInstance :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger) { +RenderCommandEncoder_drawPrimitivesWithInstances :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger) { msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:instanceCount:baseInstance:", primitiveType, vertexStart, vertexCount, instanceCount, baseInstance) } @(objc_type=RenderCommandEncoder, objc_name="executeCommandsInBuffer") diff --git a/vendor/darwin/MetalKit/MetalKit.odin b/vendor/darwin/MetalKit/MetalKit.odin new file mode 100644 index 000000000..90d147983 --- /dev/null +++ b/vendor/darwin/MetalKit/MetalKit.odin @@ -0,0 +1,259 @@ +package objc_MetalKit + +import NS "vendor:darwin/Foundation" +import MTL "vendor:darwin/Metal" +import CA "vendor:darwin/QuartzCore" +import "core:intrinsics" + +@(require) +foreign import "system:MetalKit.framework" + +@(private) +msgSend :: intrinsics.objc_send + +ColorSpaceRef :: struct {} + +ViewDelegate :: struct { + drawInMTKView: proc "c" (self: ^ViewDelegate, view: ^View), + drawableSizeWillChange: proc "c" (self: ^ViewDelegate, view: ^View, size: NS.Size), + + user_data: rawptr, +} + +@(objc_class="MTKView") +View :: struct {using _: NS.View} + +@(objc_type=View, objc_name="alloc", objc_is_class_method=true) +View_alloc :: proc() -> ^View { + return msgSend(^View, View, "alloc") +} +@(objc_type=View, objc_name="initWithFrame") +View_initWithFrame :: proc(self: ^View, frame: NS.Rect, device: ^MTL.Device) -> ^View { + return msgSend(^View, self, "initWithFrame:device:", frame, device) +} +@(objc_type=View, objc_name="initWithCoder") +View_initWithCoder :: proc(self: ^View, coder: ^NS.Coder) -> ^View { + return msgSend(^View, self, "initWithCoder:", coder) +} + +@(objc_type=View, objc_name="setDevice") +View_setDevice :: proc(self: ^View, device: ^MTL.Device) { + msgSend(nil, self, "setDevice:", device) +} +@(objc_type=View, objc_name="device") +View_device :: proc(self: ^View) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "device") +} + +@(objc_type=View, objc_name="draw") +View_draw :: proc(self: ^View) { + msgSend(nil, self, "draw") +} + +@(objc_type=View, objc_name="setDelegate") +View_setDelegate :: proc(self: ^View, delegate: ^ViewDelegate) { + drawDispatch :: proc "c" (self: ^NS.Value, cmd: NS.SEL, view: ^View) { + del := (^ViewDelegate)(self->pointerValue()) + del->drawInMTKView(view) + } + drawableSizeWillChange :: proc "c" (self: ^NS.Value, cmd: NS.SEL, view: ^View, size: NS.Size) { + del := (^ViewDelegate)(self->pointerValue()) + del->drawableSizeWillChange(view, size) + } + + wrapper := NS.Value.valueWithPointer(delegate) + + NS.class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("drawInMTKView:"), auto_cast drawDispatch, "v@:@") + + cbparams :: "v@:@{CGSize=ff}" when size_of(NS.Float) == size_of(f32) else "v@:@{CGSize=dd}" + NS.class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("mtkView:drawableSizeWillChange:"), auto_cast drawableSizeWillChange, cbparams) + + msgSend(nil, self, "setDelegate:", wrapper) +} + +@(objc_type=View, objc_name="delegate") +View_delegate :: proc(self: ^View) -> ^ViewDelegate { + wrapper := msgSend(^NS.Value, self, "delegate") + if wrapper != nil { + return (^ViewDelegate)(wrapper->pointerValue()) + } + return nil +} + +@(objc_type=View, objc_name="currentDrawable") +View_currentDrawable :: proc(self: ^View) -> ^CA.MetalDrawable { + return msgSend(^CA.MetalDrawable, self, "currentDrawable") +} + +@(objc_type=View, objc_name="setFramebufferOnly") +View_setFramebufferOnly :: proc(self: ^View, framebufferOnly: bool) { + msgSend(nil, self, "setFramebufferOnly:", framebufferOnly) +} +@(objc_type=View, objc_name="framebufferOnly") +View_framebufferOnly :: proc(self: ^View) -> bool { + return msgSend(bool, self, "framebufferOnly") +} + +@(objc_type=View, objc_name="setDepthStencilAttachmentTextureUsage") +View_setDepthStencilAttachmentTextureUsage :: proc(self: ^View, textureUsage: MTL.TextureUsage) { + msgSend(nil, self, "setDepthStencilAttachmentTextureUsage:", textureUsage) +} +@(objc_type=View, objc_name="depthStencilAttachmentTextureUsage") +View_depthStencilAttachmentTextureUsage :: proc(self: ^View) -> MTL.TextureUsage { + return msgSend(MTL.TextureUsage, self, "depthStencilAttachmentTextureUsage") +} + +@(objc_type=View, objc_name="setMultisampleColorAttachmentTextureUsage") +View_setMultisampleColorAttachmentTextureUsage :: proc(self: ^View, textureUsage: MTL.TextureUsage) { + msgSend(nil, self, "setMultisampleColorAttachmentTextureUsage:", textureUsage) +} +@(objc_type=View, objc_name="multisampleColorAttachmentTextureUsage") +View_multisampleColorAttachmentTextureUsage :: proc(self: ^View) -> MTL.TextureUsage { + return msgSend(MTL.TextureUsage, self, "multisampleColorAttachmentTextureUsage") +} + +@(objc_type=View, objc_name="setPresentsWithTransaction") +View_setPresentsWithTransaction :: proc(self: ^View, presentsWithTransaction: bool) { + msgSend(nil, self, "setPresentsWithTransaction:", presentsWithTransaction) +} +@(objc_type=View, objc_name="presentsWithTransaction") +View_presentsWithTransaction :: proc(self: ^View) -> bool { + return msgSend(bool, self, "presentsWithTransaction") +} + +@(objc_type=View, objc_name="setColorPixelFormat") +View_setColorPixelFormat :: proc(self: ^View, colorPixelFormat: MTL.PixelFormat) { + msgSend(nil, self, "setColorPixelFormat:", colorPixelFormat) +} +@(objc_type=View, objc_name="colorPixelFormat") +View_colorPixelFormat :: proc(self: ^View) -> MTL.PixelFormat { + return msgSend(MTL.PixelFormat, self, "colorPixelFormat") +} + +@(objc_type=View, objc_name="setDepthStencilPixelFormat") +View_setDepthStencilPixelFormat :: proc(self: ^View, colorPixelFormat: MTL.PixelFormat) { + msgSend(nil, self, "setDepthStencilPixelFormat:", colorPixelFormat) +} +@(objc_type=View, objc_name="depthStencilPixelFormat") +View_depthStencilPixelFormat :: proc(self: ^View) -> MTL.PixelFormat { + return msgSend(MTL.PixelFormat, self, "depthStencilPixelFormat") +} + +@(objc_type=View, objc_name="setSampleCount") +View_setSampleCount :: proc(self: ^View, sampleCount: NS.UInteger) { + msgSend(nil, self, "setSampleCount:", sampleCount) +} +@(objc_type=View, objc_name="sampleCount") +View_sampleCount :: proc(self: ^View) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} + +@(objc_type=View, objc_name="setClearColor") +View_setClearColor :: proc(self: ^View, clearColor: MTL.ClearColor) { + msgSend(nil, self, "setClearColor:", clearColor) +} +@(objc_type=View, objc_name="clearColor") +View_clearColor :: proc(self: ^View) -> MTL.ClearColor { + return msgSend(MTL.ClearColor, self, "clearColor") +} + +@(objc_type=View, objc_name="setClearDepth") +View_setClearDepth :: proc(self: ^View, clearDepth: f64) { + msgSend(nil, self, "setClearDepth:", clearDepth) +} +@(objc_type=View, objc_name="clearDepth") +View_clearDepth :: proc(self: ^View) -> f64 { + return msgSend(f64, self, "clearDepth") +} + +@(objc_type=View, objc_name="setClearStencil") +View_setClearStencil :: proc(self: ^View, clearStencil: u32) { + msgSend(nil, self, "setClearStencil:", clearStencil) +} +@(objc_type=View, objc_name="clearStencil") +View_clearStencil :: proc(self: ^View) -> u32 { + return msgSend(u32, self, "clearStencil") +} + +@(objc_type=View, objc_name="depthStencilTexture") +View_depthStencilTexture :: proc(self: ^View) -> ^MTL.Texture { + return msgSend(^MTL.Texture, self, "depthStencilTexture") +} +@(objc_type=View, objc_name="multisampleColorTexture") +View_multisampleColorTexture :: proc(self: ^View) -> ^MTL.Texture { + return msgSend(^MTL.Texture, self, "multisampleColorTexture") +} + +@(objc_type=View, objc_name="releaseDrawables") +View_releaseDrawables :: proc(self: ^View) { + msgSend(nil, self, "releaseDrawables") +} + +@(objc_type=View, objc_name="currentRenderPassDescriptor") +View_currentRenderPassDescriptor :: proc(self: ^View) -> ^MTL.RenderPassDescriptor { + return msgSend(^MTL.RenderPassDescriptor, self, "currentRenderPassDescriptor") +} + +@(objc_type=View, objc_name="setPreferredFramesPerSecond") +View_setPreferredFramesPerSecond :: proc(self: ^View, preferredFramesPerSecond: NS.Integer) { + msgSend(nil, self, "setPreferredFramesPerSecond:", preferredFramesPerSecond) +} +@(objc_type=View, objc_name="preferredFramesPerSecond") +View_preferredFramesPerSecond :: proc(self: ^View) -> NS.Integer { + return msgSend(NS.Integer, self, "preferredFramesPerSecond") +} + +@(objc_type=View, objc_name="setEnableSetNeedsDisplay") +View_setEnableSetNeedsDisplay :: proc(self: ^View, enableSetNeedsDisplay: bool) { + msgSend(nil, self, "setEnableSetNeedsDisplay:", enableSetNeedsDisplay) +} +@(objc_type=View, objc_name="enableSetNeedsDisplay") +View_enableSetNeedsDisplay :: proc(self: ^View) -> bool { + return msgSend(bool, self, "enableSetNeedsDisplay") +} + +@(objc_type=View, objc_name="setAutoresizeDrawable") +View_setAutoresizeDrawable :: proc(self: ^View, autoresizeDrawable: bool) { + msgSend(nil, self, "setAutoresizeDrawable:", autoresizeDrawable) +} +@(objc_type=View, objc_name="autoresizeDrawable") +View_autoresizeDrawable :: proc(self: ^View) -> bool { + return msgSend(bool, self, "autoresizeDrawable") +} + +@(objc_type=View, objc_name="setDrawableSize") +View_setDrawableSize :: proc(self: ^View, drawableSize: NS.Size) { + msgSend(nil, self, "setDrawableSize:", drawableSize) +} +@(objc_type=View, objc_name="drawableSize") +View_drawableSize :: proc(self: ^View) -> NS.Size { + return msgSend(NS.Size, self, "drawableSize") +} + +@(objc_type=View, objc_name="preferredDrawableSize") +View_preferredDrawableSize :: proc(self: ^View) -> NS.Size { + return msgSend(NS.Size, self, "preferredDrawableSize") +} + +@(objc_type=View, objc_name="preferredDevice") +View_preferredDevice :: proc(self: ^View) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "preferredDevice") +} + +@(objc_type=View, objc_name="setPaused") +View_setPaused :: proc(self: ^View, isPaused: bool) { + msgSend(nil, self, "setPaused:", isPaused) +} +@(objc_type=View, objc_name="isPaused") +View_isPaused :: proc(self: ^View) -> bool { + return msgSend(bool, self, "isPaused") +} + +@(objc_type=View, objc_name="setColorSpace") +View_setColorSpace :: proc(self: ^View, colorSpace: ColorSpaceRef) { + msgSend(nil, self, "setColorSpace:", colorSpace) +} +@(objc_type=View, objc_name="colorSpace") +View_colorSpace :: proc(self: ^View) -> ColorSpaceRef { + return msgSend(ColorSpaceRef, self, "colorSpace") +} From 8a9f7fc684b39c803cab184344a8a017308ed63a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Apr 2022 15:09:03 +0100 Subject: [PATCH 026/245] Fix #1713 --- src/check_expr.cpp | 5 ++++- src/exact_value.cpp | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index dcf17af39..336a711d4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -8161,7 +8161,10 @@ ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type * case Type_Basic: { if (!is_type_any(t)) { if (cl->elems.count != 0) { - error(node, "Illegal compound literal"); + gbString s = type_to_string(t); + error(node, "Illegal compound literal, %s cannot be used as a compound literal with fields", s); + gb_string_free(s); + is_constant = false; } break; } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index f6df48951..cedef48c4 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -591,6 +591,7 @@ failure: i32 exact_value_order(ExactValue const &v) { switch (v.kind) { case ExactValue_Invalid: + case ExactValue_Compound: return 0; case ExactValue_Bool: case ExactValue_String: @@ -607,8 +608,6 @@ i32 exact_value_order(ExactValue const &v) { return 6; case ExactValue_Procedure: return 7; - // case ExactValue_Compound: - // return 8; default: GB_PANIC("How'd you get here? Invalid Value.kind %d", v.kind); From e53c85885559144f3273cfa13a10c6531787d173 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Apr 2022 15:47:49 +0100 Subject: [PATCH 027/245] Add NS.Block to allow for the creation of block-like lambdas in Odin --- vendor/darwin/Foundation/block_literal.odin | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 vendor/darwin/Foundation/block_literal.odin diff --git a/vendor/darwin/Foundation/block_literal.odin b/vendor/darwin/Foundation/block_literal.odin new file mode 100644 index 000000000..19e9782e4 --- /dev/null +++ b/vendor/darwin/Foundation/block_literal.odin @@ -0,0 +1,67 @@ +package objc_Foundation + +import "core:intrinsics" + +Internal_Block_Literal_Base :: struct { + isa: ^intrinsics.objc_class, + flags: u32, + reserved: u32, + invoke: proc "c" (^Internal_Block_Literal), + descriptor: ^Block_Descriptor, +} + +Internal_Block_Literal :: struct { + using base: Internal_Block_Literal_Base, + // Imported Variables + user_proc: proc "c" (user_data: rawptr), + user_data: rawptr, +} + +Block_Descriptor :: struct { + reserved: uint, + size: uint, + copy_helper: proc "c" (dst, src: rawptr), + dispose_helper: proc "c" (src: rawptr), + signature: cstring, +} + +global_block_descriptor := Block_Descriptor{ + reserved = 0, + size = size_of(Internal_Block_Literal), +} + + +@(objc_class="NSConcreteGlobalBlock") +Block :: struct {using _: Object} + +@(objc_type=Block, objc_name="create", objc_is_class_method=true) +Block_create :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + // Set to true on blocks that have captures (and thus are not true + // global blocks) but are known not to escape for various other + // reasons. For backward compatibility with old runtimes, whenever + // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a + // non-escaping block returns the original block and releasing such a + // block is a no-op, which is exactly how global blocks are handled. + BLOCK_IS_NOESCAPE :: (1 << 23)|BLOCK_IS_GLOBAL + + BLOCK_HAS_COPY_DISPOSE :: 1 << 25 + BLOCK_HAS_CTOR :: 1 << 26 // helpers have C++ code + BLOCK_IS_GLOBAL :: 1 << 28 + BLOCK_HAS_STRET :: 1 << 29 // IFF BLOCK_HAS_SIGNATURE + BLOCK_HAS_SIGNATURE :: 1 << 30 + + extraBytes :: size_of(Internal_Block_Literal) - size_of(Internal_Block_Literal_Base) + + cls := intrinsics.objc_find_class("NSConcreteGlobalBlock") + bl := (^Internal_Block_Literal)(AllocateObject(cls, extraBytes, nil)) + bl.isa = cls + bl.flags = BLOCK_IS_GLOBAL + bl.invoke = proc "c" (bl: ^Internal_Block_Literal) { + bl.user_proc(bl.user_data) + } + bl.descriptor = &global_block_descriptor + bl.user_proc = user_proc + bl.user_data = user_data + + return auto_cast bl +} From 0d621511e582ccba60cb9c7c0d59fcfc88d4f9c4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Apr 2022 16:16:53 +0100 Subject: [PATCH 028/245] Correct signature types --- vendor/darwin/Metal/MetalClasses.odin | 28 +++++++++++++-------------- vendor/darwin/Metal/MetalTypes.odin | 16 +++++++-------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 29653f015..f91d5f112 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -6490,35 +6490,35 @@ Device_newCommandQueueWithMaxCommandBufferCount :: #force_inline proc(self: ^Dev return msgSend(^CommandQueue, self, "newCommandQueueWithMaxCommandBufferCount:", maxCommandBufferCount) } @(objc_type=Device, objc_name="newComputePipelineStateWithDescriptorWithCompletionHandler") -Device_newComputePipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) { - msgSend(nil, self, "newComputePipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler) +Device_newComputePipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) -> ^ComputePipelineState { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler) } @(objc_type=Device, objc_name="newComputePipelineStateWithDescriptorWithReflection") -Device_newComputePipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (device: ^Device, error: ^NS.Error) { - device = msgSend(^Device, self, "newComputePipelineStateWithDescriptor:options:reflection:error:", descriptor, options, reflection, &error) +Device_newComputePipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithDescriptor:options:reflection:error:", descriptor, options, reflection, &error) return } @(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithCompletionHandler") -Device_newComputePipelineStateWithFunctionWithCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, completionHandler: NewComputePipelineStateCompletionHandler) { - msgSend(nil, self, "newComputePipelineStateWithFunction:completionHandler:", computeFunction, completionHandler) +Device_newComputePipelineStateWithFunctionWithCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, completionHandler: NewComputePipelineStateCompletionHandler) -> ^ComputePipelineState { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:completionHandler:", computeFunction, completionHandler) } @(objc_type=Device, objc_name="newComputePipelineStateWithFunction") -Device_newComputePipelineStateWithFunction :: #force_inline proc(self: ^Device, computeFunction: ^Function) -> (res: ^Device, error: ^NS.Error) { - res = msgSend(^Device, self, "newComputePipelineStateWithFunction:error:", computeFunction, &error) +Device_newComputePipelineStateWithFunction :: #force_inline proc(self: ^Device, computeFunction: ^Function) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:error:", computeFunction, &error) return } @(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler") -Device_newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) { - msgSend(nil, self, "newComputePipelineStateWithFunction:options:completionHandler:", computeFunction, options, completionHandler) +Device_newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) -> (res: ^ComputePipelineState) { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:options:completionHandler:", computeFunction, options, completionHandler) } @(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithReflection") -Device_newComputePipelineStateWithFunctionWithReflection :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (device: ^Device, error: ^NS.Error) { - device = msgSend(^Device, self, "newComputePipelineStateWithFunction:options:reflection:error:", computeFunction, options, reflection, &error) +Device_newComputePipelineStateWithFunctionWithReflection :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:options:reflection:error:", computeFunction, options, reflection, &error) return } @(objc_type=Device, objc_name="newCounterSampleBuffer") -Device_newCounterSampleBuffer :: #force_inline proc(self: ^Device, descriptor: ^CounterSampleBufferDescriptor) -> (device: ^Device, error: ^NS.Error) { - device = msgSend(^Device, self, "newCounterSampleBufferWithDescriptor:error:", descriptor, &error) +Device_newCounterSampleBuffer :: #force_inline proc(self: ^Device, descriptor: ^CounterSampleBufferDescriptor) -> (counter: ^Counter, error: ^NS.Error) { + counter = msgSend(^Counter, self, "newCounterSampleBufferWithDescriptor:error:", descriptor, &error) return } @(objc_type=Device, objc_name="newDefaultLibrary") diff --git a/vendor/darwin/Metal/MetalTypes.odin b/vendor/darwin/Metal/MetalTypes.odin index 673769c09..cc9d25ca0 100644 --- a/vendor/darwin/Metal/MetalTypes.odin +++ b/vendor/darwin/Metal/MetalTypes.odin @@ -184,16 +184,16 @@ Viewport :: struct { Timestamp :: distinct u64 -DeviceNotificationHandler :: distinct rawptr +DeviceNotificationHandler :: ^NS.Block AutoreleasedComputePipelineReflection :: ^ComputePipelineReflection AutoreleasedRenderPipelineReflection :: ^RenderPipelineReflection -NewLibraryCompletionHandler :: distinct rawptr -NewRenderPipelineStateCompletionHandler :: distinct rawptr -NewRenderPipelineStateWithReflectionCompletionHandler :: distinct rawptr -NewComputePipelineStateCompletionHandler :: distinct rawptr -NewComputePipelineStateWithReflectionCompletionHandler :: distinct rawptr -SharedEventNotificationBlock :: distinct rawptr +NewLibraryCompletionHandler :: ^NS.Block +NewRenderPipelineStateCompletionHandler :: ^NS.Block +NewRenderPipelineStateWithReflectionCompletionHandler :: ^NS.Block +NewComputePipelineStateCompletionHandler :: ^NS.Block +NewComputePipelineStateWithReflectionCompletionHandler :: ^NS.Block +SharedEventNotificationBlock :: ^NS.Block -DrawablePresentedHandler :: distinct rawptr +DrawablePresentedHandler :: ^NS.Block AutoreleasedArgument :: ^Argument \ No newline at end of file From ea0b02d9b95fd445f94ff96d94fae78332aa701c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Apr 2022 16:42:24 +0100 Subject: [PATCH 029/245] Add Buffer contentsAsSlice and contentsAsType --- vendor/darwin/Metal/MetalClasses.odin | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index f91d5f112..38a7267b9 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -5495,6 +5495,17 @@ Buffer_contents :: #force_inline proc(self: ^Buffer) -> []byte { Buffer_contentsPointer :: #force_inline proc(self: ^Buffer) -> rawptr { return msgSend(rawptr, self, "contents") } +@(objc_type=Buffer, objc_name="contentsAsSlice") +Buffer_contentsAsSlice :: #force_inline proc(self: ^Buffer, $T: typeid/[]$E) -> T { + contents := msgSend([^]byte, self, "contents") + length := Buffer_length(self) + return mem.slice_data_cast(T, contents[:length]) +} +@(objc_type=Buffer, objc_name="contentsAsType") +Buffer_contentsAsType :: #force_inline proc(self: ^Buffer, $T: typeid, offset: uintptr = 0) -> ^T { + ptr := msgSend(rawptr, self, "contents") + return (^T)(uintptr(ptr) + offset) +} @(objc_type=Buffer, objc_name="didModifyRange") Buffer_didModifyRange :: #force_inline proc(self: ^Buffer, range: NS.Range) { msgSend(nil, self, "didModifyRange:", range) From 9a2d9002e6de463fb6809d89d91b5b9959b748d1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 15 Apr 2022 11:14:59 +0100 Subject: [PATCH 030/245] Minor fixes and add use of proc groups where better suited --- vendor/darwin/Metal/MetalClasses.odin | 44 +++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 38a7267b9..c039510c6 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -6442,12 +6442,12 @@ Device_maxTransferRate :: #force_inline proc(self: ^Device) -> u64 { return msgSend(u64, self, "maxTransferRate") } @(objc_type=Device, objc_name="minimumLinearTextureAlignmentForPixelFormat") -Device_minimumLinearTextureAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> ^Device { - return msgSend(^Device, self, "minimumLinearTextureAlignmentForPixelFormat:", format) +Device_minimumLinearTextureAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> NS.UInteger { + return msgSend(NS.UInteger, self, "minimumLinearTextureAlignmentForPixelFormat:", format) } @(objc_type=Device, objc_name="minimumTextureBufferAlignmentForPixelFormat") -Device_minimumTextureBufferAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> ^Device { - return msgSend(^Device, self, "minimumTextureBufferAlignmentForPixelFormat:", format) +Device_minimumTextureBufferAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> NS.UInteger { + return msgSend(NS.UInteger, self, "minimumTextureBufferAlignmentForPixelFormat:", format) } @(objc_type=Device, objc_name="name") Device_name :: #force_inline proc(self: ^Device) -> ^NS.String { @@ -6527,6 +6527,17 @@ Device_newComputePipelineStateWithFunctionWithReflection :: #force_inline proc(s res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:options:reflection:error:", computeFunction, options, reflection, &error) return } + +@(objc_type=Device, objc_name="newComputePipelineState") +Device_newComputePipelineState :: proc{ + Device_newComputePipelineStateWithDescriptorWithCompletionHandler, + Device_newComputePipelineStateWithDescriptorWithReflection, + Device_newComputePipelineStateWithFunctionWithCompletionHandler, + Device_newComputePipelineStateWithFunction, + Device_newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler, + Device_newComputePipelineStateWithFunctionWithReflection, +} + @(objc_type=Device, objc_name="newCounterSampleBuffer") Device_newCounterSampleBuffer :: #force_inline proc(self: ^Device, descriptor: ^CounterSampleBufferDescriptor) -> (counter: ^Counter, error: ^NS.Error) { counter = msgSend(^Counter, self, "newCounterSampleBufferWithDescriptor:error:", descriptor, &error) @@ -6595,6 +6606,16 @@ Device_newLibraryWithURL :: #force_inline proc(self: ^Device, url: ^NS.URL) -> ( library = msgSend(^Library, self, "newLibraryWithURL:error:", url, &error) return } +@(objc_type=Device, objc_name="newLibrary") +Device_newLibrary :: proc{ + Device_newLibraryWithData, + Device_newLibraryWithFile, + Device_newLibraryWithSourceWithCompletionHandler, + Device_newLibraryWithSource, + Device_newLibraryWithURL, +} + + @(objc_type=Device, objc_name="newRasterizationRateMap") Device_newRasterizationRateMap :: #force_inline proc(self: ^Device, descriptor: ^RasterizationRateMapDescriptor) -> ^RasterizationRateMap { return msgSend(^RasterizationRateMap, self, "newRasterizationRateMapWithDescriptor:", descriptor) @@ -6603,8 +6624,8 @@ Device_newRasterizationRateMap :: #force_inline proc(self: ^Device, descriptor: Device_newRenderPipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, completionHandler: NewRenderPipelineStateCompletionHandler) -> ^RenderPipelineState { return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:completionHandler:", descriptor, completionHandler) } -@(objc_type=Device, objc_name="newRenderPipelineState") -Device_newRenderPipelineState :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) { +@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptor") +Device_newRenderPipelineStateWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) { pipeline = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:error:", descriptor, &error) return } @@ -6626,6 +6647,17 @@ Device_newRenderPipelineStateWithTileDescriptorWithReflection :: #force_inline p pipeline = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithTileDescriptor:options:reflection:error:", descriptor, options, reflection, &error) return } +@(objc_type=Device, objc_name="newRenderPipelineState") +Device_newRenderPipelineState :: proc{ + Device_newRenderPipelineStateWithDescriptorWithCompletionHandler, + Device_newRenderPipelineStateWithDescriptor, + Device_newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler, + Device_newRenderPipelineStateWithDescriptorWithReflection, + Device_newRenderPipelineStateWithTileDescriptorWithCompletionHandler, + Device_newRenderPipelineStateWithTileDescriptorWithReflection, +} + + @(objc_type=Device, objc_name="newSamplerState") Device_newSamplerState :: #force_inline proc(self: ^Device, descriptor: ^SamplerDescriptor) -> ^SamplerState { return msgSend(^SamplerState, self, "newSamplerStateWithDescriptor:", descriptor) From cfeb16f917eafc987a00c4726322e3664c34ce02 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 15 Apr 2022 11:20:42 +0100 Subject: [PATCH 031/245] Add more proc groups --- vendor/darwin/Metal/MetalClasses.odin | 65 +++++++++++++++++++++------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index c039510c6..c30fde95c 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -1152,6 +1152,12 @@ CaptureManager_newCaptureScopeWithCommandQueue :: #force_inline proc(self: ^Capt CaptureManager_newCaptureScopeWithDevice :: #force_inline proc(self: ^CaptureManager, device: ^Device) -> ^CaptureScope { return msgSend(^CaptureScope, self, "newCaptureScopeWithDevice:", device) } +@(objc_type=CaptureManager, objc_name="newCaptureScope") +CaptureManager_newCaptureScope :: proc{ + CaptureManager_newCaptureScopeWithCommandQueue, + CaptureManager_newCaptureScopeWithDevice, +} + @(objc_type=CaptureManager, objc_name="setDefaultCaptureScope") CaptureManager_setDefaultCaptureScope :: #force_inline proc(self: ^CaptureManager, defaultCaptureScope: ^CaptureScope) { msgSend(nil, self, "setDefaultCaptureScope:", defaultCaptureScope) @@ -6670,22 +6676,34 @@ Device_newSharedEvent :: #force_inline proc(self: ^Device) -> ^SharedEvent { Device_newSharedEventWithHandle :: #force_inline proc(self: ^Device, sharedEventHandle: ^SharedEventHandle) -> ^SharedEvent { return msgSend(^SharedEvent, self, "newSharedEventWithHandle:", sharedEventHandle) } -@(objc_type=Device, objc_name="newSharedTexture") -Device_newSharedTexture :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor) -> ^SharedEvent { +@(objc_type=Device, objc_name="newSharedTextureWithDescriptor") +Device_newSharedTextureWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor) -> ^SharedEvent { return msgSend(^SharedEvent, self, "newSharedTextureWithDescriptor:", descriptor) } @(objc_type=Device, objc_name="newSharedTextureWithHandle") Device_newSharedTextureWithHandle :: #force_inline proc(self: ^Device, sharedHandle: ^SharedTextureHandle) -> ^SharedEvent { return msgSend(^SharedEvent, self, "newSharedTextureWithHandle:", sharedHandle) } -@(objc_type=Device, objc_name="newTexture") -Device_newTexture :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> ^Texture { +@(objc_type=Device, objc_name="newSharedTexture") +Device_newSharedTexture :: proc{ + Device_newSharedTextureWithDescriptor, + Device_newSharedTextureWithHandle, +} + +@(objc_type=Device, objc_name="newTextureWithDescriptor") +Device_newTextureWithDescriptor :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> ^Texture { return msgSend(^Texture, self, "newTextureWithDescriptor:", desc) } @(objc_type=Device, objc_name="newTextureWithIOSurface") Device_newTextureWithIOSurface :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor, iosurface: IOSurfaceRef, plane: NS.UInteger) -> ^Texture { return msgSend(^Texture, self, "newTextureWithDescriptor:iosurface:plane:", descriptor, iosurface, plane) } +@(objc_type=Device, objc_name="newTexture") +Device_newTexture :: proc{ + Device_newTextureWithDescriptor, + Device_newTextureWithIOSurface, +} + @(objc_type=Device, objc_name="peerCount") Device_peerCount :: #force_inline proc(self: ^Device) -> u32 { return msgSend(u32, self, "peerCount") @@ -7147,22 +7165,34 @@ Heap_label :: #force_inline proc(self: ^Heap) -> ^NS.String { Heap_maxAvailableSizeWithAlignment :: #force_inline proc(self: ^Heap, alignment: NS.UInteger) -> NS.UInteger { return msgSend(NS.UInteger, self, "maxAvailableSizeWithAlignment:", alignment) } -@(objc_type=Heap, objc_name="newBuffer") -Heap_newBuffer :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions) -> ^Buffer { +@(objc_type=Heap, objc_name="newBufferWithLength") +Heap_newBufferWithLength :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions) -> ^Buffer { return msgSend(^Buffer, self, "newBufferWithLength:options:", length, options) } @(objc_type=Heap, objc_name="newBufferWithOptions") Heap_newBufferWithOptions :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions, offset: NS.UInteger) -> ^Buffer { return msgSend(^Buffer, self, "newBufferWithLength:options:offset:", length, options, offset) } -@(objc_type=Heap, objc_name="newTexture") -Heap_newTexture :: #force_inline proc(self: ^Heap, desc: ^TextureDescriptor) -> ^Texture { +@(objc_type=Heap, objc_name="newBuffer") +Heap_newBuffer :: proc{ + Heap_newBufferWithLength, + Heap_newBufferWithOptions, +} + +@(objc_type=Heap, objc_name="newTextureWithDescriptor") +Heap_newTextureWithDescriptor :: #force_inline proc(self: ^Heap, desc: ^TextureDescriptor) -> ^Texture { return msgSend(^Texture, self, "newTextureWithDescriptor:", desc) } -@(objc_type=Heap, objc_name="newTextureWithOffset") -Heap_newTextureWithOffset :: #force_inline proc(self: ^Heap, descriptor: ^TextureDescriptor, offset: NS.UInteger) -> ^Texture { +@(objc_type=Heap, objc_name="newTextureWithDescriptorAndOffset") +Heap_newTextureWithDescriptorAndOffset :: #force_inline proc(self: ^Heap, descriptor: ^TextureDescriptor, offset: NS.UInteger) -> ^Texture { return msgSend(^Texture, self, "newTextureWithDescriptor:offset:", descriptor, offset) } +@(objc_type=Heap, objc_name="newTexture") +Heap_newTexture :: proc{ + Heap_newTextureWithDescriptor, + Heap_newTextureWithDescriptorAndOffset, +} + @(objc_type=Heap, objc_name="resourceOptions") Heap_resourceOptions :: #force_inline proc(self: ^Heap) -> ResourceOptions { return msgSend(ResourceOptions, self, "resourceOptions") @@ -7431,7 +7461,7 @@ Library_label :: #force_inline proc(self: ^Library) -> ^NS.String { return msgSend(^NS.String, self, "label") } @(objc_type=Library, objc_name="newFunctionWithCompletionHandler") -Library_newFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^FunctionDescriptor, completionHandler: rawptr) -> ^Function { +Library_newFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^FunctionDescriptor, completionHandler: ^NS.Block) -> ^Function { return msgSend(^Function, self, "newFunctionWithDescriptor:completionHandler:", descriptor, completionHandler) } @(objc_type=Library, objc_name="newFunctionWithDescriptor") @@ -7444,7 +7474,7 @@ Library_newFunctionWithName :: #force_inline proc(self: ^Library, functionName: return msgSend(^Function, self, "newFunctionWithName:", functionName) } @(objc_type=Library, objc_name="newFunctionWithConstantValuesAndCompletionHandler") -Library_newFunctionWithConstantValuesAndCompletionHandler :: #force_inline proc(self: ^Library, name: ^NS.String, constantValues: ^FunctionConstantValues, completionHandler: rawptr) -> ^Function { +Library_newFunctionWithConstantValuesAndCompletionHandler :: #force_inline proc(self: ^Library, name: ^NS.String, constantValues: ^FunctionConstantValues, completionHandler: ^NS.Block) -> ^Function { return msgSend(^Function, self, "newFunctionWithName:constantValues:completionHandler:", name, constantValues, completionHandler) } @(objc_type=Library, objc_name="newFunctionWithConstantValues") @@ -7452,8 +7482,17 @@ Library_newFunctionWithConstantValues :: #force_inline proc(self: ^Library, name function = msgSend(^Function, self, "newFunctionWithName:constantValues:error:", name, constantValues, &error) return } +@(objc_type=Library, objc_name="newFunction") +Library_newFunction :: proc{ + Library_newFunctionWithCompletionHandler, + Library_newFunctionWithDescriptor, + Library_newFunctionWithName, + Library_newFunctionWithConstantValuesAndCompletionHandler, + Library_newFunctionWithConstantValues, +} + @(objc_type=Library, objc_name="newIntersectionFunctionWithCompletionHandler") -Library_newIntersectionFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^IntersectionFunctionDescriptor, completionHandler: rawptr) -> ^Function { +Library_newIntersectionFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^IntersectionFunctionDescriptor, completionHandler: ^NS.Block) -> ^Function { return msgSend(^Function, self, "newIntersectionFunctionWithDescriptor:completionHandler:", descriptor, completionHandler) } @(objc_type=Library, objc_name="newIntersectionFunction") From 6b7c04e046d97bd08401123977a046398563bb87 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 15 Apr 2022 11:33:28 +0100 Subject: [PATCH 032/245] Improve utilities --- .../{block_literal.odin => NSBlock.odin} | 20 +++++++++++++++---- vendor/darwin/Metal/MetalClasses.odin | 2 ++ vendor/darwin/Metal/MetalProcedures.odin | 5 +++++ 3 files changed, 23 insertions(+), 4 deletions(-) rename vendor/darwin/Foundation/{block_literal.odin => NSBlock.odin} (74%) diff --git a/vendor/darwin/Foundation/block_literal.odin b/vendor/darwin/Foundation/NSBlock.odin similarity index 74% rename from vendor/darwin/Foundation/block_literal.odin rename to vendor/darwin/Foundation/NSBlock.odin index 19e9782e4..67ab502e8 100644 --- a/vendor/darwin/Foundation/block_literal.odin +++ b/vendor/darwin/Foundation/NSBlock.odin @@ -34,8 +34,9 @@ global_block_descriptor := Block_Descriptor{ @(objc_class="NSConcreteGlobalBlock") Block :: struct {using _: Object} -@(objc_type=Block, objc_name="create", objc_is_class_method=true) -Block_create :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + +@(private="file") +Block_createInternal :: proc "c" (is_global: bool, user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { // Set to true on blocks that have captures (and thus are not true // global blocks) but are known not to escape for various other // reasons. For backward compatibility with old runtimes, whenever @@ -55,13 +56,24 @@ Block_create :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: raw cls := intrinsics.objc_find_class("NSConcreteGlobalBlock") bl := (^Internal_Block_Literal)(AllocateObject(cls, extraBytes, nil)) bl.isa = cls - bl.flags = BLOCK_IS_GLOBAL + bl.flags = BLOCK_IS_GLOBAL if is_global else 0 bl.invoke = proc "c" (bl: ^Internal_Block_Literal) { bl.user_proc(bl.user_data) } bl.descriptor = &global_block_descriptor bl.user_proc = user_proc bl.user_data = user_data - + return auto_cast bl } + +@(objc_type=Block, objc_name="createGlobal", objc_is_class_method=true) +Block_createGlobal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(true, user_data, user_proc) +} + + +@(objc_type=Block, objc_name="createLocal", objc_is_class_method=true) +Block_createLocal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(false, user_data, user_proc) +} diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index c30fde95c..075aae545 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -6588,6 +6588,7 @@ Device_newHeap :: #force_inline proc(self: ^Device, descriptor: ^HeapDescriptor) Device_newIndirectCommandBuffer :: #force_inline proc(self: ^Device, descriptor: ^IndirectCommandBufferDescriptor, maxCount: NS.UInteger, options: ResourceOptions) -> ^IndirectCommandBuffer { return msgSend(^IndirectCommandBuffer, self, "newIndirectCommandBufferWithDescriptor:maxCommandCount:options:", descriptor, maxCount, options) } + @(objc_type=Device, objc_name="newLibraryWithData") Device_newLibraryWithData :: #force_inline proc(self: ^Device, data: dispatch_data_t) -> (library: ^Library, error: ^NS.Error) { library = msgSend(^Library, self, "newLibraryWithData:error:", data, &error) @@ -6626,6 +6627,7 @@ Device_newLibrary :: proc{ Device_newRasterizationRateMap :: #force_inline proc(self: ^Device, descriptor: ^RasterizationRateMapDescriptor) -> ^RasterizationRateMap { return msgSend(^RasterizationRateMap, self, "newRasterizationRateMapWithDescriptor:", descriptor) } + @(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithCompletionHandler") Device_newRenderPipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, completionHandler: NewRenderPipelineStateCompletionHandler) -> ^RenderPipelineState { return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:completionHandler:", descriptor, completionHandler) diff --git a/vendor/darwin/Metal/MetalProcedures.odin b/vendor/darwin/Metal/MetalProcedures.odin index b76c7f541..ca8fb1aea 100644 --- a/vendor/darwin/Metal/MetalProcedures.odin +++ b/vendor/darwin/Metal/MetalProcedures.odin @@ -11,4 +11,9 @@ foreign Metal { CopyAllDevicesWithObserver :: proc(observer: ^id, handler: DeviceNotificationHandler) -> ^NS.Array --- CreateSystemDefaultDevice :: proc() -> ^Device --- RemoveDeviceObserver :: proc(observer: id) --- +} + + +new :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, NS.Object) { + return T.alloc()->init() } \ No newline at end of file From fc3f62e3eda6f6c605c0e1db73a1dc36cb5fc848 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 15 Apr 2022 11:50:08 +0100 Subject: [PATCH 033/245] Minor rearrangement --- vendor/darwin/Foundation/NSBlock.odin | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/vendor/darwin/Foundation/NSBlock.odin b/vendor/darwin/Foundation/NSBlock.odin index 67ab502e8..7fa061484 100644 --- a/vendor/darwin/Foundation/NSBlock.odin +++ b/vendor/darwin/Foundation/NSBlock.odin @@ -2,6 +2,21 @@ package objc_Foundation import "core:intrinsics" +@(objc_class="NSConcreteGlobalBlock") +Block :: struct {using _: Object} + +@(objc_type=Block, objc_name="createGlobal", objc_is_class_method=true) +Block_createGlobal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(true, user_data, user_proc) +} + +@(objc_type=Block, objc_name="createLocal", objc_is_class_method=true) +Block_createLocal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(false, user_data, user_proc) +} + + +@(private) Internal_Block_Literal_Base :: struct { isa: ^intrinsics.objc_class, flags: u32, @@ -10,6 +25,7 @@ Internal_Block_Literal_Base :: struct { descriptor: ^Block_Descriptor, } +@(private) Internal_Block_Literal :: struct { using base: Internal_Block_Literal_Base, // Imported Variables @@ -17,6 +33,7 @@ Internal_Block_Literal :: struct { user_data: rawptr, } +@(private) Block_Descriptor :: struct { reserved: uint, size: uint, @@ -25,16 +42,12 @@ Block_Descriptor :: struct { signature: cstring, } +@(private) global_block_descriptor := Block_Descriptor{ reserved = 0, size = size_of(Internal_Block_Literal), } - -@(objc_class="NSConcreteGlobalBlock") -Block :: struct {using _: Object} - - @(private="file") Block_createInternal :: proc "c" (is_global: bool, user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { // Set to true on blocks that have captures (and thus are not true @@ -66,14 +79,3 @@ Block_createInternal :: proc "c" (is_global: bool, user_data: rawptr, user_proc: return auto_cast bl } - -@(objc_type=Block, objc_name="createGlobal", objc_is_class_method=true) -Block_createGlobal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { - return Block_createInternal(true, user_data, user_proc) -} - - -@(objc_type=Block, objc_name="createLocal", objc_is_class_method=true) -Block_createLocal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { - return Block_createInternal(false, user_data, user_proc) -} From 989641a6167498dfe6663fb330525d4d92becf8a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 15 Apr 2022 12:14:12 +0100 Subject: [PATCH 034/245] Update Vulkan generation and package --- .../vulkan/_gen/create_vulkan_odin_wrapper.py | 37 +- vendor/vulkan/_gen/vk_icd.h | 2 +- vendor/vulkan/_gen/vk_platform.h | 4 +- vendor/vulkan/_gen/vulkan_core.h | 2569 ++++++++++++----- vendor/vulkan/_gen/vulkan_ios.h | 2 +- vendor/vulkan/_gen/vulkan_macos.h | 2 +- vendor/vulkan/_gen/vulkan_metal.h | 2 +- vendor/vulkan/_gen/vulkan_win32.h | 2 +- vendor/vulkan/core.odin | 98 +- vendor/vulkan/enums.odin | 1819 +++++++----- vendor/vulkan/procedures.odin | 341 ++- vendor/vulkan/structs.odin | 1529 ++++++---- 12 files changed, 4320 insertions(+), 2087 deletions(-) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index f1949f973..ae1bc8d64 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -7,14 +7,14 @@ import os.path import math file_and_urls = [ - ("vk_platform.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_platform.h', True), - ("vulkan_core.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h', False), - ("vk_layer.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_layer.h', True), - ("vk_icd.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_icd.h', True), - ("vulkan_win32.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_win32.h', False), - ("vulkan_metal.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_metal.h', False), - ("vulkan_macos.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_macos.h', False), - ("vulkan_ios.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_ios.h', False), + ("vk_platform.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_platform.h', True), + ("vulkan_core.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_core.h', False), + ("vk_layer.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_layer.h', True), + ("vk_icd.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_icd.h', True), + ("vulkan_win32.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_win32.h', False), + ("vulkan_metal.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_metal.h', False), + ("vulkan_macos.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_macos.h', False), + ("vulkan_ios.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_ios.h', False), ] for file, url, _ in file_and_urls: @@ -125,7 +125,7 @@ def to_snake_case(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() -ext_suffixes = ["KHR", "EXT", "AMD", "NV", "NVX", "GOOGLE"] +ext_suffixes = ["KHR", "EXT", "AMD", "NV", "NVX", "GOOGLE", "KHX"] ext_suffixes_title = [ext.title() for ext in ext_suffixes] @@ -254,9 +254,19 @@ def parse_constants(f): f.write("{}{} :: {}\n".format(name, "".rjust(max_len-len(name)), value)) f.write("\n// Vendor Constants\n") - data = re.findall(r"#define VK_((?:"+'|'.join(ext_suffixes)+r")\w+)\s*(.*?)\n", src, re.S) + fixes = '|'.join(ext_suffixes) + inner = r"((?:(?:" + fixes + r")\w+)|(?:\w+" + fixes + r"))" + pattern = r"#define\s+VK_" + inner + r"\s*(.*?)\n" + data = re.findall(pattern, src, re.S) + + number_suffix_re = re.compile(r"(\d+)[UuLlFf]") + max_len = max(len(name) for name, value in data) for name, value in data: + value = remove_prefix(value, 'VK_') + v = number_suffix_re.findall(value) + if v: + value = v[0] f.write("{}{} :: {}\n".format(name, "".rjust(max_len-len(name)), value)) f.write("\n") @@ -652,15 +662,12 @@ MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 MAX_EXTENSION_NAME_SIZE :: 256 MAX_DESCRIPTION_SIZE :: 256 -MAX_DEVICE_GROUP_SIZE_KHX :: 32 MAX_DEVICE_GROUP_SIZE :: 32 LUID_SIZE_KHX :: 8 -LUID_SIZE_KHR :: 8 LUID_SIZE :: 8 -MAX_DRIVER_NAME_SIZE_KHR :: 256 -MAX_DRIVER_INFO_SIZE_KHR :: 256 -MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(0)-1 +MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE_EXT :: 16 +QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL """[1::]) parse_constants(f) diff --git a/vendor/vulkan/_gen/vk_icd.h b/vendor/vulkan/_gen/vk_icd.h index ae006d06d..41989ee35 100644 --- a/vendor/vulkan/_gen/vk_icd.h +++ b/vendor/vulkan/_gen/vk_icd.h @@ -33,7 +33,7 @@ // Version 2 - Add Loader/ICD Interface version negotiation // via vk_icdNegotiateLoaderICDInterfaceVersion. // Version 3 - Add ICD creation/destruction of KHR_surface objects. -// Version 4 - Add unknown physical device extension qyering via +// Version 4 - Add unknown physical device extension querying via // vk_icdGetPhysicalDeviceProcAddr. // Version 5 - Tells ICDs that the loader is now paying attention to the // application version of Vulkan passed into the ApplicationInfo diff --git a/vendor/vulkan/_gen/vk_platform.h b/vendor/vulkan/_gen/vk_platform.h index 18b913abc..3ff8c5d14 100644 --- a/vendor/vulkan/_gen/vk_platform.h +++ b/vendor/vulkan/_gen/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright 2014-2021 The Khronos Group Inc. +** Copyright 2014-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -42,7 +42,7 @@ extern "C" #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan isn't supported for the 'armeabi' NDK ABI" + #error "Vulkan is not supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" // calling convention, i.e. float parameters are passed in registers. This diff --git a/vendor/vulkan/_gen/vulkan_core.h b/vendor/vulkan/_gen/vulkan_core.h index 18b302fa0..5c8b8461f 100644 --- a/vendor/vulkan/_gen/vulkan_core.h +++ b/vendor/vulkan/_gen/vulkan_core.h @@ -2,7 +2,7 @@ #define VULKAN_CORE_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -72,10 +72,10 @@ extern "C" { #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 // Version of this file -#define VK_HEADER_VERSION 191 +#define VK_HEADER_VERSION 211 // Complete version of this file -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION) +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) // DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) @@ -160,6 +160,7 @@ typedef enum VkResult { VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, VK_ERROR_FRAGMENTATION = -1000161000, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_PIPELINE_COMPILE_REQUIRED = 1000297000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, @@ -168,19 +169,20 @@ typedef enum VkResult { VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_NOT_PERMITTED_KHR = -1000174001, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, VK_THREAD_IDLE_KHR = 1000268000, VK_THREAD_DONE_KHR = 1000268001, VK_OPERATION_DEFERRED_KHR = 1000268002, VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, - VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT, + VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -349,6 +351,58 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -418,8 +472,14 @@ typedef enum VkStructureType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, #endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, +#endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, #endif VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, @@ -436,54 +496,94 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, #endif VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, @@ -493,7 +593,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, @@ -565,10 +664,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, @@ -607,6 +703,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, #ifdef VK_ENABLE_BETA_EXTENSIONS @@ -634,7 +731,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, @@ -646,29 +742,28 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, #endif + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, @@ -689,14 +784,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, @@ -712,7 +803,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, @@ -743,7 +833,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, @@ -754,10 +843,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, @@ -771,30 +857,26 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, #endif VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = 1000314000, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = 1000314003, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = 1000314004, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, @@ -805,20 +887,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = 1000337000, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = 1000337001, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = 1000337005, - VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = 1000337006, - VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = 1000337008, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = 1000337010, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, @@ -826,12 +898,24 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, + VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, + VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, + VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, @@ -842,14 +926,31 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, + VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, @@ -869,6 +970,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, @@ -911,6 +1013,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, @@ -932,9 +1038,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, @@ -947,12 +1055,17 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES, VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, @@ -961,6 +1074,42 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -980,6 +1129,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, @@ -1002,8 +1153,6 @@ typedef enum VkImageLayout { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, #endif - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = 1000314001, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1011,6 +1160,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } VkImageLayout; @@ -1043,6 +1194,7 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_COMMAND_POOL = 25, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, @@ -1063,9 +1215,10 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = 1000295000, + VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; @@ -1318,6 +1471,26 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1326,26 +1499,20 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = 1000340000, - VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK, VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, @@ -1380,6 +1547,12 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -1422,6 +1595,7 @@ typedef enum VkQueryType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, #endif + VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000, VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; @@ -1553,6 +1727,21 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_CULL_MODE = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, @@ -1562,25 +1751,25 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - VK_DYNAMIC_STATE_CULL_MODE_EXT = 1000267000, - VK_DYNAMIC_STATE_FRONT_FACE_EXT = 1000267001, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = 1000267002, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = 1000267003, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = 1000267004, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = 1000267006, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = 1000267007, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = 1000267008, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = 1000267010, - VK_DYNAMIC_STATE_STENCIL_OP_EXT = 1000267011, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = 1000377002, VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, + VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, + VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; @@ -1699,10 +1888,11 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -1717,8 +1907,10 @@ typedef enum VkAttachmentLoadOp { typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000, - VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE = 1000301000, + VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE, VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; @@ -1770,6 +1962,7 @@ typedef enum VkAccessFlagBits { VK_ACCESS_HOST_WRITE_BIT = 0x00004000, VK_ACCESS_MEMORY_READ_BIT = 0x00008000, VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_NONE = 0, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, @@ -1781,10 +1974,10 @@ typedef enum VkAccessFlagBits { VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, - VK_ACCESS_NONE_KHR = 0, VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -1797,6 +1990,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_NONE = 0, VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, @@ -1804,6 +1998,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageAspectFlagBits; typedef VkFlags VkImageAspectFlags; @@ -1879,6 +2074,8 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, @@ -1935,6 +2132,11 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; + +typedef enum VkInstanceCreateFlagBits { + VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001, + VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkInstanceCreateFlagBits; typedef VkFlags VkInstanceCreateFlags; typedef enum VkMemoryHeapFlagBits { @@ -2000,6 +2202,7 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_NONE = 0, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, @@ -2009,10 +2212,10 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, - VK_PIPELINE_STAGE_NONE_KHR = 0, VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, + VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -2040,7 +2243,8 @@ typedef VkFlags VkFenceCreateFlags; typedef VkFlags VkSemaphoreCreateFlags; typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkEventCreateFlagBits; typedef VkFlags VkEventCreateFlags; @@ -2132,7 +2336,8 @@ typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef enum VkPipelineCacheCreateFlagBits { - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; @@ -2152,6 +2357,10 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, @@ -2164,19 +2373,25 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = 0x00000100, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = 0x00000200, + VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, + VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; typedef enum VkPipelineShaderStageCreateFlagBits { - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000001, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT, VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineShaderStageCreateFlagBits; typedef VkFlags VkPipelineShaderStageCreateFlags; @@ -2222,9 +2437,25 @@ typedef VkFlags VkPipelineTessellationStateCreateFlags; typedef VkFlags VkPipelineViewportStateCreateFlags; typedef VkFlags VkPipelineRasterizationStateCreateFlags; typedef VkFlags VkPipelineMultisampleStateCreateFlags; + +typedef enum VkPipelineDepthStencilStateCreateFlagBits { + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000002, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineDepthStencilStateCreateFlagBits; typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + +typedef enum VkPipelineColorBlendStateCreateFlagBits { + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineColorBlendStateCreateFlagBits; typedef VkFlags VkPipelineColorBlendStateCreateFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; + +typedef enum VkPipelineLayoutCreateFlagBits { + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, + VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineLayoutCreateFlagBits; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; @@ -2288,6 +2519,9 @@ typedef enum VkSubpassDescriptionFlagBits { VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = 0x00000010, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000020, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000040, VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubpassDescriptionFlagBits; typedef VkFlags VkSubpassDescriptionFlags; @@ -5285,6 +5519,11 @@ typedef enum VkDriverId { VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, VK_DRIVER_ID_JUICE_PROPRIETARY = 16, VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, + VK_DRIVER_ID_MESA_TURNIP = 18, + VK_DRIVER_ID_MESA_V3DV = 19, + VK_DRIVER_ID_MESA_PANVK = 20, + VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, + VK_DRIVER_ID_MESA_VENUS = 22, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, @@ -6006,6 +6245,1037 @@ VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( #endif +#define VK_VERSION_1_3 1 +// Vulkan 1.3 version number +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 + +typedef uint64_t VkFlags64; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) + +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef VkFlags VkPipelineCreationFeedbackFlags; + +typedef enum VkToolPurposeFlagBits { + VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkToolPurposeFlagBits; +typedef VkFlags VkToolPurposeFlags; +typedef VkFlags VkPrivateDataSlotCreateFlags; +typedef VkFlags64 VkPipelineStageFlags2; + +// Flag bits for VkPipelineStageFlagBits2 +typedef VkFlags64 VkPipelineStageFlagBits2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +#endif +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; + +typedef VkFlags64 VkAccessFlags2; + +// Flag bits for VkAccessFlagBits2 +typedef VkFlags64 VkAccessFlagBits2; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +#endif +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; + + +typedef enum VkSubmitFlagBits { + VK_SUBMIT_PROTECTED_BIT = 0x00000001, + VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, + VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubmitFlagBits; +typedef VkFlags VkSubmitFlags; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, + VK_RENDERING_SUSPENDING_BIT = 0x00000002, + VK_RENDERING_RESUMING_BIT = 0x00000004, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; +typedef VkFlags VkRenderingFlags; +typedef VkFlags64 VkFormatFeatureFlags2; + +// Flag bits for VkFormatFeatureFlagBits2 +typedef VkFlags64 VkFormatFeatureFlagBits2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; + +typedef struct VkPhysicalDeviceVulkan13Features { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; + VkBool32 pipelineCreationCacheControl; + VkBool32 privateData; + VkBool32 shaderDemoteToHelperInvocation; + VkBool32 shaderTerminateInvocation; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; + VkBool32 synchronization2; + VkBool32 textureCompressionASTC_HDR; + VkBool32 shaderZeroInitializeWorkgroupMemory; + VkBool32 dynamicRendering; + VkBool32 shaderIntegerDotProduct; + VkBool32 maintenance4; +} VkPhysicalDeviceVulkan13Features; + +typedef struct VkPhysicalDeviceVulkan13Properties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; + uint32_t maxInlineUniformTotalSize; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceVulkan13Properties; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreationFeedback* pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkPhysicalDeviceToolProperties { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlags purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolProperties; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDevicePrivateDataFeatures { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeatures; + +typedef struct VkDevicePrivateDataCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfo; + +typedef struct VkPrivateDataSlotCreateInfo { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlags flags; +} VkPrivateDataSlotCreateInfo; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; +} VkMemoryBarrier2; + +typedef struct VkBufferMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2; + +typedef struct VkImageMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2; + +typedef struct VkDependencyInfo { + VkStructureType sType; + const void* pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2* pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2* pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2* pImageMemoryBarriers; +} VkDependencyInfo; + +typedef struct VkSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2 stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfo; + +typedef struct VkCommandBufferSubmitInfo { + VkStructureType sType; + const void* pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfo; + +typedef struct VkSubmitInfo2 { + VkStructureType sType; + const void* pNext; + VkSubmitFlags flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfo* pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos; +} VkSubmitInfo2; + +typedef struct VkPhysicalDeviceSynchronization2Features { + VkStructureType sType; + void* pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2Features; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkBufferCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2; + +typedef struct VkCopyBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2* pRegions; +} VkCopyBufferInfo2; + +typedef struct VkImageCopy2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2; + +typedef struct VkCopyImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageInfo2; + +typedef struct VkBufferImageCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2; + +typedef struct VkCopyBufferToImageInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyBufferToImageInfo2; + +typedef struct VkCopyImageToBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyImageToBufferInfo2; + +typedef struct VkImageBlit2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit2; + +typedef struct VkBlitImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2* pRegions; + VkFilter filter; +} VkBlitImageInfo2; + +typedef struct VkImageResolve2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2; + +typedef struct VkResolveImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2* pRegions; +} VkResolveImageInfo2; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkRenderingAttachmentInfo { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkResolveModeFlagBits resolveMode; + VkImageView resolveImageView; + VkImageLayout resolveImageLayout; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkClearValue clearValue; +} VkRenderingAttachmentInfo; + +typedef struct VkRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + VkRect2D renderArea; + uint32_t layerCount; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkRenderingAttachmentInfo* pColorAttachments; + const VkRenderingAttachmentInfo* pDepthAttachment; + const VkRenderingAttachmentInfo* pStencilAttachment; +} VkRenderingInfo; + +typedef struct VkPipelineRenderingCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkPipelineRenderingCreateInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRendering; +} VkPhysicalDeviceDynamicRenderingFeatures; + +typedef struct VkCommandBufferInheritanceRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +} VkCommandBufferInheritanceRenderingInfo; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void* pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void* pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void* pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkBufferCreateInfo* pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolProperties* pToolProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot( + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot( + VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( + VkCommandBuffer commandBuffer, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2* pResolveImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + #define VK_KHR_surface 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 @@ -6432,6 +7702,68 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" +#define VK_KHR_dynamic_rendering 1 +#define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1 +#define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering" +typedef VkRenderingFlags VkRenderingFlagsKHR; + +typedef VkRenderingFlagBits VkRenderingFlagBitsKHR; + +typedef VkRenderingInfo VkRenderingInfoKHR; + +typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR; + +typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR; + +typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR; + +typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; + +typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkExtent2D shadingRateAttachmentTexelSize; +} VkRenderingFragmentShadingRateAttachmentInfoKHR; + +typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; +} VkRenderingFragmentDensityMapAttachmentInfoEXT; + +typedef struct VkAttachmentSampleCountInfoAMD { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const VkSampleCountFlagBits* pColorAttachmentSamples; + VkSampleCountFlagBits depthStencilAttachmentSamples; +} VkAttachmentSampleCountInfoAMD; + +typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; + +typedef struct VkMultiviewPerViewAttributesInfoNVX { + VkStructureType sType; + const void* pNext; + VkBool32 perViewAttributes; + VkBool32 perViewAttributesPositionXOnly; +} VkMultiviewPerViewAttributesInfoNVX; + +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( + VkCommandBuffer commandBuffer); +#endif + + #define VK_KHR_multiview 1 #define VK_KHR_MULTIVIEW_SPEC_VERSION 1 #define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" @@ -6566,8 +7898,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( #define VK_KHR_maintenance1 1 -#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2 -#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION +#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); @@ -7147,8 +8481,10 @@ VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( #define VK_KHR_maintenance2 1 -#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION +#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR; @@ -7401,8 +8737,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( #define VK_KHR_maintenance3 1 -#define VK_KHR_MAINTENANCE3_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION +#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; @@ -7477,6 +8815,43 @@ typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { +#define VK_KHR_global_priority 1 +#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U +#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 +#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" + +typedef enum VkQueueGlobalPriorityKHR { + VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueueGlobalPriorityKHR; +typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriorityKHR globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoKHR; + +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; + +typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; +} VkQueueFamilyGlobalPriorityPropertiesKHR; + + + #define VK_KHR_driver_properties 1 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" @@ -7569,16 +8944,12 @@ typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryMo #define VK_KHR_shader_terminate_invocation 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; +typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; #define VK_KHR_fragment_shading_rate 1 -#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 1 +#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 2 #define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate" typedef enum VkFragmentShadingRateCombinerOpKHR { @@ -7870,46 +9241,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR #define VK_KHR_shader_integer_dot_product 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product" -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; -typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; @@ -7949,261 +9283,94 @@ typedef struct VkPhysicalDevicePresentIdFeaturesKHR { #define VK_KHR_synchronization2 1 -typedef uint64_t VkFlags64; #define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 #define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" -typedef VkFlags64 VkPipelineStageFlags2KHR; +typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR; -// Flag bits for VkPipelineStageFlagBits2KHR -typedef VkFlags64 VkPipelineStageFlagBits2KHR; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; -#endif -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; +typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR; -typedef VkFlags64 VkAccessFlags2KHR; +typedef VkAccessFlags2 VkAccessFlags2KHR; -// Flag bits for VkAccessFlagBits2KHR -typedef VkFlags64 VkAccessFlagBits2KHR; -static const VkAccessFlagBits2KHR VK_ACCESS_2_NONE_KHR = 0ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; -#endif -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; +typedef VkAccessFlagBits2 VkAccessFlagBits2KHR; +typedef VkSubmitFlagBits VkSubmitFlagBitsKHR; -typedef enum VkSubmitFlagBitsKHR { - VK_SUBMIT_PROTECTED_BIT_KHR = 0x00000001, - VK_SUBMIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSubmitFlagBitsKHR; -typedef VkFlags VkSubmitFlagsKHR; -typedef struct VkMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; -} VkMemoryBarrier2KHR; +typedef VkSubmitFlags VkSubmitFlagsKHR; -typedef struct VkBufferMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier2KHR; +typedef VkMemoryBarrier2 VkMemoryBarrier2KHR; -typedef struct VkImageMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier2KHR; +typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR; -typedef struct VkDependencyInfoKHR { - VkStructureType sType; - const void* pNext; - VkDependencyFlags dependencyFlags; - uint32_t memoryBarrierCount; - const VkMemoryBarrier2KHR* pMemoryBarriers; - uint32_t bufferMemoryBarrierCount; - const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; - uint32_t imageMemoryBarrierCount; - const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; -} VkDependencyInfoKHR; +typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR; -typedef struct VkSemaphoreSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; - VkPipelineStageFlags2KHR stageMask; - uint32_t deviceIndex; -} VkSemaphoreSubmitInfoKHR; +typedef VkDependencyInfo VkDependencyInfoKHR; -typedef struct VkCommandBufferSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkCommandBuffer commandBuffer; - uint32_t deviceMask; -} VkCommandBufferSubmitInfoKHR; +typedef VkSubmitInfo2 VkSubmitInfo2KHR; -typedef struct VkSubmitInfo2KHR { - VkStructureType sType; - const void* pNext; - VkSubmitFlagsKHR flags; - uint32_t waitSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos; - uint32_t commandBufferInfoCount; - const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos; - uint32_t signalSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos; -} VkSubmitInfo2KHR; +typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR; -typedef struct VkPhysicalDeviceSynchronization2FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 synchronization2; -} VkPhysicalDeviceSynchronization2FeaturesKHR; +typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; + +typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; typedef struct VkQueueFamilyCheckpointProperties2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR checkpointExecutionStageMask; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 checkpointExecutionStageMask; } VkQueueFamilyCheckpointProperties2NV; typedef struct VkCheckpointData2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR stage; - void* pCheckpointMarker; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 stage; + void* pCheckpointMarker; } VkCheckpointData2NV; -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfos); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - VkPipelineStageFlags2KHR stageMask); + VkPipelineStageFlags2 stageMask); VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, - const VkDependencyInfoKHR* pDependencyInfos); + const VkDependencyInfo* pDependencyInfos); VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( VkCommandBuffer commandBuffer, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( VkQueue queue, uint32_t submitCount, - const VkSubmitInfo2KHR* pSubmits, + const VkSubmitInfo2* pSubmits, VkFence fence); VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); @@ -8229,11 +9396,7 @@ typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { #define VK_KHR_zero_initialize_workgroup_memory 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; +typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; @@ -8254,148 +9417,109 @@ typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { #define VK_KHR_copy_commands2 1 #define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 #define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" -typedef struct VkBufferCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy2KHR; +typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR; -typedef struct VkCopyBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferCopy2KHR* pRegions; -} VkCopyBufferInfo2KHR; +typedef VkCopyImageInfo2 VkCopyImageInfo2KHR; -typedef struct VkImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy2KHR; +typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR; -typedef struct VkCopyImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2KHR* pRegions; -} VkCopyImageInfo2KHR; +typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR; -typedef struct VkBufferImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy2KHR; +typedef VkBlitImageInfo2 VkBlitImageInfo2KHR; -typedef struct VkCopyBufferToImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyBufferToImageInfo2KHR; +typedef VkResolveImageInfo2 VkResolveImageInfo2KHR; -typedef struct VkCopyImageToBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyImageToBufferInfo2KHR; +typedef VkBufferCopy2 VkBufferCopy2KHR; -typedef struct VkImageBlit2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit2KHR; +typedef VkImageCopy2 VkImageCopy2KHR; -typedef struct VkBlitImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageBlit2KHR* pRegions; - VkFilter filter; -} VkBlitImageInfo2KHR; +typedef VkImageBlit2 VkImageBlit2KHR; -typedef struct VkImageResolve2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve2KHR; +typedef VkBufferImageCopy2 VkBufferImageCopy2KHR; -typedef struct VkResolveImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageResolve2KHR* pRegions; -} VkResolveImageInfo2KHR; +typedef VkImageResolve2 VkImageResolve2KHR; -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR* pCopyBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR* pCopyImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR* pBlitImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferInfo2KHR* pCopyBufferInfo); + const VkCopyBufferInfo2* pCopyBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageInfo2KHR* pCopyImageInfo); + const VkCopyImageInfo2* pCopyImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( VkCommandBuffer commandBuffer, - const VkBlitImageInfo2KHR* pBlitImageInfo); + const VkBlitImageInfo2* pBlitImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( VkCommandBuffer commandBuffer, - const VkResolveImageInfo2KHR* pResolveImageInfo); + const VkResolveImageInfo2* pResolveImageInfo); +#endif + + +#define VK_KHR_format_feature_flags2 1 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 1 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2" +typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR; + +typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR; + +typedef VkFormatProperties3 VkFormatProperties3KHR; + + + +#define VK_KHR_portability_enumeration 1 +#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" + + +#define VK_KHR_maintenance4 1 +#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4" +typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR; + +typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR; + +typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR; + +typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR; + +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #endif @@ -8443,6 +9567,7 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, @@ -9028,11 +10153,7 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_texture_compression_astc_hdr 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; +typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; @@ -9302,8 +10423,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( #define VK_NV_viewport_array2 1 -#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION +#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME #define VK_NVX_multiview_per_view_attributes 1 @@ -9658,35 +10781,13 @@ typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFil #define VK_EXT_inline_uniform_block 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" -typedef struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeaturesEXT; +typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT; -typedef struct VkPhysicalDeviceInlineUniformBlockPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockPropertiesEXT; +typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT; -typedef struct VkWriteDescriptorSetInlineUniformBlockEXT { - VkStructureType sType; - const void* pNext; - uint32_t dataSize; - const void* pData; -} VkWriteDescriptorSetInlineUniformBlockEXT; +typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT; -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfoEXT; +typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT; @@ -9873,7 +10974,7 @@ typedef struct VkPhysicalDeviceShaderSMBuiltinsFeaturesNV { #define VK_EXT_image_drm_format_modifier 1 -#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 1 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 2 #define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier" typedef struct VkDrmFormatModifierPropertiesEXT { uint64_t drmFormatModifier; @@ -9918,6 +11019,19 @@ typedef struct VkImageDrmFormatModifierPropertiesEXT { uint64_t drmFormatModifier; } VkImageDrmFormatModifierPropertiesEXT; +typedef struct VkDrmFormatModifierProperties2EXT { + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags2 drmFormatModifierTilingFeatures; +} VkDrmFormatModifierProperties2EXT; + +typedef struct VkDrmFormatModifierPropertiesList2EXT { + VkStructureType sType; + void* pNext; + uint32_t drmFormatModifierCount; + VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties; +} VkDrmFormatModifierPropertiesList2EXT; + typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); #ifndef VK_NO_PROTOTYPES @@ -10519,19 +11633,9 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" +typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; -typedef enum VkQueueGlobalPriorityEXT { - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, - VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF -} VkQueueGlobalPriorityEXT; -typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkQueueGlobalPriorityEXT globalPriority; -} VkDeviceQueueGlobalPriorityCreateInfoEXT; +typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; @@ -10709,26 +11813,13 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT { #define VK_EXT_pipeline_creation_feedback 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback" +typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT; -typedef enum VkPipelineCreationFeedbackFlagBitsEXT { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = 0x00000001, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = 0x00000002, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = 0x00000004, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBitsEXT; -typedef VkFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackEXT { - VkPipelineCreationFeedbackFlagsEXT flags; - uint64_t duration; -} VkPipelineCreationFeedbackEXT; +typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineCreationFeedbackEXT* pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedbackEXT* pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfoEXT; +typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT; + +typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; @@ -11079,7 +12170,7 @@ VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD( #define VK_EXT_fragment_density_map 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2 #define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { VkStructureType sType; @@ -11113,8 +12204,10 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_GOOGLE_hlsl_functionality1 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME #define VK_GOOGLE_decorate_string 1 @@ -11125,27 +12218,11 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_EXT_subgroup_size_control 1 #define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 #define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" -typedef struct VkPhysicalDeviceSubgroupSizeControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; -typedef struct VkPhysicalDeviceSubgroupSizeControlPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT { - VkStructureType sType; - void* pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; +typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; @@ -11262,35 +12339,19 @@ VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( #define VK_EXT_tooling_info 1 #define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 #define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" +typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT; -typedef enum VkToolPurposeFlagBitsEXT { - VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001, - VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002, - VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010, - VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, - VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, - VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkToolPurposeFlagBitsEXT; -typedef VkFlags VkToolPurposeFlagsEXT; -typedef struct VkPhysicalDeviceToolPropertiesEXT { - VkStructureType sType; - void* pNext; - char name[VK_MAX_EXTENSION_NAME_SIZE]; - char version[VK_MAX_EXTENSION_NAME_SIZE]; - VkToolPurposeFlagsEXT purposes; - char description[VK_MAX_DESCRIPTION_SIZE]; - char layer[VK_MAX_EXTENSION_NAME_SIZE]; -} VkPhysicalDeviceToolPropertiesEXT; +typedef VkToolPurposeFlags VkToolPurposeFlagsEXT; -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); +typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice, uint32_t* pToolCount, - VkPhysicalDeviceToolPropertiesEXT* pToolProperties); + VkPhysicalDeviceToolProperties* pToolProperties); #endif @@ -11721,11 +12782,7 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { #define VK_EXT_shader_demote_to_helper_invocation 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; +typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; @@ -11947,14 +13004,7 @@ typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT { VkBool32 texelBufferAlignment; } VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT; -typedef struct VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; +typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; @@ -12092,61 +13142,47 @@ typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { #define VK_EXT_private_data 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlotEXT) +typedef VkPrivateDataSlot VkPrivateDataSlotEXT; + #define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 #define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" +typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT; -typedef enum VkPrivateDataSlotCreateFlagBitsEXT { - VK_PRIVATE_DATA_SLOT_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPrivateDataSlotCreateFlagBitsEXT; -typedef VkFlags VkPrivateDataSlotCreateFlagsEXT; -typedef struct VkPhysicalDevicePrivateDataFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 privateData; -} VkPhysicalDevicePrivateDataFeaturesEXT; +typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT; -typedef struct VkDevicePrivateDataCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t privateDataSlotRequestCount; -} VkDevicePrivateDataCreateInfoEXT; +typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT; -typedef struct VkPrivateDataSlotCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPrivateDataSlotCreateFlagsEXT flags; -} VkPrivateDataSlotCreateInfoEXT; +typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT; -typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlotEXT* pPrivateDataSlot); -typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlotEXT privateDataSlot, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data); -typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t* pData); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( VkDevice device, - const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, + const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, - VkPrivateDataSlotEXT* pPrivateDataSlot); + VkPrivateDataSlot* pPrivateDataSlot); VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( VkDevice device, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t data); VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t* pData); #endif @@ -12154,11 +13190,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( #define VK_EXT_pipeline_creation_cache_control 1 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; +typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; @@ -12192,6 +13224,39 @@ typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { #define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" +#define VK_EXT_graphics_pipeline_library 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library" + +typedef enum VkGraphicsPipelineLibraryFlagBitsEXT { + VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001, + VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008, + VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkGraphicsPipelineLibraryFlagBitsEXT; +typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibrary; +} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT; + +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibraryFastLinking; + VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration; +} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT; + +typedef struct VkGraphicsPipelineLibraryCreateInfoEXT { + VkStructureType sType; + void* pNext; + VkGraphicsPipelineLibraryFlagsEXT flags; +} VkGraphicsPipelineLibraryCreateInfoEXT; + + + #define VK_NV_fragment_shading_rate_enums 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" @@ -12384,11 +13449,7 @@ typedef struct VkCopyCommandTransformInfoQCOM { #define VK_EXT_image_robustness 1 #define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 #define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" -typedef struct VkPhysicalDeviceImageRobustnessFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeaturesEXT; +typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT; @@ -12404,6 +13465,30 @@ typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { +#define VK_ARM_rasterization_order_attachment_access 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access" +typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 rasterizationOrderColorAttachmentAccess; + VkBool32 rasterizationOrderDepthAttachmentAccess; + VkBool32 rasterizationOrderStencilAttachmentAccess; +} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM; + + + +#define VK_EXT_rgba10x6_formats 1 +#define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1 +#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats" +typedef struct VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 formatRgba10x6WithoutYCbCrSampler; +} VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; + + + #define VK_NV_acquire_winrt_display 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" @@ -12500,6 +13585,23 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT { +#define VK_EXT_depth_clip_control 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control" +typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClipControl; +} VkPhysicalDeviceDepthClipControlFeaturesEXT; + +typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 negativeOneToOne; +} VkPipelineViewportDepthClipControlCreateInfoEXT; + + + #define VK_EXT_primitive_topology_list_restart 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart" @@ -12660,22 +13762,43 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWrite #endif -#define VK_EXT_global_priority_query 1 -#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT 16U -#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 -#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" -typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT { +#define VK_EXT_primitives_generated_query 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query" +typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { VkStructureType sType; void* pNext; - VkBool32 globalPriorityQuery; -} VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + VkBool32 primitivesGeneratedQuery; + VkBool32 primitivesGeneratedQueryWithRasterizerDiscard; + VkBool32 primitivesGeneratedQueryWithNonZeroStreams; +} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT; -typedef struct VkQueueFamilyGlobalPriorityPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t priorityCount; - VkQueueGlobalPriorityEXT priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_EXT]; -} VkQueueFamilyGlobalPriorityPropertiesEXT; + + +#define VK_EXT_global_priority_query 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR +typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + +typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +#define VK_EXT_image_view_min_lod 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod" +typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 minLod; +} VkPhysicalDeviceImageViewMinLodFeaturesEXT; + +typedef struct VkImageViewMinLodCreateInfoEXT { + VkStructureType sType; + const void* pNext; + float minLod; +} VkImageViewMinLodCreateInfoEXT; @@ -12728,11 +13851,42 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( #endif +#define VK_EXT_image_2d_view_of_3d 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d" +typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 image2DViewOf3D; + VkBool32 sampler2DViewOf3D; +} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT; + + + #define VK_EXT_load_store_op_none 1 #define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 #define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" +#define VK_EXT_border_color_swizzle 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle" +typedef struct VkPhysicalDeviceBorderColorSwizzleFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 borderColorSwizzle; + VkBool32 borderColorSwizzleFromImage; +} VkPhysicalDeviceBorderColorSwizzleFeaturesEXT; + +typedef struct VkSamplerBorderColorComponentMappingCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkComponentMapping components; + VkBool32 srgb; +} VkSamplerBorderColorComponentMappingCreateInfoEXT; + + + #define VK_EXT_pageable_device_local_memory 1 #define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1 #define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory" @@ -12752,9 +13906,88 @@ VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( #endif +#define VK_VALVE_descriptor_set_host_mapping 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping" +typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 descriptorSetHostMapping; +} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE; + +typedef struct VkDescriptorSetBindingReferenceVALVE { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayout descriptorSetLayout; + uint32_t binding; +} VkDescriptorSetBindingReferenceVALVE; + +typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE { + VkStructureType sType; + void* pNext; + size_t descriptorOffset; + uint32_t descriptorSize; +} VkDescriptorSetLayoutHostMappingInfoVALVE; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( + VkDevice device, + const VkDescriptorSetBindingReferenceVALVE* pBindingReference, + VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( + VkDevice device, + VkDescriptorSet descriptorSet, + void** ppData); +#endif + + +#define VK_QCOM_fragment_density_map_offset 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapOffset; +} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; + +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent2D fragmentDensityOffsetGranularity; +} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; + +typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { + VkStructureType sType; + const void* pNext; + uint32_t fragmentDensityOffsetCount; + const VkOffset2D* pFragmentDensityOffsets; +} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; + + + +#define VK_NV_linear_color_attachment 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment" +typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 linearColorAttachment; +} VkPhysicalDeviceLinearColorAttachmentFeaturesNV; + + + +#define VK_GOOGLE_surfaceless_query 1 +#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 1 +#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query" + + #define VK_KHR_acceleration_structure 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) -#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12 +#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 #define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" typedef enum VkBuildAccelerationStructureModeKHR { diff --git a/vendor/vulkan/_gen/vulkan_ios.h b/vendor/vulkan/_gen/vulkan_ios.h index 6e7e6afea..579220543 100644 --- a/vendor/vulkan/_gen/vulkan_ios.h +++ b/vendor/vulkan/_gen/vulkan_ios.h @@ -2,7 +2,7 @@ #define VULKAN_IOS_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_macos.h b/vendor/vulkan/_gen/vulkan_macos.h index c49b123d0..8e197c7cf 100644 --- a/vendor/vulkan/_gen/vulkan_macos.h +++ b/vendor/vulkan/_gen/vulkan_macos.h @@ -2,7 +2,7 @@ #define VULKAN_MACOS_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_metal.h b/vendor/vulkan/_gen/vulkan_metal.h index 5cf4a703a..3631f1200 100644 --- a/vendor/vulkan/_gen/vulkan_metal.h +++ b/vendor/vulkan/_gen/vulkan_metal.h @@ -2,7 +2,7 @@ #define VULKAN_METAL_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_win32.h b/vendor/vulkan/_gen/vulkan_win32.h index 1b680f0b1..affe0c02a 100644 --- a/vendor/vulkan/_gen/vulkan_win32.h +++ b/vendor/vulkan/_gen/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index 67ca47553..94c667910 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -39,18 +39,15 @@ MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 MAX_EXTENSION_NAME_SIZE :: 256 MAX_DESCRIPTION_SIZE :: 256 -MAX_DEVICE_GROUP_SIZE_KHX :: 32 MAX_DEVICE_GROUP_SIZE :: 32 LUID_SIZE_KHX :: 8 -LUID_SIZE_KHR :: 8 LUID_SIZE :: 8 -MAX_DRIVER_NAME_SIZE_KHR :: 256 -MAX_DRIVER_INFO_SIZE_KHR :: 256 -MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(0)-1 +MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE_EXT :: 16 +QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL // General Constants -HEADER_VERSION :: 191 +HEADER_VERSION :: 211 MAX_DRIVER_NAME_SIZE :: 256 MAX_DRIVER_INFO_SIZE :: 256 @@ -70,6 +67,9 @@ KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_display_swapc KHR_sampler_mirror_clamp_to_edge :: 1 KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION :: 3 KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME :: "VK_KHR_sampler_mirror_clamp_to_edge" +KHR_dynamic_rendering :: 1 +KHR_DYNAMIC_RENDERING_SPEC_VERSION :: 1 +KHR_DYNAMIC_RENDERING_EXTENSION_NAME :: "VK_KHR_dynamic_rendering" KHR_multiview :: 1 KHR_MULTIVIEW_SPEC_VERSION :: 1 KHR_MULTIVIEW_EXTENSION_NAME :: "VK_KHR_multiview" @@ -83,17 +83,22 @@ KHR_shader_draw_parameters :: 1 KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION :: 1 KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME :: "VK_KHR_shader_draw_parameters" KHR_maintenance1 :: 1 -KHR_MAINTENANCE1_SPEC_VERSION :: 2 -KHR_MAINTENANCE1_EXTENSION_NAME :: "VK_KHR_maintenance1" +KHR_MAINTENANCE_1_SPEC_VERSION :: 2 +KHR_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_maintenance1" +KHR_MAINTENANCE1_SPEC_VERSION :: KHR_MAINTENANCE_1_SPEC_VERSION +KHR_MAINTENANCE1_EXTENSION_NAME :: KHR_MAINTENANCE_1_EXTENSION_NAME KHR_device_group_creation :: 1 KHR_DEVICE_GROUP_CREATION_SPEC_VERSION :: 1 KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME :: "VK_KHR_device_group_creation" +MAX_DEVICE_GROUP_SIZE_KHR :: MAX_DEVICE_GROUP_SIZE KHR_external_memory_capabilities :: 1 KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_memory_capabilities" +LUID_SIZE_KHR :: LUID_SIZE KHR_external_memory :: 1 KHR_EXTERNAL_MEMORY_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_KHR_external_memory" +QUEUE_FAMILY_EXTERNAL_KHR :: QUEUE_FAMILY_EXTERNAL KHR_external_memory_fd :: 1 KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME :: "VK_KHR_external_memory_fd" @@ -143,8 +148,10 @@ KHR_performance_query :: 1 KHR_PERFORMANCE_QUERY_SPEC_VERSION :: 1 KHR_PERFORMANCE_QUERY_EXTENSION_NAME :: "VK_KHR_performance_query" KHR_maintenance2 :: 1 -KHR_MAINTENANCE2_SPEC_VERSION :: 1 -KHR_MAINTENANCE2_EXTENSION_NAME :: "VK_KHR_maintenance2" +KHR_MAINTENANCE_2_SPEC_VERSION :: 1 +KHR_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_maintenance2" +KHR_MAINTENANCE2_SPEC_VERSION :: KHR_MAINTENANCE_2_SPEC_VERSION +KHR_MAINTENANCE2_EXTENSION_NAME :: KHR_MAINTENANCE_2_EXTENSION_NAME KHR_get_surface_capabilities2 :: 1 KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION :: 1 KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME :: "VK_KHR_get_surface_capabilities2" @@ -176,8 +183,10 @@ KHR_bind_memory2 :: 1 KHR_BIND_MEMORY_2_SPEC_VERSION :: 1 KHR_BIND_MEMORY_2_EXTENSION_NAME :: "VK_KHR_bind_memory2" KHR_maintenance3 :: 1 -KHR_MAINTENANCE3_SPEC_VERSION :: 1 -KHR_MAINTENANCE3_EXTENSION_NAME :: "VK_KHR_maintenance3" +KHR_MAINTENANCE_3_SPEC_VERSION :: 1 +KHR_MAINTENANCE_3_EXTENSION_NAME :: "VK_KHR_maintenance3" +KHR_MAINTENANCE3_SPEC_VERSION :: KHR_MAINTENANCE_3_SPEC_VERSION +KHR_MAINTENANCE3_EXTENSION_NAME :: KHR_MAINTENANCE_3_EXTENSION_NAME KHR_draw_indirect_count :: 1 KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 1 KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_KHR_draw_indirect_count" @@ -193,9 +202,15 @@ KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME :: "VK_KHR_shader_atomic KHR_shader_clock :: 1 KHR_SHADER_CLOCK_SPEC_VERSION :: 1 KHR_SHADER_CLOCK_EXTENSION_NAME :: "VK_KHR_shader_clock" +KHR_global_priority :: 1 +MAX_GLOBAL_PRIORITY_SIZE_KHR :: 16 +KHR_GLOBAL_PRIORITY_SPEC_VERSION :: 1 +KHR_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_KHR_global_priority" KHR_driver_properties :: 1 KHR_DRIVER_PROPERTIES_SPEC_VERSION :: 1 KHR_DRIVER_PROPERTIES_EXTENSION_NAME :: "VK_KHR_driver_properties" +MAX_DRIVER_NAME_SIZE_KHR :: MAX_DRIVER_NAME_SIZE +MAX_DRIVER_INFO_SIZE_KHR :: MAX_DRIVER_INFO_SIZE KHR_shader_float_controls :: 1 KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION :: 4 KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME :: "VK_KHR_shader_float_controls" @@ -215,7 +230,7 @@ KHR_shader_terminate_invocation :: 1 KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION :: 1 KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME :: "VK_KHR_shader_terminate_invocation" KHR_fragment_shading_rate :: 1 -KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 1 +KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 2 KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME :: "VK_KHR_fragment_shading_rate" KHR_spirv_1_4 :: 1 KHR_SPIRV_1_4_SPEC_VERSION :: 1 @@ -268,6 +283,15 @@ KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME :: "VK_KHR_workgroup_mem KHR_copy_commands2 :: 1 KHR_COPY_COMMANDS_2_SPEC_VERSION :: 1 KHR_COPY_COMMANDS_2_EXTENSION_NAME :: "VK_KHR_copy_commands2" +KHR_format_feature_flags2 :: 1 +KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION :: 1 +KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME :: "VK_KHR_format_feature_flags2" +KHR_portability_enumeration :: 1 +KHR_PORTABILITY_ENUMERATION_SPEC_VERSION :: 1 +KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME :: "VK_KHR_portability_enumeration" +KHR_maintenance4 :: 1 +KHR_MAINTENANCE_4_SPEC_VERSION :: 2 +KHR_MAINTENANCE_4_EXTENSION_NAME :: "VK_KHR_maintenance4" EXT_debug_report :: 1 EXT_DEBUG_REPORT_SPEC_VERSION :: 10 EXT_DEBUG_REPORT_EXTENSION_NAME :: "VK_EXT_debug_report" @@ -374,8 +398,10 @@ NV_geometry_shader_passthrough :: 1 NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION :: 1 NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME :: "VK_NV_geometry_shader_passthrough" NV_viewport_array2 :: 1 -NV_VIEWPORT_ARRAY2_SPEC_VERSION :: 1 -NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: "VK_NV_viewport_array2" +NV_VIEWPORT_ARRAY_2_SPEC_VERSION :: 1 +NV_VIEWPORT_ARRAY_2_EXTENSION_NAME :: "VK_NV_viewport_array2" +NV_VIEWPORT_ARRAY2_SPEC_VERSION :: NV_VIEWPORT_ARRAY_2_SPEC_VERSION +NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: NV_VIEWPORT_ARRAY_2_EXTENSION_NAME NVX_multiview_per_view_attributes :: 1 NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION :: 1 NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME :: "VK_NVX_multiview_per_view_attributes" @@ -446,7 +472,7 @@ EXT_post_depth_coverage :: 1 EXT_POST_DEPTH_COVERAGE_SPEC_VERSION :: 1 EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME :: "VK_EXT_post_depth_coverage" EXT_image_drm_format_modifier :: 1 -EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 1 +EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 2 EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME :: "VK_EXT_image_drm_format_modifier" EXT_validation_cache :: 1 EXT_VALIDATION_CACHE_SPEC_VERSION :: 1 @@ -463,6 +489,7 @@ NV_SHADING_RATE_IMAGE_EXTENSION_NAME :: "VK_NV_shading_rate_i NV_ray_tracing :: 1 NV_RAY_TRACING_SPEC_VERSION :: 3 NV_RAY_TRACING_EXTENSION_NAME :: "VK_NV_ray_tracing" +SHADER_UNUSED_KHR :: 0 NV_representative_fragment_test :: 1 NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION :: 2 NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME :: "VK_NV_representative_fragment_test" @@ -524,14 +551,16 @@ AMD_display_native_hdr :: 1 AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION :: 1 AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME :: "VK_AMD_display_native_hdr" EXT_fragment_density_map :: 1 -EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 1 +EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 2 EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME :: "VK_EXT_fragment_density_map" EXT_scalar_block_layout :: 1 EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION :: 1 EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_EXT_scalar_block_layout" GOOGLE_hlsl_functionality1 :: 1 -GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: 1 -GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" +GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION :: 1 +GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" +GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME GOOGLE_decorate_string :: 1 GOOGLE_DECORATE_STRING_SPEC_VERSION :: 1 GOOGLE_DECORATE_STRING_EXTENSION_NAME :: "VK_GOOGLE_decorate_string" @@ -640,6 +669,9 @@ EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME :: "VK_EXT_pipeline_crea NV_device_diagnostics_config :: 1 NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION :: 1 NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME :: "VK_NV_device_diagnostics_config" +EXT_graphics_pipeline_library :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_EXT_graphics_pipeline_library" NV_fragment_shading_rate_enums :: 1 NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION :: 1 NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME :: "VK_NV_fragment_shading_rate_enums" @@ -658,6 +690,9 @@ EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_image_robustn EXT_4444_formats :: 1 EXT_4444_FORMATS_SPEC_VERSION :: 1 EXT_4444_FORMATS_EXTENSION_NAME :: "VK_EXT_4444_formats" +EXT_rgba10x6_formats :: 1 +EXT_RGBA10X6_FORMATS_SPEC_VERSION :: 1 +EXT_RGBA10X6_FORMATS_EXTENSION_NAME :: "VK_EXT_rgba10x6_formats" NV_acquire_winrt_display :: 1 NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION :: 1 NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME :: "VK_NV_acquire_winrt_display" @@ -667,6 +702,9 @@ EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_vertex_input_ EXT_physical_device_drm :: 1 EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION :: 1 EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME :: "VK_EXT_physical_device_drm" +EXT_depth_clip_control :: 1 +EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION :: 1 +EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clip_control" EXT_primitive_topology_list_restart :: 1 EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION :: 1 EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME :: "VK_EXT_primitive_topology_list_restart" @@ -679,20 +717,38 @@ EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME :: "VK_EXT_extended_dyna EXT_color_write_enable :: 1 EXT_COLOR_WRITE_ENABLE_SPEC_VERSION :: 1 EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME :: "VK_EXT_color_write_enable" +EXT_primitives_generated_query :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME :: "VK_EXT_primitives_generated_query" EXT_global_priority_query :: 1 EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION :: 1 EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME :: "VK_EXT_global_priority_query" +EXT_image_view_min_lod :: 1 +EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION :: 1 +EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME :: "VK_EXT_image_view_min_lod" EXT_multi_draw :: 1 EXT_MULTI_DRAW_SPEC_VERSION :: 1 EXT_MULTI_DRAW_EXTENSION_NAME :: "VK_EXT_multi_draw" +EXT_image_2d_view_of_3d :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_2d_view_of_3d" EXT_load_store_op_none :: 1 EXT_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_EXT_load_store_op_none" +EXT_border_color_swizzle :: 1 +EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION :: 1 +EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME :: "VK_EXT_border_color_swizzle" EXT_pageable_device_local_memory :: 1 EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION :: 1 EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME :: "VK_EXT_pageable_device_local_memory" +NV_linear_color_attachment :: 1 +NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION :: 1 +NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME :: "VK_NV_linear_color_attachment" +GOOGLE_surfaceless_query :: 1 +GOOGLE_SURFACELESS_QUERY_SPEC_VERSION :: 1 +GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME :: "VK_GOOGLE_surfaceless_query" KHR_acceleration_structure :: 1 -KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 12 +KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 13 KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_KHR_acceleration_structure" KHR_ray_tracing_pipeline :: 1 KHR_RAY_TRACING_PIPELINE_SPEC_VERSION :: 1 @@ -756,6 +812,7 @@ Framebuffer :: distinct NonDispatchableHandle CommandPool :: distinct NonDispatchableHandle SamplerYcbcrConversion :: distinct NonDispatchableHandle DescriptorUpdateTemplate :: distinct NonDispatchableHandle +PrivateDataSlot :: distinct NonDispatchableHandle SurfaceKHR :: distinct NonDispatchableHandle SwapchainKHR :: distinct NonDispatchableHandle DisplayKHR :: distinct NonDispatchableHandle @@ -769,7 +826,6 @@ ValidationCacheEXT :: distinct NonDispatchableHandle AccelerationStructureNV :: distinct NonDispatchableHandle PerformanceConfigurationINTEL :: distinct NonDispatchableHandle IndirectCommandsLayoutNV :: distinct NonDispatchableHandle -PrivateDataSlotEXT :: distinct NonDispatchableHandle AccelerationStructureKHR :: distinct NonDispatchableHandle diff --git a/vendor/vulkan/enums.odin b/vendor/vulkan/enums.odin index be6691ab4..b2eec06ab 100644 --- a/vendor/vulkan/enums.odin +++ b/vendor/vulkan/enums.odin @@ -78,7 +78,7 @@ AccessFlag :: enum Flags { ACCELERATION_STRUCTURE_WRITE_NV = ACCELERATION_STRUCTURE_WRITE_KHR, } -AccessFlags_NONE_KHR :: AccessFlags{} +AccessFlags_NONE :: AccessFlags{} AcquireProfilingLockFlagsKHR :: distinct bit_set[AcquireProfilingLockFlagKHR; Flags] @@ -100,8 +100,7 @@ AttachmentLoadOp :: enum c.int { AttachmentStoreOp :: enum c.int { STORE = 0, DONT_CARE = 1, - NONE_EXT = 1000301000, - NONE_QCOM = NONE_EXT, + NONE = 1000301000, } BlendFactor :: enum c.int { @@ -460,6 +459,7 @@ DebugReportObjectTypeEXT :: enum c.int { CU_FUNCTION_NVX = 1000029001, ACCELERATION_STRUCTURE_KHR = 1000150000, ACCELERATION_STRUCTURE_NV = 1000165000, + BUFFER_COLLECTION_FUCHSIA = 1000366000, DEBUG_REPORT = DEBUG_REPORT_CALLBACK_EXT, VALIDATION_CACHE = VALIDATION_CACHE_EXT, DESCRIPTOR_UPDATE_TEMPLATE_KHR = DESCRIPTOR_UPDATE_TEMPLATE, @@ -530,10 +530,11 @@ DescriptorType :: enum c.int { UNIFORM_BUFFER_DYNAMIC = 8, STORAGE_BUFFER_DYNAMIC = 9, INPUT_ATTACHMENT = 10, - INLINE_UNIFORM_BLOCK_EXT = 1000138000, + INLINE_UNIFORM_BLOCK = 1000138000, ACCELERATION_STRUCTURE_KHR = 1000150000, ACCELERATION_STRUCTURE_NV = 1000165000, MUTABLE_VALVE = 1000351000, + INLINE_UNIFORM_BLOCK_EXT = INLINE_UNIFORM_BLOCK, } DescriptorUpdateTemplateType :: enum c.int { @@ -615,6 +616,11 @@ DriverId :: enum c.int { COREAVI_PROPRIETARY = 15, JUICE_PROPRIETARY = 16, VERISILICON_PROPRIETARY = 17, + MESA_TURNIP = 18, + MESA_V3DV = 19, + MESA_PANVK = 20, + SAMSUNG_PROPRIETARY = 21, + MESA_VENUS = 22, AMD_PROPRIETARY_KHR = AMD_PROPRIETARY, AMD_OPEN_SOURCE_KHR = AMD_OPEN_SOURCE, MESA_RADV_KHR = MESA_RADV, @@ -639,6 +645,21 @@ DynamicState :: enum c.int { STENCIL_COMPARE_MASK = 6, STENCIL_WRITE_MASK = 7, STENCIL_REFERENCE = 8, + CULL_MODE = 1000267000, + FRONT_FACE = 1000267001, + PRIMITIVE_TOPOLOGY = 1000267002, + VIEWPORT_WITH_COUNT = 1000267003, + SCISSOR_WITH_COUNT = 1000267004, + VERTEX_INPUT_BINDING_STRIDE = 1000267005, + DEPTH_TEST_ENABLE = 1000267006, + DEPTH_WRITE_ENABLE = 1000267007, + DEPTH_COMPARE_OP = 1000267008, + DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + STENCIL_TEST_ENABLE = 1000267010, + STENCIL_OP = 1000267011, + RASTERIZER_DISCARD_ENABLE = 1000377001, + DEPTH_BIAS_ENABLE = 1000377002, + PRIMITIVE_RESTART_ENABLE = 1000377004, VIEWPORT_W_SCALING_NV = 1000087000, DISCARD_RECTANGLE_EXT = 1000099000, SAMPLE_LOCATIONS_EXT = 1000143000, @@ -648,30 +669,31 @@ DynamicState :: enum c.int { EXCLUSIVE_SCISSOR_NV = 1000205001, FRAGMENT_SHADING_RATE_KHR = 1000226000, LINE_STIPPLE_EXT = 1000259000, - CULL_MODE_EXT = 1000267000, - FRONT_FACE_EXT = 1000267001, - PRIMITIVE_TOPOLOGY_EXT = 1000267002, - VIEWPORT_WITH_COUNT_EXT = 1000267003, - SCISSOR_WITH_COUNT_EXT = 1000267004, - VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, - DEPTH_TEST_ENABLE_EXT = 1000267006, - DEPTH_WRITE_ENABLE_EXT = 1000267007, - DEPTH_COMPARE_OP_EXT = 1000267008, - DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, - STENCIL_TEST_ENABLE_EXT = 1000267010, - STENCIL_OP_EXT = 1000267011, VERTEX_INPUT_EXT = 1000352000, PATCH_CONTROL_POINTS_EXT = 1000377000, - RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, - DEPTH_BIAS_ENABLE_EXT = 1000377002, LOGIC_OP_EXT = 1000377003, - PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, COLOR_WRITE_ENABLE_EXT = 1000381000, + CULL_MODE_EXT = CULL_MODE, + FRONT_FACE_EXT = FRONT_FACE, + PRIMITIVE_TOPOLOGY_EXT = PRIMITIVE_TOPOLOGY, + VIEWPORT_WITH_COUNT_EXT = VIEWPORT_WITH_COUNT, + SCISSOR_WITH_COUNT_EXT = SCISSOR_WITH_COUNT, + VERTEX_INPUT_BINDING_STRIDE_EXT = VERTEX_INPUT_BINDING_STRIDE, + DEPTH_TEST_ENABLE_EXT = DEPTH_TEST_ENABLE, + DEPTH_WRITE_ENABLE_EXT = DEPTH_WRITE_ENABLE, + DEPTH_COMPARE_OP_EXT = DEPTH_COMPARE_OP, + DEPTH_BOUNDS_TEST_ENABLE_EXT = DEPTH_BOUNDS_TEST_ENABLE, + STENCIL_TEST_ENABLE_EXT = STENCIL_TEST_ENABLE, + STENCIL_OP_EXT = STENCIL_OP, + RASTERIZER_DISCARD_ENABLE_EXT = RASTERIZER_DISCARD_ENABLE, + DEPTH_BIAS_ENABLE_EXT = DEPTH_BIAS_ENABLE, + PRIMITIVE_RESTART_ENABLE_EXT = PRIMITIVE_RESTART_ENABLE, } EventCreateFlags :: distinct bit_set[EventCreateFlag; Flags] EventCreateFlag :: enum Flags { - DEVICE_ONLY_KHR = 0, + DEVICE_ONLY = 0, + DEVICE_ONLY_KHR = DEVICE_ONLY, } ExternalFenceFeatureFlags :: distinct bit_set[ExternalFenceFeatureFlag; Flags] @@ -1005,6 +1027,26 @@ Format :: enum c.int { G16_B16_R16_3PLANE_422_UNORM = 1000156031, G16_B16R16_2PLANE_422_UNORM = 1000156032, G16_B16_R16_3PLANE_444_UNORM = 1000156033, + G8_B8R8_2PLANE_444_UNORM = 1000330000, + G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + G16_B16R16_2PLANE_444_UNORM = 1000330003, + A4R4G4B4_UNORM_PACK16 = 1000340000, + A4B4G4R4_UNORM_PACK16 = 1000340001, + ASTC_4x4_SFLOAT_BLOCK = 1000066000, + ASTC_5x4_SFLOAT_BLOCK = 1000066001, + ASTC_5x5_SFLOAT_BLOCK = 1000066002, + ASTC_6x5_SFLOAT_BLOCK = 1000066003, + ASTC_6x6_SFLOAT_BLOCK = 1000066004, + ASTC_8x5_SFLOAT_BLOCK = 1000066005, + ASTC_8x6_SFLOAT_BLOCK = 1000066006, + ASTC_8x8_SFLOAT_BLOCK = 1000066007, + ASTC_10x5_SFLOAT_BLOCK = 1000066008, + ASTC_10x6_SFLOAT_BLOCK = 1000066009, + ASTC_10x8_SFLOAT_BLOCK = 1000066010, + ASTC_10x10_SFLOAT_BLOCK = 1000066011, + ASTC_12x10_SFLOAT_BLOCK = 1000066012, + ASTC_12x12_SFLOAT_BLOCK = 1000066013, PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1013,26 +1055,20 @@ Format :: enum c.int { PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, - ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, - ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, - ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, - ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, - ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, - ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, - ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, - ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, - ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, - ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, - ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, - ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, - ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, - G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, - G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, - G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, - G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, - A4R4G4B4_UNORM_PACK16_EXT = 1000340000, - A4B4G4R4_UNORM_PACK16_EXT = 1000340001, + ASTC_4x4_SFLOAT_BLOCK_EXT = ASTC_4x4_SFLOAT_BLOCK, + ASTC_5x4_SFLOAT_BLOCK_EXT = ASTC_5x4_SFLOAT_BLOCK, + ASTC_5x5_SFLOAT_BLOCK_EXT = ASTC_5x5_SFLOAT_BLOCK, + ASTC_6x5_SFLOAT_BLOCK_EXT = ASTC_6x5_SFLOAT_BLOCK, + ASTC_6x6_SFLOAT_BLOCK_EXT = ASTC_6x6_SFLOAT_BLOCK, + ASTC_8x5_SFLOAT_BLOCK_EXT = ASTC_8x5_SFLOAT_BLOCK, + ASTC_8x6_SFLOAT_BLOCK_EXT = ASTC_8x6_SFLOAT_BLOCK, + ASTC_8x8_SFLOAT_BLOCK_EXT = ASTC_8x8_SFLOAT_BLOCK, + ASTC_10x5_SFLOAT_BLOCK_EXT = ASTC_10x5_SFLOAT_BLOCK, + ASTC_10x6_SFLOAT_BLOCK_EXT = ASTC_10x6_SFLOAT_BLOCK, + ASTC_10x8_SFLOAT_BLOCK_EXT = ASTC_10x8_SFLOAT_BLOCK, + ASTC_10x10_SFLOAT_BLOCK_EXT = ASTC_10x10_SFLOAT_BLOCK, + ASTC_12x10_SFLOAT_BLOCK_EXT = ASTC_12x10_SFLOAT_BLOCK, + ASTC_12x12_SFLOAT_BLOCK_EXT = ASTC_12x12_SFLOAT_BLOCK, G8B8G8R8_422_UNORM_KHR = G8B8G8R8_422_UNORM, B8G8R8G8_422_UNORM_KHR = B8G8R8G8_422_UNORM, G8_B8_R8_3PLANE_420_UNORM_KHR = G8_B8_R8_3PLANE_420_UNORM, @@ -1067,6 +1103,12 @@ Format :: enum c.int { G16_B16_R16_3PLANE_422_UNORM_KHR = G16_B16_R16_3PLANE_422_UNORM, G16_B16R16_2PLANE_422_UNORM_KHR = G16_B16R16_2PLANE_422_UNORM, G16_B16_R16_3PLANE_444_UNORM_KHR = G16_B16_R16_3PLANE_444_UNORM, + G8_B8R8_2PLANE_444_UNORM_EXT = G8_B8R8_2PLANE_444_UNORM, + G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + G16_B16R16_2PLANE_444_UNORM_EXT = G16_B16R16_2PLANE_444_UNORM, + A4R4G4B4_UNORM_PACK16_EXT = A4R4G4B4_UNORM_PACK16, + A4B4G4R4_UNORM_PACK16_EXT = A4B4G4R4_UNORM_PACK16, } FormatFeatureFlags :: distinct bit_set[FormatFeatureFlag; Flags] @@ -1190,6 +1232,14 @@ GeometryTypeKHR :: enum c.int { AABBS_NV = AABBS, } +GraphicsPipelineLibraryFlagsEXT :: distinct bit_set[GraphicsPipelineLibraryFlagEXT; Flags] +GraphicsPipelineLibraryFlagEXT :: enum Flags { + VERTEX_INPUT_INTERFACE = 0, + PRE_RASTERIZATION_SHADERS = 1, + FRAGMENT_SHADER = 2, + FRAGMENT_OUTPUT_INTERFACE = 3, +} + ImageAspectFlags :: distinct bit_set[ImageAspectFlag; Flags] ImageAspectFlag :: enum Flags { COLOR = 0, @@ -1208,6 +1258,9 @@ ImageAspectFlag :: enum Flags { PLANE_2_KHR = PLANE_2, } +ImageAspectFlags_NONE :: ImageAspectFlags{} + + ImageCreateFlags :: distinct bit_set[ImageCreateFlag; Flags] ImageCreateFlag :: enum Flags { SPARSE_BINDING = 0, @@ -1225,6 +1278,8 @@ ImageCreateFlag :: enum Flags { CORNER_SAMPLED_NV = 13, SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_EXT = 12, SUBSAMPLED_EXT = 14, + D2_VIEW_COMPATIBLE_EXT = 17, + FRAGMENT_DENSITY_MAP_OFFSET_QCOM = 15, SPLIT_INSTANCE_BIND_REGIONS_KHR = SPLIT_INSTANCE_BIND_REGIONS, D2_ARRAY_COMPATIBLE_KHR = D2_ARRAY_COMPATIBLE, BLOCK_TEXEL_VIEW_COMPATIBLE_KHR = BLOCK_TEXEL_VIEW_COMPATIBLE, @@ -1249,6 +1304,8 @@ ImageLayout :: enum c.int { DEPTH_READ_ONLY_OPTIMAL = 1000241001, STENCIL_ATTACHMENT_OPTIMAL = 1000241002, STENCIL_READ_ONLY_OPTIMAL = 1000241003, + READ_ONLY_OPTIMAL = 1000314000, + ATTACHMENT_OPTIMAL = 1000314001, PRESENT_SRC_KHR = 1000001002, VIDEO_DECODE_DST_KHR = 1000024000, VIDEO_DECODE_SRC_KHR = 1000024001, @@ -1259,8 +1316,6 @@ ImageLayout :: enum c.int { VIDEO_ENCODE_DST_KHR = 1000299000, VIDEO_ENCODE_SRC_KHR = 1000299001, VIDEO_ENCODE_DPB_KHR = 1000299002, - READ_ONLY_OPTIMAL_KHR = 1000314000, - ATTACHMENT_OPTIMAL_KHR = 1000314001, DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, SHADING_RATE_OPTIMAL_NV = FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1268,6 +1323,8 @@ ImageLayout :: enum c.int { DEPTH_READ_ONLY_OPTIMAL_KHR = DEPTH_READ_ONLY_OPTIMAL, STENCIL_ATTACHMENT_OPTIMAL_KHR = STENCIL_ATTACHMENT_OPTIMAL, STENCIL_READ_ONLY_OPTIMAL_KHR = STENCIL_READ_ONLY_OPTIMAL, + READ_ONLY_OPTIMAL_KHR = READ_ONLY_OPTIMAL, + ATTACHMENT_OPTIMAL_KHR = ATTACHMENT_OPTIMAL, } ImageTiling :: enum c.int { @@ -1351,6 +1408,11 @@ IndirectStateFlagNV :: enum Flags { FLAG_FRONTFACE = 0, } +InstanceCreateFlags :: distinct bit_set[InstanceCreateFlag; Flags] +InstanceCreateFlag :: enum Flags { + ENUMERATE_PORTABILITY_KHR = 0, +} + InternalAllocationType :: enum c.int { EXECUTABLE = 0, } @@ -1446,6 +1508,7 @@ ObjectType :: enum c.int { COMMAND_POOL = 25, SAMPLER_YCBCR_CONVERSION = 1000156000, DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + PRIVATE_DATA_SLOT = 1000295000, SURFACE_KHR = 1000000000, SWAPCHAIN_KHR = 1000001000, DISPLAY_KHR = 1000002000, @@ -1462,9 +1525,10 @@ ObjectType :: enum c.int { PERFORMANCE_CONFIGURATION_INTEL = 1000210000, DEFERRED_OPERATION_KHR = 1000268000, INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - PRIVATE_DATA_SLOT_EXT = 1000295000, + BUFFER_COLLECTION_FUCHSIA = 1000366000, DESCRIPTOR_UPDATE_TEMPLATE_KHR = DESCRIPTOR_UPDATE_TEMPLATE, SAMPLER_YCBCR_CONVERSION_KHR = SAMPLER_YCBCR_CONVERSION, + PRIVATE_DATA_SLOT_EXT = PRIVATE_DATA_SLOT, } PeerMemoryFeatureFlags :: distinct bit_set[PeerMemoryFeatureFlag; Flags] @@ -1557,48 +1621,71 @@ PipelineBindPoint :: enum c.int { PipelineCacheCreateFlags :: distinct bit_set[PipelineCacheCreateFlag; Flags] PipelineCacheCreateFlag :: enum Flags { - EXTERNALLY_SYNCHRONIZED_EXT = 0, + EXTERNALLY_SYNCHRONIZED = 0, + EXTERNALLY_SYNCHRONIZED_EXT = EXTERNALLY_SYNCHRONIZED, } PipelineCacheHeaderVersion :: enum c.int { ONE = 1, } +PipelineColorBlendStateCreateFlags :: distinct bit_set[PipelineColorBlendStateCreateFlag; Flags] +PipelineColorBlendStateCreateFlag :: enum Flags { + RASTERIZATION_ORDER_ATTACHMENT_ACCESS_ARM = 0, +} + PipelineCompilerControlFlagsAMD :: distinct bit_set[PipelineCompilerControlFlagAMD; Flags] PipelineCompilerControlFlagAMD :: enum Flags { } PipelineCreateFlags :: distinct bit_set[PipelineCreateFlag; Flags] PipelineCreateFlag :: enum Flags { - DISABLE_OPTIMIZATION = 0, - ALLOW_DERIVATIVES = 1, - DERIVATIVE = 2, - VIEW_INDEX_FROM_DEVICE_INDEX = 3, - DISPATCH_BASE = 4, - RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_KHR = 14, - RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_KHR = 15, - RAY_TRACING_NO_NULL_MISS_SHADERS_KHR = 16, - RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_KHR = 17, - RAY_TRACING_SKIP_TRIANGLES_KHR = 12, - RAY_TRACING_SKIP_AABBS_KHR = 13, - RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_KHR = 19, - DEFER_COMPILE_NV = 5, - CAPTURE_STATISTICS_KHR = 6, - CAPTURE_INTERNAL_REPRESENTATIONS_KHR = 7, - INDIRECT_BINDABLE_NV = 18, - LIBRARY_KHR = 11, - FAIL_ON_PIPELINE_COMPILE_REQUIRED_EXT = 8, - EARLY_RETURN_ON_FAILURE_EXT = 9, - RAY_TRACING_ALLOW_MOTION_NV = 20, - VIEW_INDEX_FROM_DEVICE_INDEX_KHR = VIEW_INDEX_FROM_DEVICE_INDEX, - DISPATCH_BASE_KHR = DISPATCH_BASE, + DISABLE_OPTIMIZATION = 0, + ALLOW_DERIVATIVES = 1, + DERIVATIVE = 2, + VIEW_INDEX_FROM_DEVICE_INDEX = 3, + DISPATCH_BASE = 4, + FAIL_ON_PIPELINE_COMPILE_REQUIRED = 8, + EARLY_RETURN_ON_FAILURE = 9, + RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR = 21, + RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT = 22, + RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_KHR = 14, + RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_KHR = 15, + RAY_TRACING_NO_NULL_MISS_SHADERS_KHR = 16, + RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_KHR = 17, + RAY_TRACING_SKIP_TRIANGLES_KHR = 12, + RAY_TRACING_SKIP_AABBS_KHR = 13, + RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_KHR = 19, + DEFER_COMPILE_NV = 5, + CAPTURE_STATISTICS_KHR = 6, + CAPTURE_INTERNAL_REPRESENTATIONS_KHR = 7, + INDIRECT_BINDABLE_NV = 18, + LIBRARY_KHR = 11, + RETAIN_LINK_TIME_OPTIMIZATION_INFO_EXT = 23, + LINK_TIME_OPTIMIZATION_EXT = 10, + RAY_TRACING_ALLOW_MOTION_NV = 20, + PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR = RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR, + PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT = RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT, + VIEW_INDEX_FROM_DEVICE_INDEX_KHR = VIEW_INDEX_FROM_DEVICE_INDEX, + DISPATCH_BASE_KHR = DISPATCH_BASE, + FAIL_ON_PIPELINE_COMPILE_REQUIRED_EXT = FAIL_ON_PIPELINE_COMPILE_REQUIRED, + EARLY_RETURN_ON_FAILURE_EXT = EARLY_RETURN_ON_FAILURE, } -PipelineCreationFeedbackFlagsEXT :: distinct bit_set[PipelineCreationFeedbackFlagEXT; Flags] -PipelineCreationFeedbackFlagEXT :: enum Flags { - VALID = 0, - APPLICATION_PIPELINE_CACHE_HIT = 1, - BASE_PIPELINE_ACCELERATION = 2, +PipelineCreationFeedbackFlags :: distinct bit_set[PipelineCreationFeedbackFlag; Flags] +PipelineCreationFeedbackFlag :: enum Flags { + VALID = 0, + APPLICATION_PIPELINE_CACHE_HIT = 1, + BASE_PIPELINE_ACCELERATION = 2, + VALID_EXT = VALID, + APPLICATION_PIPELINE_CACHE_HIT_EXT = APPLICATION_PIPELINE_CACHE_HIT, + BASE_PIPELINE_ACCELERATION_EXT = BASE_PIPELINE_ACCELERATION, +} + +PipelineDepthStencilStateCreateFlags :: distinct bit_set[PipelineDepthStencilStateCreateFlag; Flags] +PipelineDepthStencilStateCreateFlag :: enum Flags { + RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_ARM = 0, + RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_ARM = 1, } PipelineExecutableStatisticFormatKHR :: enum c.int { @@ -1608,10 +1695,17 @@ PipelineExecutableStatisticFormatKHR :: enum c.int { FLOAT64 = 3, } +PipelineLayoutCreateFlags :: distinct bit_set[PipelineLayoutCreateFlag; Flags] +PipelineLayoutCreateFlag :: enum Flags { + INDEPENDENT_SETS_EXT = 1, +} + PipelineShaderStageCreateFlags :: distinct bit_set[PipelineShaderStageCreateFlag; Flags] PipelineShaderStageCreateFlag :: enum Flags { - ALLOW_VARYING_SUBGROUP_SIZE_EXT = 0, - REQUIRE_FULL_SUBGROUPS_EXT = 1, + ALLOW_VARYING_SUBGROUP_SIZE = 0, + REQUIRE_FULL_SUBGROUPS = 1, + ALLOW_VARYING_SUBGROUP_SIZE_EXT = ALLOW_VARYING_SUBGROUP_SIZE, + REQUIRE_FULL_SUBGROUPS_EXT = REQUIRE_FULL_SUBGROUPS, } PipelineStageFlags :: distinct bit_set[PipelineStageFlag; Flags] @@ -1647,7 +1741,7 @@ PipelineStageFlag :: enum Flags { ACCELERATION_STRUCTURE_BUILD_NV = ACCELERATION_STRUCTURE_BUILD_KHR, } -PipelineStageFlags_NONE_KHR :: PipelineStageFlags{} +PipelineStageFlags_NONE :: PipelineStageFlags{} PointClippingBehavior :: enum c.int { @@ -1687,10 +1781,6 @@ PrimitiveTopology :: enum c.int { PATCH_LIST = 10, } -PrivateDataSlotCreateFlagsEXT :: distinct bit_set[PrivateDataSlotCreateFlagEXT; Flags] -PrivateDataSlotCreateFlagEXT :: enum Flags { -} - ProvokingVertexModeEXT :: enum c.int { FIRST_VERTEX = 0, LAST_VERTEX = 1, @@ -1741,6 +1831,7 @@ QueryType :: enum c.int { ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, PERFORMANCE_QUERY_INTEL = 1000210000, VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, + PRIMITIVES_GENERATED_EXT = 1000382000, } QueueFlags :: distinct bit_set[QueueFlag; Flags] @@ -1754,11 +1845,15 @@ QueueFlag :: enum Flags { VIDEO_ENCODE_KHR = 6, } -QueueGlobalPriorityEXT :: enum c.int { - LOW = 128, - MEDIUM = 256, - HIGH = 512, - REALTIME = 1024, +QueueGlobalPriorityKHR :: enum c.int { + LOW = 128, + MEDIUM = 256, + HIGH = 512, + REALTIME = 1024, + LOW_EXT = LOW, + MEDIUM_EXT = MEDIUM, + HIGH_EXT = HIGH, + REALTIME_EXT = REALTIME, } RasterizationOrderAMD :: enum c.int { @@ -1780,6 +1875,16 @@ RenderPassCreateFlag :: enum Flags { TRANSFORM_QCOM = 1, } +RenderingFlags :: distinct bit_set[RenderingFlag; Flags] +RenderingFlag :: enum Flags { + CONTENTS_SECONDARY_COMMAND_BUFFERS = 0, + SUSPENDING = 1, + RESUMING = 2, + CONTENTS_SECONDARY_COMMAND_BUFFERS_KHR = CONTENTS_SECONDARY_COMMAND_BUFFERS, + SUSPENDING_KHR = SUSPENDING, + RESUMING_KHR = RESUMING, +} + ResolveModeFlags :: distinct bit_set[ResolveModeFlag; Flags] ResolveModeFlag :: enum Flags { SAMPLE_ZERO = 0, @@ -1819,6 +1924,7 @@ Result :: enum c.int { ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, ERROR_FRAGMENTATION = -1000161000, ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + PIPELINE_COMPILE_REQUIRED = 1000297000, ERROR_SURFACE_LOST_KHR = -1000000000, ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, SUBOPTIMAL_KHR = 1000001003, @@ -1827,19 +1933,20 @@ Result :: enum c.int { ERROR_VALIDATION_FAILED_EXT = -1000011001, ERROR_INVALID_SHADER_NV = -1000012000, ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - ERROR_NOT_PERMITTED_EXT = -1000174001, + ERROR_NOT_PERMITTED_KHR = -1000174001, ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, THREAD_IDLE_KHR = 1000268000, THREAD_DONE_KHR = 1000268001, OPERATION_DEFERRED_KHR = 1000268002, OPERATION_NOT_DEFERRED_KHR = 1000268003, - PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, ERROR_OUT_OF_POOL_MEMORY_KHR = ERROR_OUT_OF_POOL_MEMORY, ERROR_INVALID_EXTERNAL_HANDLE_KHR = ERROR_INVALID_EXTERNAL_HANDLE, ERROR_FRAGMENTATION_EXT = ERROR_FRAGMENTATION, + ERROR_NOT_PERMITTED_EXT = ERROR_NOT_PERMITTED_KHR, ERROR_INVALID_DEVICE_ADDRESS_EXT = ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED_EXT, + PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED, + ERROR_PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED, } SampleCountFlags :: distinct bit_set[SampleCountFlag; Flags] @@ -2036,692 +2143,809 @@ StencilOp :: enum c.int { } StructureType :: enum c.int { - APPLICATION_INFO = 0, - INSTANCE_CREATE_INFO = 1, - DEVICE_QUEUE_CREATE_INFO = 2, - DEVICE_CREATE_INFO = 3, - SUBMIT_INFO = 4, - MEMORY_ALLOCATE_INFO = 5, - MAPPED_MEMORY_RANGE = 6, - BIND_SPARSE_INFO = 7, - FENCE_CREATE_INFO = 8, - SEMAPHORE_CREATE_INFO = 9, - EVENT_CREATE_INFO = 10, - QUERY_POOL_CREATE_INFO = 11, - BUFFER_CREATE_INFO = 12, - BUFFER_VIEW_CREATE_INFO = 13, - IMAGE_CREATE_INFO = 14, - IMAGE_VIEW_CREATE_INFO = 15, - SHADER_MODULE_CREATE_INFO = 16, - PIPELINE_CACHE_CREATE_INFO = 17, - PIPELINE_SHADER_STAGE_CREATE_INFO = 18, - PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, - PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, - PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, - PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, - PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, - PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, - PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, - PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, - PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, - GRAPHICS_PIPELINE_CREATE_INFO = 28, - COMPUTE_PIPELINE_CREATE_INFO = 29, - PIPELINE_LAYOUT_CREATE_INFO = 30, - SAMPLER_CREATE_INFO = 31, - DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, - DESCRIPTOR_POOL_CREATE_INFO = 33, - DESCRIPTOR_SET_ALLOCATE_INFO = 34, - WRITE_DESCRIPTOR_SET = 35, - COPY_DESCRIPTOR_SET = 36, - FRAMEBUFFER_CREATE_INFO = 37, - RENDER_PASS_CREATE_INFO = 38, - COMMAND_POOL_CREATE_INFO = 39, - COMMAND_BUFFER_ALLOCATE_INFO = 40, - COMMAND_BUFFER_INHERITANCE_INFO = 41, - COMMAND_BUFFER_BEGIN_INFO = 42, - RENDER_PASS_BEGIN_INFO = 43, - BUFFER_MEMORY_BARRIER = 44, - IMAGE_MEMORY_BARRIER = 45, - MEMORY_BARRIER = 46, - LOADER_INSTANCE_CREATE_INFO = 47, - LOADER_DEVICE_CREATE_INFO = 48, - PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, - BIND_BUFFER_MEMORY_INFO = 1000157000, - BIND_IMAGE_MEMORY_INFO = 1000157001, - PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, - MEMORY_DEDICATED_REQUIREMENTS = 1000127000, - MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, - MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, - DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, - DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, - DEVICE_GROUP_SUBMIT_INFO = 1000060005, - DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, - BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, - BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, - PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, - DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, - BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, - IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, - IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, - MEMORY_REQUIREMENTS_2 = 1000146003, - SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, - PHYSICAL_DEVICE_FEATURES_2 = 1000059000, - PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, - FORMAT_PROPERTIES_2 = 1000059002, - IMAGE_FORMAT_PROPERTIES_2 = 1000059003, - PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, - QUEUE_FAMILY_PROPERTIES_2 = 1000059005, - PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, - SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, - PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, - PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, - RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, - IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, - PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, - RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, - PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, - PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, - PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, - PROTECTED_SUBMIT_INFO = 1000145000, - PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, - PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, - DEVICE_QUEUE_INFO_2 = 1000145003, - SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, - SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, - BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, - IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, - PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, - SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, - DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, - PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, - EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, - PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, - EXTERNAL_BUFFER_PROPERTIES = 1000071003, - PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, - EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, - EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, - PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, - EXTERNAL_FENCE_PROPERTIES = 1000112001, - EXPORT_FENCE_CREATE_INFO = 1000113000, - EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, - PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, - EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, - PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, - DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, - PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, - PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, - PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, - PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, - PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, - IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, - ATTACHMENT_DESCRIPTION_2 = 1000109000, - ATTACHMENT_REFERENCE_2 = 1000109001, - SUBPASS_DESCRIPTION_2 = 1000109002, - SUBPASS_DEPENDENCY_2 = 1000109003, - RENDER_PASS_CREATE_INFO_2 = 1000109004, - SUBPASS_BEGIN_INFO = 1000109005, - SUBPASS_END_INFO = 1000109006, - PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, - PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, - PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, - PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, - PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, - DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, - PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, - SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, - PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, - IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, - PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, - SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, - PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, - PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, - FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, - FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, - RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, - PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, - PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, - PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, - ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, - ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, - PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, - SEMAPHORE_TYPE_CREATE_INFO = 1000207002, - TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, - SEMAPHORE_WAIT_INFO = 1000207004, - SEMAPHORE_SIGNAL_INFO = 1000207005, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, - BUFFER_DEVICE_ADDRESS_INFO = 1000244001, - BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, - MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, - DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, - SWAPCHAIN_CREATE_INFO_KHR = 1000001000, - PRESENT_INFO_KHR = 1000001001, - DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, - IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, - BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, - ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, - DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, - DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, - DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, - DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, - DISPLAY_PRESENT_INFO_KHR = 1000003000, - XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, - XCB_SURFACE_CREATE_INFO_KHR = 1000005000, - WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, - ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, - WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, - DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, - DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, - DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, - DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, - VIDEO_PROFILE_KHR = 1000023000, - VIDEO_CAPABILITIES_KHR = 1000023001, - VIDEO_PICTURE_RESOURCE_KHR = 1000023002, - VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, - VIDEO_BIND_MEMORY_KHR = 1000023004, - VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, - VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, - VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, - VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, - VIDEO_END_CODING_INFO_KHR = 1000023009, - VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, - VIDEO_REFERENCE_SLOT_KHR = 1000023011, - VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, - VIDEO_PROFILES_KHR = 1000023013, - PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, - VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, - VIDEO_DECODE_INFO_KHR = 1000024000, - DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, - DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, - DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, - PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, - PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, - PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, - CU_MODULE_CREATE_INFO_NVX = 1000029000, - CU_FUNCTION_CREATE_INFO_NVX = 1000029001, - CU_LAUNCH_INFO_NVX = 1000029002, - IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, - IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, - VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, - VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, - VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, - VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, - VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, - VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, - VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, - VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, - VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, - VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, - VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, - VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, - VIDEO_DECODE_H264_MVC_EXT = 1000040003, - VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, - VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, - VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, - VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, - TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, - PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, - EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, - IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, - EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, - WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, - VALIDATION_FLAGS_EXT = 1000061000, - VI_SURFACE_CREATE_INFO_NN = 1000062000, - PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, - IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, - PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, - IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, - EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, - MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, - MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, - IMPORT_MEMORY_FD_INFO_KHR = 1000074000, - MEMORY_FD_PROPERTIES_KHR = 1000074001, - MEMORY_GET_FD_INFO_KHR = 1000074002, - WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, - IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, - EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, - D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, - SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, - IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, - SEMAPHORE_GET_FD_INFO_KHR = 1000079001, - PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, - COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, - PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, - CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, - PRESENT_REGIONS_KHR = 1000084000, - PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, - SURFACE_CAPABILITIES_2_EXT = 1000090000, - DISPLAY_POWER_INFO_EXT = 1000091000, - DEVICE_EVENT_INFO_EXT = 1000091001, - DISPLAY_EVENT_INFO_EXT = 1000091002, - SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, - PRESENT_TIMES_INFO_GOOGLE = 1000092000, - PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, - PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, - PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, - PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, - PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, - PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, - PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, - PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, - HDR_METADATA_EXT = 1000105000, - SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, - IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, - EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, - FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, - IMPORT_FENCE_FD_INFO_KHR = 1000115000, - FENCE_GET_FD_INFO_KHR = 1000115001, - PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, - PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, - QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, - PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, - ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, - PERFORMANCE_COUNTER_KHR = 1000116005, - PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, - PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, - SURFACE_CAPABILITIES_2_KHR = 1000119001, - SURFACE_FORMAT_2_KHR = 1000119002, - DISPLAY_PROPERTIES_2_KHR = 1000121000, - DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, - DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, - DISPLAY_PLANE_INFO_2_KHR = 1000121003, - DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, - IOS_SURFACE_CREATE_INFO_MVK = 1000122000, - MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, - DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, - DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, - DEBUG_UTILS_LABEL_EXT = 1000128002, - DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, - DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, - ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, - ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, - IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, - MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, - EXTERNAL_FORMAT_ANDROID = 1000129005, - PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, - PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, - WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, - DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, - SAMPLE_LOCATIONS_INFO_EXT = 1000143000, - RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, - PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, - PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, - MULTISAMPLE_PROPERTIES_EXT = 1000143004, - PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, - PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, - PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, - PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, - WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, - ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, - ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, - ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, - ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, - ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, - ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, - ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, - COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, - COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, - COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, - PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, - PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, - ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, - ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, - PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, - PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, - RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, - RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, - RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, - PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, - PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, - PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, - PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, - DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, - PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, - IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, - IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, - IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, - VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, - SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, - PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, - PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, - PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, - PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, - PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, - PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, - RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, - ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, - GEOMETRY_NV = 1000165003, - GEOMETRY_TRIANGLES_NV = 1000165004, - GEOMETRY_AABB_NV = 1000165005, - BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, - WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, - ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, - PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, - RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, - ACCELERATION_STRUCTURE_INFO_NV = 1000165012, - PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, - PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, - PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, - FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, - IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, - MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, - PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, - PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, - PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, - CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, - PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, - VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, - VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, - VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, - VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, - VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, - VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, - VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, - DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, - PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, - PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, - PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, - PRESENT_FRAME_TOKEN_GGP = 1000191000, - PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, - PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, - PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, - PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, - PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, - PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, - PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, - PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, - CHECKPOINT_DATA_NV = 1000206000, - QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, - PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, - QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, - INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, - PERFORMANCE_MARKER_INFO_INTEL = 1000210002, - PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, - PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, - PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, - PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, - DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, - SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, - IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, - METAL_SURFACE_CREATE_INFO_EXT = 1000217000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, - RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, - PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, - PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, - FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, - PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, - PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, - PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, - PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, - PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, - PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, - MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, - SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, - PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, - BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, - VALIDATION_FEATURES_EXT = 1000247000, - PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, - PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, - COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, - PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, - PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, - PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, - FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, - PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, - PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, - PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, - PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, - PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, - SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, - SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, - SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, - HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, - PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, - PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, - PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, - PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, - PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, - PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, - PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, - PIPELINE_INFO_KHR = 1000269001, - PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, - PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, - PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, - PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, - PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, - PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, - GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, - GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, - INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, - INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, - GENERATED_COMMANDS_INFO_NV = 1000277005, - GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, - PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, - PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, - COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000, - PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001, - PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, - COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, - RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, - PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, - DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, - DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, - PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, - PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, - SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, - PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, - PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, - PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, - PRESENT_ID_KHR = 1000294000, - PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, - PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, - DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, - PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, - PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, - VIDEO_ENCODE_INFO_KHR = 1000299000, - VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, - PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, - DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - MEMORY_BARRIER_2_KHR = 1000314000, - BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, - IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, - DEPENDENCY_INFO_KHR = 1000314003, - SUBMIT_INFO_2_KHR = 1000314004, - SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, - COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, - PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, - QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, - CHECKPOINT_DATA_2_NV = 1000314009, - PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, - PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, - ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, - PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, - ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, - PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, - COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, - PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - COPY_BUFFER_INFO_2_KHR = 1000337000, - COPY_IMAGE_INFO_2_KHR = 1000337001, - COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, - COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, - BLIT_IMAGE_INFO_2_KHR = 1000337004, - RESOLVE_IMAGE_INFO_2_KHR = 1000337005, - BUFFER_COPY_2_KHR = 1000337006, - IMAGE_COPY_2_KHR = 1000337007, - IMAGE_BLIT_2_KHR = 1000337008, - BUFFER_IMAGE_COPY_2_KHR = 1000337009, - IMAGE_RESOLVE_2_KHR = 1000337010, - PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, - DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, - PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, - MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, - PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, - VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, - VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, - PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, - PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, - IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, - MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, - MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, - IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, - SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, - SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, - PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, - PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, - PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, - MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, - PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, - PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, - SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, - PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, - PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, - QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, - PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, - PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, - PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, - PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, - DEBUG_REPORT_CREATE_INFO_EXT = DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = RENDER_PASS_MULTIVIEW_CREATE_INFO, - PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = PHYSICAL_DEVICE_MULTIVIEW_FEATURES, - PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, - PHYSICAL_DEVICE_FEATURES_2_KHR = PHYSICAL_DEVICE_FEATURES_2, - PHYSICAL_DEVICE_PROPERTIES_2_KHR = PHYSICAL_DEVICE_PROPERTIES_2, - FORMAT_PROPERTIES_2_KHR = FORMAT_PROPERTIES_2, - IMAGE_FORMAT_PROPERTIES_2_KHR = IMAGE_FORMAT_PROPERTIES_2, - PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - QUEUE_FAMILY_PROPERTIES_2_KHR = QUEUE_FAMILY_PROPERTIES_2, - PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, - SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = SPARSE_IMAGE_FORMAT_PROPERTIES_2, - PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, - MEMORY_ALLOCATE_FLAGS_INFO_KHR = MEMORY_ALLOCATE_FLAGS_INFO, - DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, - DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, - DEVICE_GROUP_SUBMIT_INFO_KHR = DEVICE_GROUP_SUBMIT_INFO, - DEVICE_GROUP_BIND_SPARSE_INFO_KHR = DEVICE_GROUP_BIND_SPARSE_INFO, - BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, - BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, - PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = PHYSICAL_DEVICE_GROUP_PROPERTIES, - DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = DEVICE_GROUP_DEVICE_CREATE_INFO, - PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = EXTERNAL_IMAGE_FORMAT_PROPERTIES, - PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, - EXTERNAL_BUFFER_PROPERTIES_KHR = EXTERNAL_BUFFER_PROPERTIES, - PHYSICAL_DEVICE_ID_PROPERTIES_KHR = PHYSICAL_DEVICE_ID_PROPERTIES, - EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = EXTERNAL_MEMORY_BUFFER_CREATE_INFO, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - EXPORT_MEMORY_ALLOCATE_INFO_KHR = EXPORT_MEMORY_ALLOCATE_INFO, - PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, - EXTERNAL_SEMAPHORE_PROPERTIES_KHR = EXTERNAL_SEMAPHORE_PROPERTIES, - EXPORT_SEMAPHORE_CREATE_INFO_KHR = EXPORT_SEMAPHORE_CREATE_INFO, - PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, - DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, - SURFACE_CAPABILITIES2_EXT = SURFACE_CAPABILITIES_2_EXT, - PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, - FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, - FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, - RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = RENDER_PASS_ATTACHMENT_BEGIN_INFO, - ATTACHMENT_DESCRIPTION_2_KHR = ATTACHMENT_DESCRIPTION_2, - ATTACHMENT_REFERENCE_2_KHR = ATTACHMENT_REFERENCE_2, - SUBPASS_DESCRIPTION_2_KHR = SUBPASS_DESCRIPTION_2, - SUBPASS_DEPENDENCY_2_KHR = SUBPASS_DEPENDENCY_2, - RENDER_PASS_CREATE_INFO_2_KHR = RENDER_PASS_CREATE_INFO_2, - SUBPASS_BEGIN_INFO_KHR = SUBPASS_BEGIN_INFO, - SUBPASS_END_INFO_KHR = SUBPASS_END_INFO, - PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, - EXTERNAL_FENCE_PROPERTIES_KHR = EXTERNAL_FENCE_PROPERTIES, - EXPORT_FENCE_CREATE_INFO_KHR = EXPORT_FENCE_CREATE_INFO, - PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, - RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, - IMAGE_VIEW_USAGE_CREATE_INFO_KHR = IMAGE_VIEW_USAGE_CREATE_INFO, - PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, - MEMORY_DEDICATED_REQUIREMENTS_KHR = MEMORY_DEDICATED_REQUIREMENTS, - MEMORY_DEDICATED_ALLOCATE_INFO_KHR = MEMORY_DEDICATED_ALLOCATE_INFO, - PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, - SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = SAMPLER_REDUCTION_MODE_CREATE_INFO, - BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = BUFFER_MEMORY_REQUIREMENTS_INFO_2, - IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_MEMORY_REQUIREMENTS_INFO_2, - IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, - MEMORY_REQUIREMENTS_2_KHR = MEMORY_REQUIREMENTS_2, - SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, - IMAGE_FORMAT_LIST_CREATE_INFO_KHR = IMAGE_FORMAT_LIST_CREATE_INFO, - SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = SAMPLER_YCBCR_CONVERSION_CREATE_INFO, - SAMPLER_YCBCR_CONVERSION_INFO_KHR = SAMPLER_YCBCR_CONVERSION_INFO, - BIND_IMAGE_PLANE_MEMORY_INFO_KHR = BIND_IMAGE_PLANE_MEMORY_INFO, - IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, - PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, - SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, - BIND_BUFFER_MEMORY_INFO_KHR = BIND_BUFFER_MEMORY_INFO, - BIND_IMAGE_MEMORY_INFO_KHR = BIND_IMAGE_MEMORY_INFO, - DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, - PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, - DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = DESCRIPTOR_SET_LAYOUT_SUPPORT, - PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, - PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, - PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, - PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = PHYSICAL_DEVICE_DRIVER_PROPERTIES, - PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, - PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, - SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, - SEMAPHORE_TYPE_CREATE_INFO_KHR = SEMAPHORE_TYPE_CREATE_INFO, - TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = TIMELINE_SEMAPHORE_SUBMIT_INFO, - SEMAPHORE_WAIT_INFO_KHR = SEMAPHORE_WAIT_INFO, - SEMAPHORE_SIGNAL_INFO_KHR = SEMAPHORE_SIGNAL_INFO, - QUERY_POOL_CREATE_INFO_INTEL = QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, - PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, - PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, - PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, - ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = ATTACHMENT_REFERENCE_STENCIL_LAYOUT, - ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, - PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - BUFFER_DEVICE_ADDRESS_INFO_EXT = BUFFER_DEVICE_ADDRESS_INFO, - IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = IMAGE_STENCIL_USAGE_CREATE_INFO, - PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, - BUFFER_DEVICE_ADDRESS_INFO_KHR = BUFFER_DEVICE_ADDRESS_INFO, - BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, - MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, - DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, - PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + APPLICATION_INFO = 0, + INSTANCE_CREATE_INFO = 1, + DEVICE_QUEUE_CREATE_INFO = 2, + DEVICE_CREATE_INFO = 3, + SUBMIT_INFO = 4, + MEMORY_ALLOCATE_INFO = 5, + MAPPED_MEMORY_RANGE = 6, + BIND_SPARSE_INFO = 7, + FENCE_CREATE_INFO = 8, + SEMAPHORE_CREATE_INFO = 9, + EVENT_CREATE_INFO = 10, + QUERY_POOL_CREATE_INFO = 11, + BUFFER_CREATE_INFO = 12, + BUFFER_VIEW_CREATE_INFO = 13, + IMAGE_CREATE_INFO = 14, + IMAGE_VIEW_CREATE_INFO = 15, + SHADER_MODULE_CREATE_INFO = 16, + PIPELINE_CACHE_CREATE_INFO = 17, + PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + GRAPHICS_PIPELINE_CREATE_INFO = 28, + COMPUTE_PIPELINE_CREATE_INFO = 29, + PIPELINE_LAYOUT_CREATE_INFO = 30, + SAMPLER_CREATE_INFO = 31, + DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + DESCRIPTOR_POOL_CREATE_INFO = 33, + DESCRIPTOR_SET_ALLOCATE_INFO = 34, + WRITE_DESCRIPTOR_SET = 35, + COPY_DESCRIPTOR_SET = 36, + FRAMEBUFFER_CREATE_INFO = 37, + RENDER_PASS_CREATE_INFO = 38, + COMMAND_POOL_CREATE_INFO = 39, + COMMAND_BUFFER_ALLOCATE_INFO = 40, + COMMAND_BUFFER_INHERITANCE_INFO = 41, + COMMAND_BUFFER_BEGIN_INFO = 42, + RENDER_PASS_BEGIN_INFO = 43, + BUFFER_MEMORY_BARRIER = 44, + IMAGE_MEMORY_BARRIER = 45, + MEMORY_BARRIER = 46, + LOADER_INSTANCE_CREATE_INFO = 47, + LOADER_DEVICE_CREATE_INFO = 48, + PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + BIND_BUFFER_MEMORY_INFO = 1000157000, + BIND_IMAGE_MEMORY_INFO = 1000157001, + PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + MEMORY_DEDICATED_REQUIREMENTS = 1000127000, + MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, + MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, + DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, + DEVICE_GROUP_SUBMIT_INFO = 1000060005, + DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, + BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, + BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, + PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, + DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, + BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, + IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, + IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, + MEMORY_REQUIREMENTS_2 = 1000146003, + SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, + PHYSICAL_DEVICE_FEATURES_2 = 1000059000, + PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, + FORMAT_PROPERTIES_2 = 1000059002, + IMAGE_FORMAT_PROPERTIES_2 = 1000059003, + PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, + QUEUE_FAMILY_PROPERTIES_2 = 1000059005, + PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, + SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, + PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, + PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, + PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, + PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, + PROTECTED_SUBMIT_INFO = 1000145000, + PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, + PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, + DEVICE_QUEUE_INFO_2 = 1000145003, + SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, + PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, + EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, + PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, + EXTERNAL_BUFFER_PROPERTIES = 1000071003, + PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, + EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, + EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, + PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, + EXTERNAL_FENCE_PROPERTIES = 1000112001, + EXPORT_FENCE_CREATE_INFO = 1000113000, + EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, + PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, + EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, + DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + ATTACHMENT_DESCRIPTION_2 = 1000109000, + ATTACHMENT_REFERENCE_2 = 1000109001, + SUBPASS_DESCRIPTION_2 = 1000109002, + SUBPASS_DEPENDENCY_2 = 1000109003, + RENDER_PASS_CREATE_INFO_2 = 1000109004, + SUBPASS_BEGIN_INFO = 1000109005, + SUBPASS_END_INFO = 1000109006, + PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + SEMAPHORE_WAIT_INFO = 1000207004, + SEMAPHORE_SIGNAL_INFO = 1000207005, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + MEMORY_BARRIER_2 = 1000314000, + BUFFER_MEMORY_BARRIER_2 = 1000314001, + IMAGE_MEMORY_BARRIER_2 = 1000314002, + DEPENDENCY_INFO = 1000314003, + SUBMIT_INFO_2 = 1000314004, + SEMAPHORE_SUBMIT_INFO = 1000314005, + COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + COPY_BUFFER_INFO_2 = 1000337000, + COPY_IMAGE_INFO_2 = 1000337001, + COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + BLIT_IMAGE_INFO_2 = 1000337004, + RESOLVE_IMAGE_INFO_2 = 1000337005, + BUFFER_COPY_2 = 1000337006, + IMAGE_COPY_2 = 1000337007, + IMAGE_BLIT_2 = 1000337008, + BUFFER_IMAGE_COPY_2 = 1000337009, + IMAGE_RESOLVE_2 = 1000337010, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + RENDERING_INFO = 1000044000, + RENDERING_ATTACHMENT_INFO = 1000044001, + PIPELINE_RENDERING_CREATE_INFO = 1000044002, + PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + FORMAT_PROPERTIES_3 = 1000360000, + PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, + SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + PRESENT_INFO_KHR = 1000001001, + DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, + IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, + BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, + ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, + DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, + DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, + DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, + DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, + DISPLAY_PRESENT_INFO_KHR = 1000003000, + XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, + XCB_SURFACE_CREATE_INFO_KHR = 1000005000, + WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, + ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, + WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, + DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, + DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, + VIDEO_PROFILE_KHR = 1000023000, + VIDEO_CAPABILITIES_KHR = 1000023001, + VIDEO_PICTURE_RESOURCE_KHR = 1000023002, + VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, + VIDEO_BIND_MEMORY_KHR = 1000023004, + VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, + VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, + VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, + VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, + VIDEO_END_CODING_INFO_KHR = 1000023009, + VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, + VIDEO_REFERENCE_SLOT_KHR = 1000023011, + VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, + VIDEO_PROFILES_KHR = 1000023013, + PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, + VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, + QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, + VIDEO_DECODE_INFO_KHR = 1000024000, + VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, + DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, + DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, + DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, + PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, + PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, + CU_MODULE_CREATE_INFO_NVX = 1000029000, + CU_FUNCTION_CREATE_INFO_NVX = 1000029001, + CU_LAUNCH_INFO_NVX = 1000029002, + IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, + IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, + VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, + VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, + VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, + VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, + VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, + VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, + VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, + VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, + VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, + VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, + VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, + VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, + VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, + VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, + VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, + VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, + VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, + VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, + VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, + VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, + VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, + VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, + VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, + VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, + VIDEO_DECODE_H264_MVC_EXT = 1000040002, + VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, + VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, + VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, + VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, + TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, + RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, + ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, + STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, + PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, + EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, + IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, + EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, + WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, + VALIDATION_FLAGS_EXT = 1000061000, + VI_SURFACE_CREATE_INFO_NN = 1000062000, + IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, + PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, + IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, + EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, + MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, + MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, + IMPORT_MEMORY_FD_INFO_KHR = 1000074000, + MEMORY_FD_PROPERTIES_KHR = 1000074001, + MEMORY_GET_FD_INFO_KHR = 1000074002, + WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, + IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, + EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, + D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, + SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, + IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, + SEMAPHORE_GET_FD_INFO_KHR = 1000079001, + PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, + PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, + CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, + PRESENT_REGIONS_KHR = 1000084000, + PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, + SURFACE_CAPABILITIES_2_EXT = 1000090000, + DISPLAY_POWER_INFO_EXT = 1000091000, + DEVICE_EVENT_INFO_EXT = 1000091001, + DISPLAY_EVENT_INFO_EXT = 1000091002, + SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, + PRESENT_TIMES_INFO_GOOGLE = 1000092000, + PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, + PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, + PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, + PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, + PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, + PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, + PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, + PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, + HDR_METADATA_EXT = 1000105000, + SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, + IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, + EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, + FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, + IMPORT_FENCE_FD_INFO_KHR = 1000115000, + FENCE_GET_FD_INFO_KHR = 1000115001, + PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, + PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, + QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, + PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, + ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, + PERFORMANCE_COUNTER_KHR = 1000116005, + PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, + PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, + SURFACE_CAPABILITIES_2_KHR = 1000119001, + SURFACE_FORMAT_2_KHR = 1000119002, + DISPLAY_PROPERTIES_2_KHR = 1000121000, + DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, + DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, + DISPLAY_PLANE_INFO_2_KHR = 1000121003, + DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, + IOS_SURFACE_CREATE_INFO_MVK = 1000122000, + MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, + DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, + DEBUG_UTILS_LABEL_EXT = 1000128002, + DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, + DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, + ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, + ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, + ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, + IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, + MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, + EXTERNAL_FORMAT_ANDROID = 1000129005, + ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, + SAMPLE_LOCATIONS_INFO_EXT = 1000143000, + RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, + PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, + PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, + MULTISAMPLE_PROPERTIES_EXT = 1000143004, + PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, + PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, + PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, + PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, + ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, + ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, + ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, + ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, + ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, + ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, + ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, + COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, + COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, + COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, + PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, + PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, + ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, + ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, + PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, + PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, + RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, + RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, + RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, + PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, + PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, + PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, + DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, + PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, + IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, + IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, + IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, + DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, + VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, + SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, + PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, + PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, + PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, + PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, + PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, + PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, + RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, + ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, + GEOMETRY_NV = 1000165003, + GEOMETRY_TRIANGLES_NV = 1000165004, + GEOMETRY_AABB_NV = 1000165005, + BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, + WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, + ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, + PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, + RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, + ACCELERATION_STRUCTURE_INFO_NV = 1000165012, + PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, + PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, + PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, + FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, + IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, + MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, + PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, + PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, + CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, + PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, + VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, + VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, + VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, + VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, + VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, + VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, + DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, + PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, + PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, + PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, + PRESENT_FRAME_TOKEN_GGP = 1000191000, + PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, + PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, + PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, + PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, + PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, + PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, + PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, + CHECKPOINT_DATA_NV = 1000206000, + QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, + QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, + INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, + PERFORMANCE_MARKER_INFO_INTEL = 1000210002, + PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, + PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, + PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, + PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, + DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, + SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, + IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + METAL_SURFACE_CREATE_INFO_EXT = 1000217000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, + PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, + PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, + PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, + PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, + PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, + PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, + MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, + SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, + PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, + BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, + VALIDATION_FEATURES_EXT = 1000247000, + PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, + PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, + COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, + PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, + PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, + PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, + FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, + PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, + PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, + PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, + PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, + PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, + SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, + SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, + SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, + HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, + PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, + PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, + PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, + PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, + PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, + PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, + PIPELINE_INFO_KHR = 1000269001, + PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, + PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, + PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, + PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, + PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, + PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, + GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, + GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, + INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, + INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, + GENERATED_COMMANDS_INFO_NV = 1000277005, + GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, + PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, + PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, + COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, + COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, + RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, + PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, + DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, + DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, + PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, + PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, + SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, + PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, + PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, + PRESENT_ID_KHR = 1000294000, + PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, + VIDEO_ENCODE_INFO_KHR = 1000299000, + VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, + VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, + VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, + PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, + DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, + QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, + CHECKPOINT_DATA_2_NV = 1000314009, + PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, + PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, + PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, + ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, + PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, + ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, + PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, + COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, + PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, + PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, + PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, + DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, + PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, + MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, + PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, + VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, + VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, + PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, + PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, + IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, + MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, + MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, + IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, + SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, + IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, + BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, + BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, + BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, + BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, + IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, + IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, + SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, + BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, + SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, + PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, + PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, + PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, + MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, + PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, + PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, + SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, + PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, + PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, + PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, + PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, + PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, + PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, + SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, + PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, + PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, + PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, + DEBUG_REPORT_CREATE_INFO_EXT = DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + RENDERING_INFO_KHR = RENDERING_INFO, + RENDERING_ATTACHMENT_INFO_KHR = RENDERING_ATTACHMENT_INFO, + PIPELINE_RENDERING_CREATE_INFO_KHR = PIPELINE_RENDERING_CREATE_INFO, + PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, + ATTACHMENT_SAMPLE_COUNT_INFO_NV = ATTACHMENT_SAMPLE_COUNT_INFO_AMD, + RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = RENDER_PASS_MULTIVIEW_CREATE_INFO, + PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = PHYSICAL_DEVICE_MULTIVIEW_FEATURES, + PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, + PHYSICAL_DEVICE_FEATURES_2_KHR = PHYSICAL_DEVICE_FEATURES_2, + PHYSICAL_DEVICE_PROPERTIES_2_KHR = PHYSICAL_DEVICE_PROPERTIES_2, + FORMAT_PROPERTIES_2_KHR = FORMAT_PROPERTIES_2, + IMAGE_FORMAT_PROPERTIES_2_KHR = IMAGE_FORMAT_PROPERTIES_2, + PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + QUEUE_FAMILY_PROPERTIES_2_KHR = QUEUE_FAMILY_PROPERTIES_2, + PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, + SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = SPARSE_IMAGE_FORMAT_PROPERTIES_2, + PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, + MEMORY_ALLOCATE_FLAGS_INFO_KHR = MEMORY_ALLOCATE_FLAGS_INFO, + DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, + DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, + DEVICE_GROUP_SUBMIT_INFO_KHR = DEVICE_GROUP_SUBMIT_INFO, + DEVICE_GROUP_BIND_SPARSE_INFO_KHR = DEVICE_GROUP_BIND_SPARSE_INFO, + BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, + BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, + PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = PHYSICAL_DEVICE_GROUP_PROPERTIES, + DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = DEVICE_GROUP_DEVICE_CREATE_INFO, + PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = EXTERNAL_IMAGE_FORMAT_PROPERTIES, + PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, + EXTERNAL_BUFFER_PROPERTIES_KHR = EXTERNAL_BUFFER_PROPERTIES, + PHYSICAL_DEVICE_ID_PROPERTIES_KHR = PHYSICAL_DEVICE_ID_PROPERTIES, + EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + EXPORT_MEMORY_ALLOCATE_INFO_KHR = EXPORT_MEMORY_ALLOCATE_INFO, + PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, + EXTERNAL_SEMAPHORE_PROPERTIES_KHR = EXTERNAL_SEMAPHORE_PROPERTIES, + EXPORT_SEMAPHORE_CREATE_INFO_KHR = EXPORT_SEMAPHORE_CREATE_INFO, + PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, + DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + SURFACE_CAPABILITIES2_EXT = SURFACE_CAPABILITIES_2_EXT, + PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, + FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, + FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, + RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = RENDER_PASS_ATTACHMENT_BEGIN_INFO, + ATTACHMENT_DESCRIPTION_2_KHR = ATTACHMENT_DESCRIPTION_2, + ATTACHMENT_REFERENCE_2_KHR = ATTACHMENT_REFERENCE_2, + SUBPASS_DESCRIPTION_2_KHR = SUBPASS_DESCRIPTION_2, + SUBPASS_DEPENDENCY_2_KHR = SUBPASS_DEPENDENCY_2, + RENDER_PASS_CREATE_INFO_2_KHR = RENDER_PASS_CREATE_INFO_2, + SUBPASS_BEGIN_INFO_KHR = SUBPASS_BEGIN_INFO, + SUBPASS_END_INFO_KHR = SUBPASS_END_INFO, + PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, + EXTERNAL_FENCE_PROPERTIES_KHR = EXTERNAL_FENCE_PROPERTIES, + EXPORT_FENCE_CREATE_INFO_KHR = EXPORT_FENCE_CREATE_INFO, + PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, + RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, + IMAGE_VIEW_USAGE_CREATE_INFO_KHR = IMAGE_VIEW_USAGE_CREATE_INFO, + PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, + PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, + MEMORY_DEDICATED_REQUIREMENTS_KHR = MEMORY_DEDICATED_REQUIREMENTS, + MEMORY_DEDICATED_ALLOCATE_INFO_KHR = MEMORY_DEDICATED_ALLOCATE_INFO, + PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, + SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = SAMPLER_REDUCTION_MODE_CREATE_INFO, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, + BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = BUFFER_MEMORY_REQUIREMENTS_INFO_2, + IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_MEMORY_REQUIREMENTS_INFO_2, + IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, + MEMORY_REQUIREMENTS_2_KHR = MEMORY_REQUIREMENTS_2, + SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + IMAGE_FORMAT_LIST_CREATE_INFO_KHR = IMAGE_FORMAT_LIST_CREATE_INFO, + SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = SAMPLER_YCBCR_CONVERSION_CREATE_INFO, + SAMPLER_YCBCR_CONVERSION_INFO_KHR = SAMPLER_YCBCR_CONVERSION_INFO, + BIND_IMAGE_PLANE_MEMORY_INFO_KHR = BIND_IMAGE_PLANE_MEMORY_INFO, + IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, + PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, + SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, + BIND_BUFFER_MEMORY_INFO_KHR = BIND_BUFFER_MEMORY_INFO, + BIND_IMAGE_MEMORY_INFO_KHR = BIND_IMAGE_MEMORY_INFO, + DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, + PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, + DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = DESCRIPTOR_SET_LAYOUT_SUPPORT, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, + PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, + PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, + PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = PIPELINE_CREATION_FEEDBACK_CREATE_INFO, + PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = PHYSICAL_DEVICE_DRIVER_PROPERTIES, + PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, + SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, + SEMAPHORE_TYPE_CREATE_INFO_KHR = SEMAPHORE_TYPE_CREATE_INFO, + TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = TIMELINE_SEMAPHORE_SUBMIT_INFO, + SEMAPHORE_WAIT_INFO_KHR = SEMAPHORE_WAIT_INFO, + SEMAPHORE_SIGNAL_INFO_KHR = SEMAPHORE_SIGNAL_INFO, + QUERY_POOL_CREATE_INFO_INTEL = QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, + PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, + PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, + PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, + ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = ATTACHMENT_REFERENCE_STENCIL_LAYOUT, + ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, + PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, + BUFFER_DEVICE_ADDRESS_INFO_EXT = BUFFER_DEVICE_ADDRESS_INFO, + PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = PHYSICAL_DEVICE_TOOL_PROPERTIES, + IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = IMAGE_STENCIL_USAGE_CREATE_INFO, + PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, + BUFFER_DEVICE_ADDRESS_INFO_KHR = BUFFER_DEVICE_ADDRESS_INFO, + BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, + MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, + DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = DEVICE_PRIVATE_DATA_CREATE_INFO, + PRIVATE_DATA_SLOT_CREATE_INFO_EXT = PRIVATE_DATA_SLOT_CREATE_INFO, + PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + MEMORY_BARRIER_2_KHR = MEMORY_BARRIER_2, + BUFFER_MEMORY_BARRIER_2_KHR = BUFFER_MEMORY_BARRIER_2, + IMAGE_MEMORY_BARRIER_2_KHR = IMAGE_MEMORY_BARRIER_2, + DEPENDENCY_INFO_KHR = DEPENDENCY_INFO, + SUBMIT_INFO_2_KHR = SUBMIT_INFO_2, + SEMAPHORE_SUBMIT_INFO_KHR = SEMAPHORE_SUBMIT_INFO, + COMMAND_BUFFER_SUBMIT_INFO_KHR = COMMAND_BUFFER_SUBMIT_INFO, + PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + COPY_BUFFER_INFO_2_KHR = COPY_BUFFER_INFO_2, + COPY_IMAGE_INFO_2_KHR = COPY_IMAGE_INFO_2, + COPY_BUFFER_TO_IMAGE_INFO_2_KHR = COPY_BUFFER_TO_IMAGE_INFO_2, + COPY_IMAGE_TO_BUFFER_INFO_2_KHR = COPY_IMAGE_TO_BUFFER_INFO_2, + BLIT_IMAGE_INFO_2_KHR = BLIT_IMAGE_INFO_2, + RESOLVE_IMAGE_INFO_2_KHR = RESOLVE_IMAGE_INFO_2, + BUFFER_COPY_2_KHR = BUFFER_COPY_2, + IMAGE_COPY_2_KHR = IMAGE_COPY_2, + IMAGE_BLIT_2_KHR = IMAGE_BLIT_2, + BUFFER_IMAGE_COPY_2_KHR = BUFFER_IMAGE_COPY_2, + IMAGE_RESOLVE_2_KHR = IMAGE_RESOLVE_2, + FORMAT_PROPERTIES_3_KHR = FORMAT_PROPERTIES_3, + PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = DEVICE_BUFFER_MEMORY_REQUIREMENTS, + DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = DEVICE_IMAGE_MEMORY_REQUIREMENTS, } SubgroupFeatureFlags :: distinct bit_set[SubgroupFeatureFlag; Flags] @@ -2737,9 +2961,10 @@ SubgroupFeatureFlag :: enum Flags { PARTITIONED_NV = 8, } -SubmitFlagsKHR :: distinct bit_set[SubmitFlagKHR; Flags] -SubmitFlagKHR :: enum Flags { - PROTECTED = 0, +SubmitFlags :: distinct bit_set[SubmitFlag; Flags] +SubmitFlag :: enum Flags { + PROTECTED = 0, + PROTECTED_KHR = PROTECTED, } SubpassContents :: enum c.int { @@ -2749,10 +2974,13 @@ SubpassContents :: enum c.int { SubpassDescriptionFlags :: distinct bit_set[SubpassDescriptionFlag; Flags] SubpassDescriptionFlag :: enum Flags { - PER_VIEW_ATTRIBUTES_NVX = 0, - PER_VIEW_POSITION_X_ONLY_NVX = 1, - FRAGMENT_REGION_QCOM = 2, - SHADER_RESOLVE_QCOM = 3, + PER_VIEW_ATTRIBUTES_NVX = 0, + PER_VIEW_POSITION_X_ONLY_NVX = 1, + FRAGMENT_REGION_QCOM = 2, + SHADER_RESOLVE_QCOM = 3, + RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_ARM = 4, + RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_ARM = 5, + RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_ARM = 6, } SurfaceCounterFlagsEXT :: distinct bit_set[SurfaceCounterFlagEXT; Flags] @@ -2802,15 +3030,20 @@ TimeDomainEXT :: enum c.int { QUERY_PERFORMANCE_COUNTER = 3, } -ToolPurposeFlagsEXT :: distinct bit_set[ToolPurposeFlagEXT; Flags] -ToolPurposeFlagEXT :: enum Flags { - VALIDATION = 0, - PROFILING = 1, - TRACING = 2, - ADDITIONAL_FEATURES = 3, - MODIFYING_FEATURES = 4, - DEBUG_REPORTING = 5, - DEBUG_MARKERS = 6, +ToolPurposeFlags :: distinct bit_set[ToolPurposeFlag; Flags] +ToolPurposeFlag :: enum Flags { + VALIDATION = 0, + PROFILING = 1, + TRACING = 2, + ADDITIONAL_FEATURES = 3, + MODIFYING_FEATURES = 4, + DEBUG_REPORTING_EXT = 5, + DEBUG_MARKERS_EXT = 6, + VALIDATION_EXT = VALIDATION, + PROFILING_EXT = PROFILING, + TRACING_EXT = TRACING, + ADDITIONAL_FEATURES_EXT = ADDITIONAL_FEATURES, + MODIFYING_FEATURES_EXT = MODIFYING_FEATURES, } ValidationCacheHeaderVersionEXT :: enum c.int { @@ -2894,32 +3127,24 @@ HeadlessSurfaceCreateFlagsEXT :: distinct bit_set[Headles HeadlessSurfaceCreateFlagEXT :: enum u32 {} IOSSurfaceCreateFlagsMVK :: distinct bit_set[IOSSurfaceCreateFlagMVK; Flags] IOSSurfaceCreateFlagMVK :: enum u32 {} -InstanceCreateFlags :: distinct bit_set[InstanceCreateFlag; Flags] -InstanceCreateFlag :: enum u32 {} MacOSSurfaceCreateFlagsMVK :: distinct bit_set[MacOSSurfaceCreateFlagMVK; Flags] MacOSSurfaceCreateFlagMVK :: enum u32 {} MemoryMapFlags :: distinct bit_set[MemoryMapFlag; Flags] MemoryMapFlag :: enum u32 {} MetalSurfaceCreateFlagsEXT :: distinct bit_set[MetalSurfaceCreateFlagEXT; Flags] MetalSurfaceCreateFlagEXT :: enum u32 {} -PipelineColorBlendStateCreateFlags :: distinct bit_set[PipelineColorBlendStateCreateFlag; Flags] -PipelineColorBlendStateCreateFlag :: enum u32 {} PipelineCoverageModulationStateCreateFlagsNV :: distinct bit_set[PipelineCoverageModulationStateCreateFlagNV; Flags] PipelineCoverageModulationStateCreateFlagNV :: enum u32 {} PipelineCoverageReductionStateCreateFlagsNV :: distinct bit_set[PipelineCoverageReductionStateCreateFlagNV; Flags] PipelineCoverageReductionStateCreateFlagNV :: enum u32 {} PipelineCoverageToColorStateCreateFlagsNV :: distinct bit_set[PipelineCoverageToColorStateCreateFlagNV; Flags] PipelineCoverageToColorStateCreateFlagNV :: enum u32 {} -PipelineDepthStencilStateCreateFlags :: distinct bit_set[PipelineDepthStencilStateCreateFlag; Flags] -PipelineDepthStencilStateCreateFlag :: enum u32 {} PipelineDiscardRectangleStateCreateFlagsEXT :: distinct bit_set[PipelineDiscardRectangleStateCreateFlagEXT; Flags] PipelineDiscardRectangleStateCreateFlagEXT :: enum u32 {} PipelineDynamicStateCreateFlags :: distinct bit_set[PipelineDynamicStateCreateFlag; Flags] PipelineDynamicStateCreateFlag :: enum u32 {} PipelineInputAssemblyStateCreateFlags :: distinct bit_set[PipelineInputAssemblyStateCreateFlag; Flags] PipelineInputAssemblyStateCreateFlag :: enum u32 {} -PipelineLayoutCreateFlags :: distinct bit_set[PipelineLayoutCreateFlag; Flags] -PipelineLayoutCreateFlag :: enum u32 {} PipelineMultisampleStateCreateFlags :: distinct bit_set[PipelineMultisampleStateCreateFlag; Flags] PipelineMultisampleStateCreateFlag :: enum u32 {} PipelineRasterizationConservativeStateCreateFlagsEXT :: distinct bit_set[PipelineRasterizationConservativeStateCreateFlagEXT; Flags] @@ -2938,6 +3163,8 @@ PipelineViewportStateCreateFlags :: distinct bit_set[Pipelin PipelineViewportStateCreateFlag :: enum u32 {} PipelineViewportSwizzleStateCreateFlagsNV :: distinct bit_set[PipelineViewportSwizzleStateCreateFlagNV; Flags] PipelineViewportSwizzleStateCreateFlagNV :: enum u32 {} +PrivateDataSlotCreateFlags :: distinct bit_set[PrivateDataSlotCreateFlag; Flags] +PrivateDataSlotCreateFlag :: enum u32 {} QueryPoolCreateFlags :: distinct bit_set[QueryPoolCreateFlag; Flags] QueryPoolCreateFlag :: enum u32 {} SemaphoreCreateFlags :: distinct bit_set[SemaphoreCreateFlag; Flags] diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index 7557d3c36..227f02a87 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -100,7 +100,8 @@ ProcGetPhysicalDeviceSurfaceFormatsKHR :: #type pro ProcGetPhysicalDeviceSurfacePresentModes2EXT :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result ProcGetPhysicalDeviceSurfacePresentModesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result ProcGetPhysicalDeviceSurfaceSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32, surface: SurfaceKHR, pSupported: ^b32) -> Result -ProcGetPhysicalDeviceToolPropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolPropertiesEXT) -> Result +ProcGetPhysicalDeviceToolProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolProperties) -> Result +ProcGetPhysicalDeviceToolPropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolProperties) -> Result ProcGetPhysicalDeviceWin32PresentationSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32) -> b32 ProcGetWinrtDisplayNV :: #type proc "system" (physicalDevice: PhysicalDevice, deviceRelativeId: u32, pDisplay: ^DisplayKHR) -> Result ProcReleaseDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR) -> Result @@ -131,6 +132,8 @@ ProcCmdBeginQueryIndexedEXT :: #type proc "system" (comm ProcCmdBeginRenderPass :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, contents: SubpassContents) ProcCmdBeginRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) ProcCmdBeginRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) +ProcCmdBeginRendering :: #type proc "system" (commandBuffer: CommandBuffer, pRenderingInfo: ^RenderingInfo) +ProcCmdBeginRenderingKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRenderingInfo: ^RenderingInfo) ProcCmdBeginTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) ProcCmdBindDescriptorSets :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, firstSet: u32, descriptorSetCount: u32, pDescriptorSets: [^]DescriptorSet, dynamicOffsetCount: u32, pDynamicOffsets: [^]u32) ProcCmdBindIndexBuffer :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, indexType: IndexType) @@ -140,9 +143,11 @@ ProcCmdBindPipelineShaderGroupNV :: #type proc "system" (comm ProcCmdBindShadingRateImageNV :: #type proc "system" (commandBuffer: CommandBuffer, imageView: ImageView, imageLayout: ImageLayout) ProcCmdBindTransformFeedbackBuffersEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize) ProcCmdBindVertexBuffers :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize) +ProcCmdBindVertexBuffers2 :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize, pStrides: [^]DeviceSize) ProcCmdBindVertexBuffers2EXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize, pStrides: [^]DeviceSize) ProcCmdBlitImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageBlit, filter: Filter) -ProcCmdBlitImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2KHR) +ProcCmdBlitImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2) +ProcCmdBlitImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2) ProcCmdBuildAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^AccelerationStructureInfoNV, instanceData: Buffer, instanceOffset: DeviceSize, update: b32, dst: AccelerationStructureNV, src: AccelerationStructureNV, scratch: Buffer, scratchOffset: DeviceSize) ProcCmdBuildAccelerationStructuresIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, pIndirectDeviceAddresses: [^]DeviceAddress, pIndirectStrides: [^]u32, ppMaxPrimitiveCounts: ^[^]u32) ProcCmdBuildAccelerationStructuresKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, ppBuildRangeInfos: ^[^]AccelerationStructureBuildRangeInfoKHR) @@ -153,13 +158,17 @@ ProcCmdCopyAccelerationStructureKHR :: #type proc "system" (comm ProcCmdCopyAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, dst: AccelerationStructureNV, src: AccelerationStructureNV, mode: CopyAccelerationStructureModeKHR) ProcCmdCopyAccelerationStructureToMemoryKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) ProcCmdCopyBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferCopy) -ProcCmdCopyBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2KHR) +ProcCmdCopyBuffer2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2) +ProcCmdCopyBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2) ProcCmdCopyBufferToImage :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]BufferImageCopy) -ProcCmdCopyBufferToImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2KHR) +ProcCmdCopyBufferToImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2) +ProcCmdCopyBufferToImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2) ProcCmdCopyImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageCopy) -ProcCmdCopyImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2KHR) +ProcCmdCopyImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2) +ProcCmdCopyImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2) ProcCmdCopyImageToBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferImageCopy) -ProcCmdCopyImageToBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2KHR) +ProcCmdCopyImageToBuffer2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2) +ProcCmdCopyImageToBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2) ProcCmdCopyMemoryToAccelerationStructureKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyMemoryToAccelerationStructureInfoKHR) ProcCmdCopyQueryPoolResults :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dstBuffer: Buffer, dstOffset: DeviceSize, stride: DeviceSize, flags: QueryResultFlags) ProcCmdCuLaunchKernelNVX :: #type proc "system" (commandBuffer: CommandBuffer, pLaunchInfo: ^CuLaunchInfoNVX) @@ -193,6 +202,8 @@ ProcCmdEndQueryIndexedEXT :: #type proc "system" (comm ProcCmdEndRenderPass :: #type proc "system" (commandBuffer: CommandBuffer) ProcCmdEndRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) ProcCmdEndRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) +ProcCmdEndRendering :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndRenderingKHR :: #type proc "system" (commandBuffer: CommandBuffer) ProcCmdEndTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) ProcCmdExecuteCommands :: #type proc "system" (commandBuffer: CommandBuffer, commandBufferCount: u32, pCommandBuffers: [^]CommandBuffer) ProcCmdExecuteGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, isPreprocessed: b32, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) @@ -202,35 +213,46 @@ ProcCmdNextSubpass :: #type proc "system" (comm ProcCmdNextSubpass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) ProcCmdNextSubpass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) ProcCmdPipelineBarrier :: #type proc "system" (commandBuffer: CommandBuffer, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, dependencyFlags: DependencyFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) -ProcCmdPipelineBarrier2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfoKHR) +ProcCmdPipelineBarrier2 :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfo) +ProcCmdPipelineBarrier2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfo) ProcCmdPreprocessGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) ProcCmdPushConstants :: #type proc "system" (commandBuffer: CommandBuffer, layout: PipelineLayout, stageFlags: ShaderStageFlags, offset: u32, size: u32, pValues: rawptr) ProcCmdPushDescriptorSetKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, set: u32, descriptorWriteCount: u32, pDescriptorWrites: [^]WriteDescriptorSet) ProcCmdPushDescriptorSetWithTemplateKHR :: #type proc "system" (commandBuffer: CommandBuffer, descriptorUpdateTemplate: DescriptorUpdateTemplate, layout: PipelineLayout, set: u32, pData: rawptr) ProcCmdResetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) -ProcCmdResetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2KHR) +ProcCmdResetEvent2 :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2) +ProcCmdResetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2) ProcCmdResetQueryPool :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32) ProcCmdResolveImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageResolve) -ProcCmdResolveImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2KHR) +ProcCmdResolveImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2) +ProcCmdResolveImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2) ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer) ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) +ProcCmdSetCullMode :: #type proc "system" (commandBuffer: CommandBuffer, cullMode: CullModeFlags) ProcCmdSetCullModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, cullMode: CullModeFlags) ProcCmdSetDepthBias :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasConstantFactor: f32, depthBiasClamp: f32, depthBiasSlopeFactor: f32) +ProcCmdSetDepthBiasEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasEnable: b32) ProcCmdSetDepthBiasEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasEnable: b32) ProcCmdSetDepthBounds :: #type proc "system" (commandBuffer: CommandBuffer, minDepthBounds: f32, maxDepthBounds: f32) +ProcCmdSetDepthBoundsTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthBoundsTestEnable: b32) ProcCmdSetDepthBoundsTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBoundsTestEnable: b32) +ProcCmdSetDepthCompareOp :: #type proc "system" (commandBuffer: CommandBuffer, depthCompareOp: CompareOp) ProcCmdSetDepthCompareOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthCompareOp: CompareOp) +ProcCmdSetDepthTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthTestEnable: b32) ProcCmdSetDepthTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthTestEnable: b32) +ProcCmdSetDepthWriteEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthWriteEnable: b32) ProcCmdSetDepthWriteEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthWriteEnable: b32) ProcCmdSetDeviceMask :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) ProcCmdSetDeviceMaskKHR :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) ProcCmdSetDiscardRectangleEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstDiscardRectangle: u32, discardRectangleCount: u32, pDiscardRectangles: [^]Rect2D) ProcCmdSetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) -ProcCmdSetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfoKHR) +ProcCmdSetEvent2 :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfo) +ProcCmdSetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfo) ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV) ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D) +ProcCmdSetFrontFace :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetLineStippleEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineStippleFactor: u32, lineStipplePattern: u16) ProcCmdSetLineWidth :: #type proc "system" (commandBuffer: CommandBuffer, lineWidth: f32) @@ -239,22 +261,29 @@ ProcCmdSetPatchControlPointsEXT :: #type proc "system" (comm ProcCmdSetPerformanceMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceMarkerInfoINTEL) -> Result ProcCmdSetPerformanceOverrideINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pOverrideInfo: ^PerformanceOverrideInfoINTEL) -> Result ProcCmdSetPerformanceStreamMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceStreamMarkerInfoINTEL) -> Result +ProcCmdSetPrimitiveRestartEnable :: #type proc "system" (commandBuffer: CommandBuffer, primitiveRestartEnable: b32) ProcCmdSetPrimitiveRestartEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveRestartEnable: b32) +ProcCmdSetPrimitiveTopology :: #type proc "system" (commandBuffer: CommandBuffer, primitiveTopology: PrimitiveTopology) ProcCmdSetPrimitiveTopologyEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveTopology: PrimitiveTopology) +ProcCmdSetRasterizerDiscardEnable :: #type proc "system" (commandBuffer: CommandBuffer, rasterizerDiscardEnable: b32) ProcCmdSetRasterizerDiscardEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, rasterizerDiscardEnable: b32) ProcCmdSetRayTracingPipelineStackSizeKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStackSize: u32) ProcCmdSetSampleLocationsEXT :: #type proc "system" (commandBuffer: CommandBuffer, pSampleLocationsInfo: ^SampleLocationsInfoEXT) ProcCmdSetScissor :: #type proc "system" (commandBuffer: CommandBuffer, firstScissor: u32, scissorCount: u32, pScissors: [^]Rect2D) +ProcCmdSetScissorWithCount :: #type proc "system" (commandBuffer: CommandBuffer, scissorCount: u32, pScissors: [^]Rect2D) ProcCmdSetScissorWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, scissorCount: u32, pScissors: [^]Rect2D) ProcCmdSetStencilCompareMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, compareMask: u32) +ProcCmdSetStencilOp :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, failOp: StencilOp, passOp: StencilOp, depthFailOp: StencilOp, compareOp: CompareOp) ProcCmdSetStencilOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, failOp: StencilOp, passOp: StencilOp, depthFailOp: StencilOp, compareOp: CompareOp) ProcCmdSetStencilReference :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, reference: u32) +ProcCmdSetStencilTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, stencilTestEnable: b32) ProcCmdSetStencilTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, stencilTestEnable: b32) ProcCmdSetStencilWriteMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, writeMask: u32) ProcCmdSetVertexInputEXT :: #type proc "system" (commandBuffer: CommandBuffer, vertexBindingDescriptionCount: u32, pVertexBindingDescriptions: [^]VertexInputBindingDescription2EXT, vertexAttributeDescriptionCount: u32, pVertexAttributeDescriptions: [^]VertexInputAttributeDescription2EXT) ProcCmdSetViewport :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewports: [^]Viewport) ProcCmdSetViewportShadingRatePaletteNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pShadingRatePalettes: [^]ShadingRatePaletteNV) ProcCmdSetViewportWScalingNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewportWScalings: [^]ViewportWScalingNV) +ProcCmdSetViewportWithCount :: #type proc "system" (commandBuffer: CommandBuffer, viewportCount: u32, pViewports: [^]Viewport) ProcCmdSetViewportWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, viewportCount: u32, pViewports: [^]Viewport) ProcCmdSubpassShadingHUAWEI :: #type proc "system" (commandBuffer: CommandBuffer) ProcCmdTraceRaysIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRaygenShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pMissShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pHitShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pCallableShaderBindingTable: [^]StridedDeviceAddressRegionKHR, indirectDeviceAddress: DeviceAddress) @@ -262,13 +291,15 @@ ProcCmdTraceRaysKHR :: #type proc "system" (comm ProcCmdTraceRaysNV :: #type proc "system" (commandBuffer: CommandBuffer, raygenShaderBindingTableBuffer: Buffer, raygenShaderBindingOffset: DeviceSize, missShaderBindingTableBuffer: Buffer, missShaderBindingOffset: DeviceSize, missShaderBindingStride: DeviceSize, hitShaderBindingTableBuffer: Buffer, hitShaderBindingOffset: DeviceSize, hitShaderBindingStride: DeviceSize, callableShaderBindingTableBuffer: Buffer, callableShaderBindingOffset: DeviceSize, callableShaderBindingStride: DeviceSize, width: u32, height: u32, depth: u32) ProcCmdUpdateBuffer :: #type proc "system" (commandBuffer: CommandBuffer, dstBuffer: Buffer, dstOffset: DeviceSize, dataSize: DeviceSize, pData: rawptr) ProcCmdWaitEvents :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) -ProcCmdWaitEvents2KHR :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfoKHR) +ProcCmdWaitEvents2 :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfo) +ProcCmdWaitEvents2KHR :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfo) ProcCmdWriteAccelerationStructuresPropertiesKHR :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureKHR, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) ProcCmdWriteAccelerationStructuresPropertiesNV :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureNV, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) -ProcCmdWriteBufferMarker2AMD :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2KHR, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) +ProcCmdWriteBufferMarker2AMD :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) ProcCmdWriteBufferMarkerAMD :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) ProcCmdWriteTimestamp :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, queryPool: QueryPool, query: u32) -ProcCmdWriteTimestamp2KHR :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2KHR, queryPool: QueryPool, query: u32) +ProcCmdWriteTimestamp2 :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, queryPool: QueryPool, query: u32) +ProcCmdWriteTimestamp2KHR :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, queryPool: QueryPool, query: u32) ProcCompileDeferredNV :: #type proc "system" (device: Device, pipeline: Pipeline, shader: u32) -> Result ProcCopyAccelerationStructureKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureInfoKHR) -> Result ProcCopyAccelerationStructureToMemoryKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) -> Result @@ -295,7 +326,8 @@ ProcCreateImageView :: #type proc "system" (devi ProcCreateIndirectCommandsLayoutNV :: #type proc "system" (device: Device, pCreateInfo: ^IndirectCommandsLayoutCreateInfoNV, pAllocator: ^AllocationCallbacks, pIndirectCommandsLayout: ^IndirectCommandsLayoutNV) -> Result ProcCreatePipelineCache :: #type proc "system" (device: Device, pCreateInfo: ^PipelineCacheCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineCache: ^PipelineCache) -> Result ProcCreatePipelineLayout :: #type proc "system" (device: Device, pCreateInfo: ^PipelineLayoutCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineLayout: ^PipelineLayout) -> Result -ProcCreatePrivateDataSlotEXT :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfoEXT, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlotEXT) -> Result +ProcCreatePrivateDataSlot :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfo, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlot) -> Result +ProcCreatePrivateDataSlotEXT :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfo, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlot) -> Result ProcCreateQueryPool :: #type proc "system" (device: Device, pCreateInfo: ^QueryPoolCreateInfo, pAllocator: ^AllocationCallbacks, pQueryPool: ^QueryPool) -> Result ProcCreateRayTracingPipelinesKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoKHR, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result ProcCreateRayTracingPipelinesNV :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoNV, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result @@ -335,7 +367,8 @@ ProcDestroyIndirectCommandsLayoutNV :: #type proc "system" (devi ProcDestroyPipeline :: #type proc "system" (device: Device, pipeline: Pipeline, pAllocator: ^AllocationCallbacks) ProcDestroyPipelineCache :: #type proc "system" (device: Device, pipelineCache: PipelineCache, pAllocator: ^AllocationCallbacks) ProcDestroyPipelineLayout :: #type proc "system" (device: Device, pipelineLayout: PipelineLayout, pAllocator: ^AllocationCallbacks) -ProcDestroyPrivateDataSlotEXT :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlotEXT, pAllocator: ^AllocationCallbacks) +ProcDestroyPrivateDataSlot :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlot, pAllocator: ^AllocationCallbacks) +ProcDestroyPrivateDataSlotEXT :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlot, pAllocator: ^AllocationCallbacks) ProcDestroyQueryPool :: #type proc "system" (device: Device, queryPool: QueryPool, pAllocator: ^AllocationCallbacks) ProcDestroyRenderPass :: #type proc "system" (device: Device, renderPass: RenderPass, pAllocator: ^AllocationCallbacks) ProcDestroySampler :: #type proc "system" (device: Device, sampler: Sampler, pAllocator: ^AllocationCallbacks) @@ -367,14 +400,22 @@ ProcGetBufferOpaqueCaptureAddressKHR :: #type proc "system" (devi ProcGetCalibratedTimestampsEXT :: #type proc "system" (device: Device, timestampCount: u32, pTimestampInfos: [^]CalibratedTimestampInfoEXT, pTimestamps: [^]u64, pMaxDeviation: ^u64) -> Result ProcGetDeferredOperationMaxConcurrencyKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> u32 ProcGetDeferredOperationResultKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> Result +ProcGetDescriptorSetHostMappingVALVE :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, ppData: ^rawptr) +ProcGetDescriptorSetLayoutHostMappingInfoVALVE :: #type proc "system" (device: Device, pBindingReference: ^DescriptorSetBindingReferenceVALVE, pHostMapping: ^DescriptorSetLayoutHostMappingInfoVALVE) ProcGetDescriptorSetLayoutSupport :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) ProcGetDescriptorSetLayoutSupportKHR :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) ProcGetDeviceAccelerationStructureCompatibilityKHR :: #type proc "system" (device: Device, pVersionInfo: ^AccelerationStructureVersionInfoKHR, pCompatibility: ^AccelerationStructureCompatibilityKHR) +ProcGetDeviceBufferMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceBufferMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceBufferMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceBufferMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) ProcGetDeviceGroupPeerMemoryFeatures :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) ProcGetDeviceGroupPeerMemoryFeaturesKHR :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) ProcGetDeviceGroupPresentCapabilitiesKHR :: #type proc "system" (device: Device, pDeviceGroupPresentCapabilities: [^]DeviceGroupPresentCapabilitiesKHR) -> Result ProcGetDeviceGroupSurfacePresentModes2EXT :: #type proc "system" (device: Device, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result ProcGetDeviceGroupSurfacePresentModesKHR :: #type proc "system" (device: Device, surface: SurfaceKHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result +ProcGetDeviceImageMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceImageMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceImageSparseMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) +ProcGetDeviceImageSparseMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) ProcGetDeviceMemoryCommitment :: #type proc "system" (device: Device, memory: DeviceMemory, pCommittedMemoryInBytes: [^]DeviceSize) ProcGetDeviceMemoryOpaqueCaptureAddress :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 ProcGetDeviceMemoryOpaqueCaptureAddressKHR :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 @@ -410,7 +451,8 @@ ProcGetPipelineCacheData :: #type proc "system" (devi ProcGetPipelineExecutableInternalRepresentationsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pInternalRepresentationCount: ^u32, pInternalRepresentations: [^]PipelineExecutableInternalRepresentationKHR) -> Result ProcGetPipelineExecutablePropertiesKHR :: #type proc "system" (device: Device, pPipelineInfo: ^PipelineInfoKHR, pExecutableCount: ^u32, pProperties: [^]PipelineExecutablePropertiesKHR) -> Result ProcGetPipelineExecutableStatisticsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pStatisticCount: ^u32, pStatistics: [^]PipelineExecutableStatisticKHR) -> Result -ProcGetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlotEXT, pData: ^u64) +ProcGetPrivateData :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, pData: ^u64) +ProcGetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, pData: ^u64) ProcGetQueryPoolResults :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dataSize: int, pData: rawptr, stride: DeviceSize, flags: QueryResultFlags) -> Result ProcGetQueueCheckpointData2NV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointData2NV) ProcGetQueueCheckpointDataNV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointDataNV) @@ -445,7 +487,8 @@ ProcQueueInsertDebugUtilsLabelEXT :: #type proc "system" (queu ProcQueuePresentKHR :: #type proc "system" (queue: Queue, pPresentInfo: ^PresentInfoKHR) -> Result ProcQueueSetPerformanceConfigurationINTEL :: #type proc "system" (queue: Queue, configuration: PerformanceConfigurationINTEL) -> Result ProcQueueSubmit :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo, fence: Fence) -> Result -ProcQueueSubmit2KHR :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2KHR, fence: Fence) -> Result +ProcQueueSubmit2 :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2, fence: Fence) -> Result +ProcQueueSubmit2KHR :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2, fence: Fence) -> Result ProcQueueWaitIdle :: #type proc "system" (queue: Queue) -> Result ProcRegisterDeviceEventEXT :: #type proc "system" (device: Device, pDeviceEventInfo: ^DeviceEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result ProcRegisterDisplayEventEXT :: #type proc "system" (device: Device, display: DisplayKHR, pDisplayEventInfo: ^DisplayEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result @@ -465,7 +508,8 @@ ProcSetDeviceMemoryPriorityEXT :: #type proc "system" (devi ProcSetEvent :: #type proc "system" (device: Device, event: Event) -> Result ProcSetHdrMetadataEXT :: #type proc "system" (device: Device, swapchainCount: u32, pSwapchains: [^]SwapchainKHR, pMetadata: ^HdrMetadataEXT) ProcSetLocalDimmingAMD :: #type proc "system" (device: Device, swapChain: SwapchainKHR, localDimmingEnable: b32) -ProcSetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlotEXT, data: u64) -> Result +ProcSetPrivateData :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, data: u64) -> Result +ProcSetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, data: u64) -> Result ProcSignalSemaphore :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result ProcSignalSemaphoreKHR :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result ProcTrimCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolTrimFlags) @@ -568,6 +612,7 @@ GetPhysicalDeviceSurfaceFormatsKHR: ProcGetPhysical GetPhysicalDeviceSurfacePresentModes2EXT: ProcGetPhysicalDeviceSurfacePresentModes2EXT GetPhysicalDeviceSurfacePresentModesKHR: ProcGetPhysicalDeviceSurfacePresentModesKHR GetPhysicalDeviceSurfaceSupportKHR: ProcGetPhysicalDeviceSurfaceSupportKHR +GetPhysicalDeviceToolProperties: ProcGetPhysicalDeviceToolProperties GetPhysicalDeviceToolPropertiesEXT: ProcGetPhysicalDeviceToolPropertiesEXT GetPhysicalDeviceWin32PresentationSupportKHR: ProcGetPhysicalDeviceWin32PresentationSupportKHR GetWinrtDisplayNV: ProcGetWinrtDisplayNV @@ -599,6 +644,8 @@ CmdBeginQueryIndexedEXT: ProcCmdBeginQueryIndexedEXT CmdBeginRenderPass: ProcCmdBeginRenderPass CmdBeginRenderPass2: ProcCmdBeginRenderPass2 CmdBeginRenderPass2KHR: ProcCmdBeginRenderPass2KHR +CmdBeginRendering: ProcCmdBeginRendering +CmdBeginRenderingKHR: ProcCmdBeginRenderingKHR CmdBeginTransformFeedbackEXT: ProcCmdBeginTransformFeedbackEXT CmdBindDescriptorSets: ProcCmdBindDescriptorSets CmdBindIndexBuffer: ProcCmdBindIndexBuffer @@ -608,8 +655,10 @@ CmdBindPipelineShaderGroupNV: ProcCmdBindPipelineShaderGroupN CmdBindShadingRateImageNV: ProcCmdBindShadingRateImageNV CmdBindTransformFeedbackBuffersEXT: ProcCmdBindTransformFeedbackBuffersEXT CmdBindVertexBuffers: ProcCmdBindVertexBuffers +CmdBindVertexBuffers2: ProcCmdBindVertexBuffers2 CmdBindVertexBuffers2EXT: ProcCmdBindVertexBuffers2EXT CmdBlitImage: ProcCmdBlitImage +CmdBlitImage2: ProcCmdBlitImage2 CmdBlitImage2KHR: ProcCmdBlitImage2KHR CmdBuildAccelerationStructureNV: ProcCmdBuildAccelerationStructureNV CmdBuildAccelerationStructuresIndirectKHR: ProcCmdBuildAccelerationStructuresIndirectKHR @@ -621,12 +670,16 @@ CmdCopyAccelerationStructureKHR: ProcCmdCopyAccelerationStructur CmdCopyAccelerationStructureNV: ProcCmdCopyAccelerationStructureNV CmdCopyAccelerationStructureToMemoryKHR: ProcCmdCopyAccelerationStructureToMemoryKHR CmdCopyBuffer: ProcCmdCopyBuffer +CmdCopyBuffer2: ProcCmdCopyBuffer2 CmdCopyBuffer2KHR: ProcCmdCopyBuffer2KHR CmdCopyBufferToImage: ProcCmdCopyBufferToImage +CmdCopyBufferToImage2: ProcCmdCopyBufferToImage2 CmdCopyBufferToImage2KHR: ProcCmdCopyBufferToImage2KHR CmdCopyImage: ProcCmdCopyImage +CmdCopyImage2: ProcCmdCopyImage2 CmdCopyImage2KHR: ProcCmdCopyImage2KHR CmdCopyImageToBuffer: ProcCmdCopyImageToBuffer +CmdCopyImageToBuffer2: ProcCmdCopyImageToBuffer2 CmdCopyImageToBuffer2KHR: ProcCmdCopyImageToBuffer2KHR CmdCopyMemoryToAccelerationStructureKHR: ProcCmdCopyMemoryToAccelerationStructureKHR CmdCopyQueryPoolResults: ProcCmdCopyQueryPoolResults @@ -661,6 +714,8 @@ CmdEndQueryIndexedEXT: ProcCmdEndQueryIndexedEXT CmdEndRenderPass: ProcCmdEndRenderPass CmdEndRenderPass2: ProcCmdEndRenderPass2 CmdEndRenderPass2KHR: ProcCmdEndRenderPass2KHR +CmdEndRendering: ProcCmdEndRendering +CmdEndRenderingKHR: ProcCmdEndRenderingKHR CmdEndTransformFeedbackEXT: ProcCmdEndTransformFeedbackEXT CmdExecuteCommands: ProcCmdExecuteCommands CmdExecuteGeneratedCommandsNV: ProcCmdExecuteGeneratedCommandsNV @@ -670,35 +725,46 @@ CmdNextSubpass: ProcCmdNextSubpass CmdNextSubpass2: ProcCmdNextSubpass2 CmdNextSubpass2KHR: ProcCmdNextSubpass2KHR CmdPipelineBarrier: ProcCmdPipelineBarrier +CmdPipelineBarrier2: ProcCmdPipelineBarrier2 CmdPipelineBarrier2KHR: ProcCmdPipelineBarrier2KHR CmdPreprocessGeneratedCommandsNV: ProcCmdPreprocessGeneratedCommandsNV CmdPushConstants: ProcCmdPushConstants CmdPushDescriptorSetKHR: ProcCmdPushDescriptorSetKHR CmdPushDescriptorSetWithTemplateKHR: ProcCmdPushDescriptorSetWithTemplateKHR CmdResetEvent: ProcCmdResetEvent +CmdResetEvent2: ProcCmdResetEvent2 CmdResetEvent2KHR: ProcCmdResetEvent2KHR CmdResetQueryPool: ProcCmdResetQueryPool CmdResolveImage: ProcCmdResolveImage +CmdResolveImage2: ProcCmdResolveImage2 CmdResolveImage2KHR: ProcCmdResolveImage2KHR CmdSetBlendConstants: ProcCmdSetBlendConstants CmdSetCheckpointNV: ProcCmdSetCheckpointNV CmdSetCoarseSampleOrderNV: ProcCmdSetCoarseSampleOrderNV +CmdSetCullMode: ProcCmdSetCullMode CmdSetCullModeEXT: ProcCmdSetCullModeEXT CmdSetDepthBias: ProcCmdSetDepthBias +CmdSetDepthBiasEnable: ProcCmdSetDepthBiasEnable CmdSetDepthBiasEnableEXT: ProcCmdSetDepthBiasEnableEXT CmdSetDepthBounds: ProcCmdSetDepthBounds +CmdSetDepthBoundsTestEnable: ProcCmdSetDepthBoundsTestEnable CmdSetDepthBoundsTestEnableEXT: ProcCmdSetDepthBoundsTestEnableEXT +CmdSetDepthCompareOp: ProcCmdSetDepthCompareOp CmdSetDepthCompareOpEXT: ProcCmdSetDepthCompareOpEXT +CmdSetDepthTestEnable: ProcCmdSetDepthTestEnable CmdSetDepthTestEnableEXT: ProcCmdSetDepthTestEnableEXT +CmdSetDepthWriteEnable: ProcCmdSetDepthWriteEnable CmdSetDepthWriteEnableEXT: ProcCmdSetDepthWriteEnableEXT CmdSetDeviceMask: ProcCmdSetDeviceMask CmdSetDeviceMaskKHR: ProcCmdSetDeviceMaskKHR CmdSetDiscardRectangleEXT: ProcCmdSetDiscardRectangleEXT CmdSetEvent: ProcCmdSetEvent +CmdSetEvent2: ProcCmdSetEvent2 CmdSetEvent2KHR: ProcCmdSetEvent2KHR CmdSetExclusiveScissorNV: ProcCmdSetExclusiveScissorNV CmdSetFragmentShadingRateEnumNV: ProcCmdSetFragmentShadingRateEnumNV CmdSetFragmentShadingRateKHR: ProcCmdSetFragmentShadingRateKHR +CmdSetFrontFace: ProcCmdSetFrontFace CmdSetFrontFaceEXT: ProcCmdSetFrontFaceEXT CmdSetLineStippleEXT: ProcCmdSetLineStippleEXT CmdSetLineWidth: ProcCmdSetLineWidth @@ -707,22 +773,29 @@ CmdSetPatchControlPointsEXT: ProcCmdSetPatchControlPointsEXT CmdSetPerformanceMarkerINTEL: ProcCmdSetPerformanceMarkerINTEL CmdSetPerformanceOverrideINTEL: ProcCmdSetPerformanceOverrideINTEL CmdSetPerformanceStreamMarkerINTEL: ProcCmdSetPerformanceStreamMarkerINTEL +CmdSetPrimitiveRestartEnable: ProcCmdSetPrimitiveRestartEnable CmdSetPrimitiveRestartEnableEXT: ProcCmdSetPrimitiveRestartEnableEXT +CmdSetPrimitiveTopology: ProcCmdSetPrimitiveTopology CmdSetPrimitiveTopologyEXT: ProcCmdSetPrimitiveTopologyEXT +CmdSetRasterizerDiscardEnable: ProcCmdSetRasterizerDiscardEnable CmdSetRasterizerDiscardEnableEXT: ProcCmdSetRasterizerDiscardEnableEXT CmdSetRayTracingPipelineStackSizeKHR: ProcCmdSetRayTracingPipelineStackSizeKHR CmdSetSampleLocationsEXT: ProcCmdSetSampleLocationsEXT CmdSetScissor: ProcCmdSetScissor +CmdSetScissorWithCount: ProcCmdSetScissorWithCount CmdSetScissorWithCountEXT: ProcCmdSetScissorWithCountEXT CmdSetStencilCompareMask: ProcCmdSetStencilCompareMask +CmdSetStencilOp: ProcCmdSetStencilOp CmdSetStencilOpEXT: ProcCmdSetStencilOpEXT CmdSetStencilReference: ProcCmdSetStencilReference +CmdSetStencilTestEnable: ProcCmdSetStencilTestEnable CmdSetStencilTestEnableEXT: ProcCmdSetStencilTestEnableEXT CmdSetStencilWriteMask: ProcCmdSetStencilWriteMask CmdSetVertexInputEXT: ProcCmdSetVertexInputEXT CmdSetViewport: ProcCmdSetViewport CmdSetViewportShadingRatePaletteNV: ProcCmdSetViewportShadingRatePaletteNV CmdSetViewportWScalingNV: ProcCmdSetViewportWScalingNV +CmdSetViewportWithCount: ProcCmdSetViewportWithCount CmdSetViewportWithCountEXT: ProcCmdSetViewportWithCountEXT CmdSubpassShadingHUAWEI: ProcCmdSubpassShadingHUAWEI CmdTraceRaysIndirectKHR: ProcCmdTraceRaysIndirectKHR @@ -730,12 +803,14 @@ CmdTraceRaysKHR: ProcCmdTraceRaysKHR CmdTraceRaysNV: ProcCmdTraceRaysNV CmdUpdateBuffer: ProcCmdUpdateBuffer CmdWaitEvents: ProcCmdWaitEvents +CmdWaitEvents2: ProcCmdWaitEvents2 CmdWaitEvents2KHR: ProcCmdWaitEvents2KHR CmdWriteAccelerationStructuresPropertiesKHR: ProcCmdWriteAccelerationStructuresPropertiesKHR CmdWriteAccelerationStructuresPropertiesNV: ProcCmdWriteAccelerationStructuresPropertiesNV CmdWriteBufferMarker2AMD: ProcCmdWriteBufferMarker2AMD CmdWriteBufferMarkerAMD: ProcCmdWriteBufferMarkerAMD CmdWriteTimestamp: ProcCmdWriteTimestamp +CmdWriteTimestamp2: ProcCmdWriteTimestamp2 CmdWriteTimestamp2KHR: ProcCmdWriteTimestamp2KHR CompileDeferredNV: ProcCompileDeferredNV CopyAccelerationStructureKHR: ProcCopyAccelerationStructureKHR @@ -763,6 +838,7 @@ CreateImageView: ProcCreateImageView CreateIndirectCommandsLayoutNV: ProcCreateIndirectCommandsLayoutNV CreatePipelineCache: ProcCreatePipelineCache CreatePipelineLayout: ProcCreatePipelineLayout +CreatePrivateDataSlot: ProcCreatePrivateDataSlot CreatePrivateDataSlotEXT: ProcCreatePrivateDataSlotEXT CreateQueryPool: ProcCreateQueryPool CreateRayTracingPipelinesKHR: ProcCreateRayTracingPipelinesKHR @@ -803,6 +879,7 @@ DestroyIndirectCommandsLayoutNV: ProcDestroyIndirectCommandsLayo DestroyPipeline: ProcDestroyPipeline DestroyPipelineCache: ProcDestroyPipelineCache DestroyPipelineLayout: ProcDestroyPipelineLayout +DestroyPrivateDataSlot: ProcDestroyPrivateDataSlot DestroyPrivateDataSlotEXT: ProcDestroyPrivateDataSlotEXT DestroyQueryPool: ProcDestroyQueryPool DestroyRenderPass: ProcDestroyRenderPass @@ -835,14 +912,22 @@ GetBufferOpaqueCaptureAddressKHR: ProcGetBufferOpaqueCaptureAddre GetCalibratedTimestampsEXT: ProcGetCalibratedTimestampsEXT GetDeferredOperationMaxConcurrencyKHR: ProcGetDeferredOperationMaxConcurrencyKHR GetDeferredOperationResultKHR: ProcGetDeferredOperationResultKHR +GetDescriptorSetHostMappingVALVE: ProcGetDescriptorSetHostMappingVALVE +GetDescriptorSetLayoutHostMappingInfoVALVE: ProcGetDescriptorSetLayoutHostMappingInfoVALVE GetDescriptorSetLayoutSupport: ProcGetDescriptorSetLayoutSupport GetDescriptorSetLayoutSupportKHR: ProcGetDescriptorSetLayoutSupportKHR GetDeviceAccelerationStructureCompatibilityKHR: ProcGetDeviceAccelerationStructureCompatibilityKHR +GetDeviceBufferMemoryRequirements: ProcGetDeviceBufferMemoryRequirements +GetDeviceBufferMemoryRequirementsKHR: ProcGetDeviceBufferMemoryRequirementsKHR GetDeviceGroupPeerMemoryFeatures: ProcGetDeviceGroupPeerMemoryFeatures GetDeviceGroupPeerMemoryFeaturesKHR: ProcGetDeviceGroupPeerMemoryFeaturesKHR GetDeviceGroupPresentCapabilitiesKHR: ProcGetDeviceGroupPresentCapabilitiesKHR GetDeviceGroupSurfacePresentModes2EXT: ProcGetDeviceGroupSurfacePresentModes2EXT GetDeviceGroupSurfacePresentModesKHR: ProcGetDeviceGroupSurfacePresentModesKHR +GetDeviceImageMemoryRequirements: ProcGetDeviceImageMemoryRequirements +GetDeviceImageMemoryRequirementsKHR: ProcGetDeviceImageMemoryRequirementsKHR +GetDeviceImageSparseMemoryRequirements: ProcGetDeviceImageSparseMemoryRequirements +GetDeviceImageSparseMemoryRequirementsKHR: ProcGetDeviceImageSparseMemoryRequirementsKHR GetDeviceMemoryCommitment: ProcGetDeviceMemoryCommitment GetDeviceMemoryOpaqueCaptureAddress: ProcGetDeviceMemoryOpaqueCaptureAddress GetDeviceMemoryOpaqueCaptureAddressKHR: ProcGetDeviceMemoryOpaqueCaptureAddressKHR @@ -878,6 +963,7 @@ GetPipelineCacheData: ProcGetPipelineCacheData GetPipelineExecutableInternalRepresentationsKHR: ProcGetPipelineExecutableInternalRepresentationsKHR GetPipelineExecutablePropertiesKHR: ProcGetPipelineExecutablePropertiesKHR GetPipelineExecutableStatisticsKHR: ProcGetPipelineExecutableStatisticsKHR +GetPrivateData: ProcGetPrivateData GetPrivateDataEXT: ProcGetPrivateDataEXT GetQueryPoolResults: ProcGetQueryPoolResults GetQueueCheckpointData2NV: ProcGetQueueCheckpointData2NV @@ -913,6 +999,7 @@ QueueInsertDebugUtilsLabelEXT: ProcQueueInsertDebugUtilsLabelE QueuePresentKHR: ProcQueuePresentKHR QueueSetPerformanceConfigurationINTEL: ProcQueueSetPerformanceConfigurationINTEL QueueSubmit: ProcQueueSubmit +QueueSubmit2: ProcQueueSubmit2 QueueSubmit2KHR: ProcQueueSubmit2KHR QueueWaitIdle: ProcQueueWaitIdle RegisterDeviceEventEXT: ProcRegisterDeviceEventEXT @@ -933,6 +1020,7 @@ SetDeviceMemoryPriorityEXT: ProcSetDeviceMemoryPriorityEXT SetEvent: ProcSetEvent SetHdrMetadataEXT: ProcSetHdrMetadataEXT SetLocalDimmingAMD: ProcSetLocalDimmingAMD +SetPrivateData: ProcSetPrivateData SetPrivateDataEXT: ProcSetPrivateDataEXT SignalSemaphore: ProcSignalSemaphore SignalSemaphoreKHR: ProcSignalSemaphoreKHR @@ -1036,6 +1124,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&GetPhysicalDeviceSurfacePresentModes2EXT, "vkGetPhysicalDeviceSurfacePresentModes2EXT") set_proc_address(&GetPhysicalDeviceSurfacePresentModesKHR, "vkGetPhysicalDeviceSurfacePresentModesKHR") set_proc_address(&GetPhysicalDeviceSurfaceSupportKHR, "vkGetPhysicalDeviceSurfaceSupportKHR") + set_proc_address(&GetPhysicalDeviceToolProperties, "vkGetPhysicalDeviceToolProperties") set_proc_address(&GetPhysicalDeviceToolPropertiesEXT, "vkGetPhysicalDeviceToolPropertiesEXT") set_proc_address(&GetPhysicalDeviceWin32PresentationSupportKHR, "vkGetPhysicalDeviceWin32PresentationSupportKHR") set_proc_address(&GetWinrtDisplayNV, "vkGetWinrtDisplayNV") @@ -1067,6 +1156,8 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdBeginRenderPass, "vkCmdBeginRenderPass") set_proc_address(&CmdBeginRenderPass2, "vkCmdBeginRenderPass2") set_proc_address(&CmdBeginRenderPass2KHR, "vkCmdBeginRenderPass2KHR") + set_proc_address(&CmdBeginRendering, "vkCmdBeginRendering") + set_proc_address(&CmdBeginRenderingKHR, "vkCmdBeginRenderingKHR") set_proc_address(&CmdBeginTransformFeedbackEXT, "vkCmdBeginTransformFeedbackEXT") set_proc_address(&CmdBindDescriptorSets, "vkCmdBindDescriptorSets") set_proc_address(&CmdBindIndexBuffer, "vkCmdBindIndexBuffer") @@ -1076,8 +1167,10 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdBindShadingRateImageNV, "vkCmdBindShadingRateImageNV") set_proc_address(&CmdBindTransformFeedbackBuffersEXT, "vkCmdBindTransformFeedbackBuffersEXT") set_proc_address(&CmdBindVertexBuffers, "vkCmdBindVertexBuffers") + set_proc_address(&CmdBindVertexBuffers2, "vkCmdBindVertexBuffers2") set_proc_address(&CmdBindVertexBuffers2EXT, "vkCmdBindVertexBuffers2EXT") set_proc_address(&CmdBlitImage, "vkCmdBlitImage") + set_proc_address(&CmdBlitImage2, "vkCmdBlitImage2") set_proc_address(&CmdBlitImage2KHR, "vkCmdBlitImage2KHR") set_proc_address(&CmdBuildAccelerationStructureNV, "vkCmdBuildAccelerationStructureNV") set_proc_address(&CmdBuildAccelerationStructuresIndirectKHR, "vkCmdBuildAccelerationStructuresIndirectKHR") @@ -1089,12 +1182,16 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdCopyAccelerationStructureNV, "vkCmdCopyAccelerationStructureNV") set_proc_address(&CmdCopyAccelerationStructureToMemoryKHR, "vkCmdCopyAccelerationStructureToMemoryKHR") set_proc_address(&CmdCopyBuffer, "vkCmdCopyBuffer") + set_proc_address(&CmdCopyBuffer2, "vkCmdCopyBuffer2") set_proc_address(&CmdCopyBuffer2KHR, "vkCmdCopyBuffer2KHR") set_proc_address(&CmdCopyBufferToImage, "vkCmdCopyBufferToImage") + set_proc_address(&CmdCopyBufferToImage2, "vkCmdCopyBufferToImage2") set_proc_address(&CmdCopyBufferToImage2KHR, "vkCmdCopyBufferToImage2KHR") set_proc_address(&CmdCopyImage, "vkCmdCopyImage") + set_proc_address(&CmdCopyImage2, "vkCmdCopyImage2") set_proc_address(&CmdCopyImage2KHR, "vkCmdCopyImage2KHR") set_proc_address(&CmdCopyImageToBuffer, "vkCmdCopyImageToBuffer") + set_proc_address(&CmdCopyImageToBuffer2, "vkCmdCopyImageToBuffer2") set_proc_address(&CmdCopyImageToBuffer2KHR, "vkCmdCopyImageToBuffer2KHR") set_proc_address(&CmdCopyMemoryToAccelerationStructureKHR, "vkCmdCopyMemoryToAccelerationStructureKHR") set_proc_address(&CmdCopyQueryPoolResults, "vkCmdCopyQueryPoolResults") @@ -1129,6 +1226,8 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdEndRenderPass, "vkCmdEndRenderPass") set_proc_address(&CmdEndRenderPass2, "vkCmdEndRenderPass2") set_proc_address(&CmdEndRenderPass2KHR, "vkCmdEndRenderPass2KHR") + set_proc_address(&CmdEndRendering, "vkCmdEndRendering") + set_proc_address(&CmdEndRenderingKHR, "vkCmdEndRenderingKHR") set_proc_address(&CmdEndTransformFeedbackEXT, "vkCmdEndTransformFeedbackEXT") set_proc_address(&CmdExecuteCommands, "vkCmdExecuteCommands") set_proc_address(&CmdExecuteGeneratedCommandsNV, "vkCmdExecuteGeneratedCommandsNV") @@ -1138,35 +1237,46 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdNextSubpass2, "vkCmdNextSubpass2") set_proc_address(&CmdNextSubpass2KHR, "vkCmdNextSubpass2KHR") set_proc_address(&CmdPipelineBarrier, "vkCmdPipelineBarrier") + set_proc_address(&CmdPipelineBarrier2, "vkCmdPipelineBarrier2") set_proc_address(&CmdPipelineBarrier2KHR, "vkCmdPipelineBarrier2KHR") set_proc_address(&CmdPreprocessGeneratedCommandsNV, "vkCmdPreprocessGeneratedCommandsNV") set_proc_address(&CmdPushConstants, "vkCmdPushConstants") set_proc_address(&CmdPushDescriptorSetKHR, "vkCmdPushDescriptorSetKHR") set_proc_address(&CmdPushDescriptorSetWithTemplateKHR, "vkCmdPushDescriptorSetWithTemplateKHR") set_proc_address(&CmdResetEvent, "vkCmdResetEvent") + set_proc_address(&CmdResetEvent2, "vkCmdResetEvent2") set_proc_address(&CmdResetEvent2KHR, "vkCmdResetEvent2KHR") set_proc_address(&CmdResetQueryPool, "vkCmdResetQueryPool") set_proc_address(&CmdResolveImage, "vkCmdResolveImage") + set_proc_address(&CmdResolveImage2, "vkCmdResolveImage2") set_proc_address(&CmdResolveImage2KHR, "vkCmdResolveImage2KHR") set_proc_address(&CmdSetBlendConstants, "vkCmdSetBlendConstants") set_proc_address(&CmdSetCheckpointNV, "vkCmdSetCheckpointNV") set_proc_address(&CmdSetCoarseSampleOrderNV, "vkCmdSetCoarseSampleOrderNV") + set_proc_address(&CmdSetCullMode, "vkCmdSetCullMode") set_proc_address(&CmdSetCullModeEXT, "vkCmdSetCullModeEXT") set_proc_address(&CmdSetDepthBias, "vkCmdSetDepthBias") + set_proc_address(&CmdSetDepthBiasEnable, "vkCmdSetDepthBiasEnable") set_proc_address(&CmdSetDepthBiasEnableEXT, "vkCmdSetDepthBiasEnableEXT") set_proc_address(&CmdSetDepthBounds, "vkCmdSetDepthBounds") + set_proc_address(&CmdSetDepthBoundsTestEnable, "vkCmdSetDepthBoundsTestEnable") set_proc_address(&CmdSetDepthBoundsTestEnableEXT, "vkCmdSetDepthBoundsTestEnableEXT") + set_proc_address(&CmdSetDepthCompareOp, "vkCmdSetDepthCompareOp") set_proc_address(&CmdSetDepthCompareOpEXT, "vkCmdSetDepthCompareOpEXT") + set_proc_address(&CmdSetDepthTestEnable, "vkCmdSetDepthTestEnable") set_proc_address(&CmdSetDepthTestEnableEXT, "vkCmdSetDepthTestEnableEXT") + set_proc_address(&CmdSetDepthWriteEnable, "vkCmdSetDepthWriteEnable") set_proc_address(&CmdSetDepthWriteEnableEXT, "vkCmdSetDepthWriteEnableEXT") set_proc_address(&CmdSetDeviceMask, "vkCmdSetDeviceMask") set_proc_address(&CmdSetDeviceMaskKHR, "vkCmdSetDeviceMaskKHR") set_proc_address(&CmdSetDiscardRectangleEXT, "vkCmdSetDiscardRectangleEXT") set_proc_address(&CmdSetEvent, "vkCmdSetEvent") + set_proc_address(&CmdSetEvent2, "vkCmdSetEvent2") set_proc_address(&CmdSetEvent2KHR, "vkCmdSetEvent2KHR") set_proc_address(&CmdSetExclusiveScissorNV, "vkCmdSetExclusiveScissorNV") set_proc_address(&CmdSetFragmentShadingRateEnumNV, "vkCmdSetFragmentShadingRateEnumNV") set_proc_address(&CmdSetFragmentShadingRateKHR, "vkCmdSetFragmentShadingRateKHR") + set_proc_address(&CmdSetFrontFace, "vkCmdSetFrontFace") set_proc_address(&CmdSetFrontFaceEXT, "vkCmdSetFrontFaceEXT") set_proc_address(&CmdSetLineStippleEXT, "vkCmdSetLineStippleEXT") set_proc_address(&CmdSetLineWidth, "vkCmdSetLineWidth") @@ -1175,22 +1285,29 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdSetPerformanceMarkerINTEL, "vkCmdSetPerformanceMarkerINTEL") set_proc_address(&CmdSetPerformanceOverrideINTEL, "vkCmdSetPerformanceOverrideINTEL") set_proc_address(&CmdSetPerformanceStreamMarkerINTEL, "vkCmdSetPerformanceStreamMarkerINTEL") + set_proc_address(&CmdSetPrimitiveRestartEnable, "vkCmdSetPrimitiveRestartEnable") set_proc_address(&CmdSetPrimitiveRestartEnableEXT, "vkCmdSetPrimitiveRestartEnableEXT") + set_proc_address(&CmdSetPrimitiveTopology, "vkCmdSetPrimitiveTopology") set_proc_address(&CmdSetPrimitiveTopologyEXT, "vkCmdSetPrimitiveTopologyEXT") + set_proc_address(&CmdSetRasterizerDiscardEnable, "vkCmdSetRasterizerDiscardEnable") set_proc_address(&CmdSetRasterizerDiscardEnableEXT, "vkCmdSetRasterizerDiscardEnableEXT") set_proc_address(&CmdSetRayTracingPipelineStackSizeKHR, "vkCmdSetRayTracingPipelineStackSizeKHR") set_proc_address(&CmdSetSampleLocationsEXT, "vkCmdSetSampleLocationsEXT") set_proc_address(&CmdSetScissor, "vkCmdSetScissor") + set_proc_address(&CmdSetScissorWithCount, "vkCmdSetScissorWithCount") set_proc_address(&CmdSetScissorWithCountEXT, "vkCmdSetScissorWithCountEXT") set_proc_address(&CmdSetStencilCompareMask, "vkCmdSetStencilCompareMask") + set_proc_address(&CmdSetStencilOp, "vkCmdSetStencilOp") set_proc_address(&CmdSetStencilOpEXT, "vkCmdSetStencilOpEXT") set_proc_address(&CmdSetStencilReference, "vkCmdSetStencilReference") + set_proc_address(&CmdSetStencilTestEnable, "vkCmdSetStencilTestEnable") set_proc_address(&CmdSetStencilTestEnableEXT, "vkCmdSetStencilTestEnableEXT") set_proc_address(&CmdSetStencilWriteMask, "vkCmdSetStencilWriteMask") set_proc_address(&CmdSetVertexInputEXT, "vkCmdSetVertexInputEXT") set_proc_address(&CmdSetViewport, "vkCmdSetViewport") set_proc_address(&CmdSetViewportShadingRatePaletteNV, "vkCmdSetViewportShadingRatePaletteNV") set_proc_address(&CmdSetViewportWScalingNV, "vkCmdSetViewportWScalingNV") + set_proc_address(&CmdSetViewportWithCount, "vkCmdSetViewportWithCount") set_proc_address(&CmdSetViewportWithCountEXT, "vkCmdSetViewportWithCountEXT") set_proc_address(&CmdSubpassShadingHUAWEI, "vkCmdSubpassShadingHUAWEI") set_proc_address(&CmdTraceRaysIndirectKHR, "vkCmdTraceRaysIndirectKHR") @@ -1198,12 +1315,14 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CmdTraceRaysNV, "vkCmdTraceRaysNV") set_proc_address(&CmdUpdateBuffer, "vkCmdUpdateBuffer") set_proc_address(&CmdWaitEvents, "vkCmdWaitEvents") + set_proc_address(&CmdWaitEvents2, "vkCmdWaitEvents2") set_proc_address(&CmdWaitEvents2KHR, "vkCmdWaitEvents2KHR") set_proc_address(&CmdWriteAccelerationStructuresPropertiesKHR, "vkCmdWriteAccelerationStructuresPropertiesKHR") set_proc_address(&CmdWriteAccelerationStructuresPropertiesNV, "vkCmdWriteAccelerationStructuresPropertiesNV") set_proc_address(&CmdWriteBufferMarker2AMD, "vkCmdWriteBufferMarker2AMD") set_proc_address(&CmdWriteBufferMarkerAMD, "vkCmdWriteBufferMarkerAMD") set_proc_address(&CmdWriteTimestamp, "vkCmdWriteTimestamp") + set_proc_address(&CmdWriteTimestamp2, "vkCmdWriteTimestamp2") set_proc_address(&CmdWriteTimestamp2KHR, "vkCmdWriteTimestamp2KHR") set_proc_address(&CompileDeferredNV, "vkCompileDeferredNV") set_proc_address(&CopyAccelerationStructureKHR, "vkCopyAccelerationStructureKHR") @@ -1231,6 +1350,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&CreateIndirectCommandsLayoutNV, "vkCreateIndirectCommandsLayoutNV") set_proc_address(&CreatePipelineCache, "vkCreatePipelineCache") set_proc_address(&CreatePipelineLayout, "vkCreatePipelineLayout") + set_proc_address(&CreatePrivateDataSlot, "vkCreatePrivateDataSlot") set_proc_address(&CreatePrivateDataSlotEXT, "vkCreatePrivateDataSlotEXT") set_proc_address(&CreateQueryPool, "vkCreateQueryPool") set_proc_address(&CreateRayTracingPipelinesKHR, "vkCreateRayTracingPipelinesKHR") @@ -1271,6 +1391,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&DestroyPipeline, "vkDestroyPipeline") set_proc_address(&DestroyPipelineCache, "vkDestroyPipelineCache") set_proc_address(&DestroyPipelineLayout, "vkDestroyPipelineLayout") + set_proc_address(&DestroyPrivateDataSlot, "vkDestroyPrivateDataSlot") set_proc_address(&DestroyPrivateDataSlotEXT, "vkDestroyPrivateDataSlotEXT") set_proc_address(&DestroyQueryPool, "vkDestroyQueryPool") set_proc_address(&DestroyRenderPass, "vkDestroyRenderPass") @@ -1303,14 +1424,22 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&GetCalibratedTimestampsEXT, "vkGetCalibratedTimestampsEXT") set_proc_address(&GetDeferredOperationMaxConcurrencyKHR, "vkGetDeferredOperationMaxConcurrencyKHR") set_proc_address(&GetDeferredOperationResultKHR, "vkGetDeferredOperationResultKHR") + set_proc_address(&GetDescriptorSetHostMappingVALVE, "vkGetDescriptorSetHostMappingVALVE") + set_proc_address(&GetDescriptorSetLayoutHostMappingInfoVALVE, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") set_proc_address(&GetDescriptorSetLayoutSupport, "vkGetDescriptorSetLayoutSupport") set_proc_address(&GetDescriptorSetLayoutSupportKHR, "vkGetDescriptorSetLayoutSupportKHR") set_proc_address(&GetDeviceAccelerationStructureCompatibilityKHR, "vkGetDeviceAccelerationStructureCompatibilityKHR") + set_proc_address(&GetDeviceBufferMemoryRequirements, "vkGetDeviceBufferMemoryRequirements") + set_proc_address(&GetDeviceBufferMemoryRequirementsKHR, "vkGetDeviceBufferMemoryRequirementsKHR") set_proc_address(&GetDeviceGroupPeerMemoryFeatures, "vkGetDeviceGroupPeerMemoryFeatures") set_proc_address(&GetDeviceGroupPeerMemoryFeaturesKHR, "vkGetDeviceGroupPeerMemoryFeaturesKHR") set_proc_address(&GetDeviceGroupPresentCapabilitiesKHR, "vkGetDeviceGroupPresentCapabilitiesKHR") set_proc_address(&GetDeviceGroupSurfacePresentModes2EXT, "vkGetDeviceGroupSurfacePresentModes2EXT") set_proc_address(&GetDeviceGroupSurfacePresentModesKHR, "vkGetDeviceGroupSurfacePresentModesKHR") + set_proc_address(&GetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements") + set_proc_address(&GetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR") + set_proc_address(&GetDeviceImageSparseMemoryRequirements, "vkGetDeviceImageSparseMemoryRequirements") + set_proc_address(&GetDeviceImageSparseMemoryRequirementsKHR, "vkGetDeviceImageSparseMemoryRequirementsKHR") set_proc_address(&GetDeviceMemoryCommitment, "vkGetDeviceMemoryCommitment") set_proc_address(&GetDeviceMemoryOpaqueCaptureAddress, "vkGetDeviceMemoryOpaqueCaptureAddress") set_proc_address(&GetDeviceMemoryOpaqueCaptureAddressKHR, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") @@ -1346,6 +1475,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&GetPipelineExecutableInternalRepresentationsKHR, "vkGetPipelineExecutableInternalRepresentationsKHR") set_proc_address(&GetPipelineExecutablePropertiesKHR, "vkGetPipelineExecutablePropertiesKHR") set_proc_address(&GetPipelineExecutableStatisticsKHR, "vkGetPipelineExecutableStatisticsKHR") + set_proc_address(&GetPrivateData, "vkGetPrivateData") set_proc_address(&GetPrivateDataEXT, "vkGetPrivateDataEXT") set_proc_address(&GetQueryPoolResults, "vkGetQueryPoolResults") set_proc_address(&GetQueueCheckpointData2NV, "vkGetQueueCheckpointData2NV") @@ -1381,6 +1511,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&QueuePresentKHR, "vkQueuePresentKHR") set_proc_address(&QueueSetPerformanceConfigurationINTEL, "vkQueueSetPerformanceConfigurationINTEL") set_proc_address(&QueueSubmit, "vkQueueSubmit") + set_proc_address(&QueueSubmit2, "vkQueueSubmit2") set_proc_address(&QueueSubmit2KHR, "vkQueueSubmit2KHR") set_proc_address(&QueueWaitIdle, "vkQueueWaitIdle") set_proc_address(&RegisterDeviceEventEXT, "vkRegisterDeviceEventEXT") @@ -1401,6 +1532,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { set_proc_address(&SetEvent, "vkSetEvent") set_proc_address(&SetHdrMetadataEXT, "vkSetHdrMetadataEXT") set_proc_address(&SetLocalDimmingAMD, "vkSetLocalDimmingAMD") + set_proc_address(&SetPrivateData, "vkSetPrivateData") set_proc_address(&SetPrivateDataEXT, "vkSetPrivateDataEXT") set_proc_address(&SignalSemaphore, "vkSignalSemaphore") set_proc_address(&SignalSemaphoreKHR, "vkSignalSemaphoreKHR") @@ -1445,6 +1577,8 @@ Device_VTable :: struct { CmdBeginRenderPass: ProcCmdBeginRenderPass, CmdBeginRenderPass2: ProcCmdBeginRenderPass2, CmdBeginRenderPass2KHR: ProcCmdBeginRenderPass2KHR, + CmdBeginRendering: ProcCmdBeginRendering, + CmdBeginRenderingKHR: ProcCmdBeginRenderingKHR, CmdBeginTransformFeedbackEXT: ProcCmdBeginTransformFeedbackEXT, CmdBindDescriptorSets: ProcCmdBindDescriptorSets, CmdBindIndexBuffer: ProcCmdBindIndexBuffer, @@ -1454,8 +1588,10 @@ Device_VTable :: struct { CmdBindShadingRateImageNV: ProcCmdBindShadingRateImageNV, CmdBindTransformFeedbackBuffersEXT: ProcCmdBindTransformFeedbackBuffersEXT, CmdBindVertexBuffers: ProcCmdBindVertexBuffers, + CmdBindVertexBuffers2: ProcCmdBindVertexBuffers2, CmdBindVertexBuffers2EXT: ProcCmdBindVertexBuffers2EXT, CmdBlitImage: ProcCmdBlitImage, + CmdBlitImage2: ProcCmdBlitImage2, CmdBlitImage2KHR: ProcCmdBlitImage2KHR, CmdBuildAccelerationStructureNV: ProcCmdBuildAccelerationStructureNV, CmdBuildAccelerationStructuresIndirectKHR: ProcCmdBuildAccelerationStructuresIndirectKHR, @@ -1467,12 +1603,16 @@ Device_VTable :: struct { CmdCopyAccelerationStructureNV: ProcCmdCopyAccelerationStructureNV, CmdCopyAccelerationStructureToMemoryKHR: ProcCmdCopyAccelerationStructureToMemoryKHR, CmdCopyBuffer: ProcCmdCopyBuffer, + CmdCopyBuffer2: ProcCmdCopyBuffer2, CmdCopyBuffer2KHR: ProcCmdCopyBuffer2KHR, CmdCopyBufferToImage: ProcCmdCopyBufferToImage, + CmdCopyBufferToImage2: ProcCmdCopyBufferToImage2, CmdCopyBufferToImage2KHR: ProcCmdCopyBufferToImage2KHR, CmdCopyImage: ProcCmdCopyImage, + CmdCopyImage2: ProcCmdCopyImage2, CmdCopyImage2KHR: ProcCmdCopyImage2KHR, CmdCopyImageToBuffer: ProcCmdCopyImageToBuffer, + CmdCopyImageToBuffer2: ProcCmdCopyImageToBuffer2, CmdCopyImageToBuffer2KHR: ProcCmdCopyImageToBuffer2KHR, CmdCopyMemoryToAccelerationStructureKHR: ProcCmdCopyMemoryToAccelerationStructureKHR, CmdCopyQueryPoolResults: ProcCmdCopyQueryPoolResults, @@ -1507,6 +1647,8 @@ Device_VTable :: struct { CmdEndRenderPass: ProcCmdEndRenderPass, CmdEndRenderPass2: ProcCmdEndRenderPass2, CmdEndRenderPass2KHR: ProcCmdEndRenderPass2KHR, + CmdEndRendering: ProcCmdEndRendering, + CmdEndRenderingKHR: ProcCmdEndRenderingKHR, CmdEndTransformFeedbackEXT: ProcCmdEndTransformFeedbackEXT, CmdExecuteCommands: ProcCmdExecuteCommands, CmdExecuteGeneratedCommandsNV: ProcCmdExecuteGeneratedCommandsNV, @@ -1516,35 +1658,46 @@ Device_VTable :: struct { CmdNextSubpass2: ProcCmdNextSubpass2, CmdNextSubpass2KHR: ProcCmdNextSubpass2KHR, CmdPipelineBarrier: ProcCmdPipelineBarrier, + CmdPipelineBarrier2: ProcCmdPipelineBarrier2, CmdPipelineBarrier2KHR: ProcCmdPipelineBarrier2KHR, CmdPreprocessGeneratedCommandsNV: ProcCmdPreprocessGeneratedCommandsNV, CmdPushConstants: ProcCmdPushConstants, CmdPushDescriptorSetKHR: ProcCmdPushDescriptorSetKHR, CmdPushDescriptorSetWithTemplateKHR: ProcCmdPushDescriptorSetWithTemplateKHR, CmdResetEvent: ProcCmdResetEvent, + CmdResetEvent2: ProcCmdResetEvent2, CmdResetEvent2KHR: ProcCmdResetEvent2KHR, CmdResetQueryPool: ProcCmdResetQueryPool, CmdResolveImage: ProcCmdResolveImage, + CmdResolveImage2: ProcCmdResolveImage2, CmdResolveImage2KHR: ProcCmdResolveImage2KHR, CmdSetBlendConstants: ProcCmdSetBlendConstants, CmdSetCheckpointNV: ProcCmdSetCheckpointNV, CmdSetCoarseSampleOrderNV: ProcCmdSetCoarseSampleOrderNV, + CmdSetCullMode: ProcCmdSetCullMode, CmdSetCullModeEXT: ProcCmdSetCullModeEXT, CmdSetDepthBias: ProcCmdSetDepthBias, + CmdSetDepthBiasEnable: ProcCmdSetDepthBiasEnable, CmdSetDepthBiasEnableEXT: ProcCmdSetDepthBiasEnableEXT, CmdSetDepthBounds: ProcCmdSetDepthBounds, + CmdSetDepthBoundsTestEnable: ProcCmdSetDepthBoundsTestEnable, CmdSetDepthBoundsTestEnableEXT: ProcCmdSetDepthBoundsTestEnableEXT, + CmdSetDepthCompareOp: ProcCmdSetDepthCompareOp, CmdSetDepthCompareOpEXT: ProcCmdSetDepthCompareOpEXT, + CmdSetDepthTestEnable: ProcCmdSetDepthTestEnable, CmdSetDepthTestEnableEXT: ProcCmdSetDepthTestEnableEXT, + CmdSetDepthWriteEnable: ProcCmdSetDepthWriteEnable, CmdSetDepthWriteEnableEXT: ProcCmdSetDepthWriteEnableEXT, CmdSetDeviceMask: ProcCmdSetDeviceMask, CmdSetDeviceMaskKHR: ProcCmdSetDeviceMaskKHR, CmdSetDiscardRectangleEXT: ProcCmdSetDiscardRectangleEXT, CmdSetEvent: ProcCmdSetEvent, + CmdSetEvent2: ProcCmdSetEvent2, CmdSetEvent2KHR: ProcCmdSetEvent2KHR, CmdSetExclusiveScissorNV: ProcCmdSetExclusiveScissorNV, CmdSetFragmentShadingRateEnumNV: ProcCmdSetFragmentShadingRateEnumNV, CmdSetFragmentShadingRateKHR: ProcCmdSetFragmentShadingRateKHR, + CmdSetFrontFace: ProcCmdSetFrontFace, CmdSetFrontFaceEXT: ProcCmdSetFrontFaceEXT, CmdSetLineStippleEXT: ProcCmdSetLineStippleEXT, CmdSetLineWidth: ProcCmdSetLineWidth, @@ -1553,22 +1706,29 @@ Device_VTable :: struct { CmdSetPerformanceMarkerINTEL: ProcCmdSetPerformanceMarkerINTEL, CmdSetPerformanceOverrideINTEL: ProcCmdSetPerformanceOverrideINTEL, CmdSetPerformanceStreamMarkerINTEL: ProcCmdSetPerformanceStreamMarkerINTEL, + CmdSetPrimitiveRestartEnable: ProcCmdSetPrimitiveRestartEnable, CmdSetPrimitiveRestartEnableEXT: ProcCmdSetPrimitiveRestartEnableEXT, + CmdSetPrimitiveTopology: ProcCmdSetPrimitiveTopology, CmdSetPrimitiveTopologyEXT: ProcCmdSetPrimitiveTopologyEXT, + CmdSetRasterizerDiscardEnable: ProcCmdSetRasterizerDiscardEnable, CmdSetRasterizerDiscardEnableEXT: ProcCmdSetRasterizerDiscardEnableEXT, CmdSetRayTracingPipelineStackSizeKHR: ProcCmdSetRayTracingPipelineStackSizeKHR, CmdSetSampleLocationsEXT: ProcCmdSetSampleLocationsEXT, CmdSetScissor: ProcCmdSetScissor, + CmdSetScissorWithCount: ProcCmdSetScissorWithCount, CmdSetScissorWithCountEXT: ProcCmdSetScissorWithCountEXT, CmdSetStencilCompareMask: ProcCmdSetStencilCompareMask, + CmdSetStencilOp: ProcCmdSetStencilOp, CmdSetStencilOpEXT: ProcCmdSetStencilOpEXT, CmdSetStencilReference: ProcCmdSetStencilReference, + CmdSetStencilTestEnable: ProcCmdSetStencilTestEnable, CmdSetStencilTestEnableEXT: ProcCmdSetStencilTestEnableEXT, CmdSetStencilWriteMask: ProcCmdSetStencilWriteMask, CmdSetVertexInputEXT: ProcCmdSetVertexInputEXT, CmdSetViewport: ProcCmdSetViewport, CmdSetViewportShadingRatePaletteNV: ProcCmdSetViewportShadingRatePaletteNV, CmdSetViewportWScalingNV: ProcCmdSetViewportWScalingNV, + CmdSetViewportWithCount: ProcCmdSetViewportWithCount, CmdSetViewportWithCountEXT: ProcCmdSetViewportWithCountEXT, CmdSubpassShadingHUAWEI: ProcCmdSubpassShadingHUAWEI, CmdTraceRaysIndirectKHR: ProcCmdTraceRaysIndirectKHR, @@ -1576,12 +1736,14 @@ Device_VTable :: struct { CmdTraceRaysNV: ProcCmdTraceRaysNV, CmdUpdateBuffer: ProcCmdUpdateBuffer, CmdWaitEvents: ProcCmdWaitEvents, + CmdWaitEvents2: ProcCmdWaitEvents2, CmdWaitEvents2KHR: ProcCmdWaitEvents2KHR, CmdWriteAccelerationStructuresPropertiesKHR: ProcCmdWriteAccelerationStructuresPropertiesKHR, CmdWriteAccelerationStructuresPropertiesNV: ProcCmdWriteAccelerationStructuresPropertiesNV, CmdWriteBufferMarker2AMD: ProcCmdWriteBufferMarker2AMD, CmdWriteBufferMarkerAMD: ProcCmdWriteBufferMarkerAMD, CmdWriteTimestamp: ProcCmdWriteTimestamp, + CmdWriteTimestamp2: ProcCmdWriteTimestamp2, CmdWriteTimestamp2KHR: ProcCmdWriteTimestamp2KHR, CompileDeferredNV: ProcCompileDeferredNV, CopyAccelerationStructureKHR: ProcCopyAccelerationStructureKHR, @@ -1609,6 +1771,7 @@ Device_VTable :: struct { CreateIndirectCommandsLayoutNV: ProcCreateIndirectCommandsLayoutNV, CreatePipelineCache: ProcCreatePipelineCache, CreatePipelineLayout: ProcCreatePipelineLayout, + CreatePrivateDataSlot: ProcCreatePrivateDataSlot, CreatePrivateDataSlotEXT: ProcCreatePrivateDataSlotEXT, CreateQueryPool: ProcCreateQueryPool, CreateRayTracingPipelinesKHR: ProcCreateRayTracingPipelinesKHR, @@ -1649,6 +1812,7 @@ Device_VTable :: struct { DestroyPipeline: ProcDestroyPipeline, DestroyPipelineCache: ProcDestroyPipelineCache, DestroyPipelineLayout: ProcDestroyPipelineLayout, + DestroyPrivateDataSlot: ProcDestroyPrivateDataSlot, DestroyPrivateDataSlotEXT: ProcDestroyPrivateDataSlotEXT, DestroyQueryPool: ProcDestroyQueryPool, DestroyRenderPass: ProcDestroyRenderPass, @@ -1681,14 +1845,22 @@ Device_VTable :: struct { GetCalibratedTimestampsEXT: ProcGetCalibratedTimestampsEXT, GetDeferredOperationMaxConcurrencyKHR: ProcGetDeferredOperationMaxConcurrencyKHR, GetDeferredOperationResultKHR: ProcGetDeferredOperationResultKHR, + GetDescriptorSetHostMappingVALVE: ProcGetDescriptorSetHostMappingVALVE, + GetDescriptorSetLayoutHostMappingInfoVALVE: ProcGetDescriptorSetLayoutHostMappingInfoVALVE, GetDescriptorSetLayoutSupport: ProcGetDescriptorSetLayoutSupport, GetDescriptorSetLayoutSupportKHR: ProcGetDescriptorSetLayoutSupportKHR, GetDeviceAccelerationStructureCompatibilityKHR: ProcGetDeviceAccelerationStructureCompatibilityKHR, + GetDeviceBufferMemoryRequirements: ProcGetDeviceBufferMemoryRequirements, + GetDeviceBufferMemoryRequirementsKHR: ProcGetDeviceBufferMemoryRequirementsKHR, GetDeviceGroupPeerMemoryFeatures: ProcGetDeviceGroupPeerMemoryFeatures, GetDeviceGroupPeerMemoryFeaturesKHR: ProcGetDeviceGroupPeerMemoryFeaturesKHR, GetDeviceGroupPresentCapabilitiesKHR: ProcGetDeviceGroupPresentCapabilitiesKHR, GetDeviceGroupSurfacePresentModes2EXT: ProcGetDeviceGroupSurfacePresentModes2EXT, GetDeviceGroupSurfacePresentModesKHR: ProcGetDeviceGroupSurfacePresentModesKHR, + GetDeviceImageMemoryRequirements: ProcGetDeviceImageMemoryRequirements, + GetDeviceImageMemoryRequirementsKHR: ProcGetDeviceImageMemoryRequirementsKHR, + GetDeviceImageSparseMemoryRequirements: ProcGetDeviceImageSparseMemoryRequirements, + GetDeviceImageSparseMemoryRequirementsKHR: ProcGetDeviceImageSparseMemoryRequirementsKHR, GetDeviceMemoryCommitment: ProcGetDeviceMemoryCommitment, GetDeviceMemoryOpaqueCaptureAddress: ProcGetDeviceMemoryOpaqueCaptureAddress, GetDeviceMemoryOpaqueCaptureAddressKHR: ProcGetDeviceMemoryOpaqueCaptureAddressKHR, @@ -1724,6 +1896,7 @@ Device_VTable :: struct { GetPipelineExecutableInternalRepresentationsKHR: ProcGetPipelineExecutableInternalRepresentationsKHR, GetPipelineExecutablePropertiesKHR: ProcGetPipelineExecutablePropertiesKHR, GetPipelineExecutableStatisticsKHR: ProcGetPipelineExecutableStatisticsKHR, + GetPrivateData: ProcGetPrivateData, GetPrivateDataEXT: ProcGetPrivateDataEXT, GetQueryPoolResults: ProcGetQueryPoolResults, GetQueueCheckpointData2NV: ProcGetQueueCheckpointData2NV, @@ -1759,6 +1932,7 @@ Device_VTable :: struct { QueuePresentKHR: ProcQueuePresentKHR, QueueSetPerformanceConfigurationINTEL: ProcQueueSetPerformanceConfigurationINTEL, QueueSubmit: ProcQueueSubmit, + QueueSubmit2: ProcQueueSubmit2, QueueSubmit2KHR: ProcQueueSubmit2KHR, QueueWaitIdle: ProcQueueWaitIdle, RegisterDeviceEventEXT: ProcRegisterDeviceEventEXT, @@ -1779,6 +1953,7 @@ Device_VTable :: struct { SetEvent: ProcSetEvent, SetHdrMetadataEXT: ProcSetHdrMetadataEXT, SetLocalDimmingAMD: ProcSetLocalDimmingAMD, + SetPrivateData: ProcSetPrivateData, SetPrivateDataEXT: ProcSetPrivateDataEXT, SignalSemaphore: ProcSignalSemaphore, SignalSemaphoreKHR: ProcSignalSemaphoreKHR, @@ -1821,6 +1996,8 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdBeginRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass") vtable.CmdBeginRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2") vtable.CmdBeginRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2KHR") + vtable.CmdBeginRendering = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRendering") + vtable.CmdBeginRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderingKHR") vtable.CmdBeginTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginTransformFeedbackEXT") vtable.CmdBindDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkCmdBindDescriptorSets") vtable.CmdBindIndexBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdBindIndexBuffer") @@ -1830,8 +2007,10 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdBindShadingRateImageNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindShadingRateImageNV") vtable.CmdBindTransformFeedbackBuffersEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindTransformFeedbackBuffersEXT") vtable.CmdBindVertexBuffers = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers") + vtable.CmdBindVertexBuffers2 = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2") vtable.CmdBindVertexBuffers2EXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2EXT") vtable.CmdBlitImage = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage") + vtable.CmdBlitImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2") vtable.CmdBlitImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2KHR") vtable.CmdBuildAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructureNV") vtable.CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresIndirectKHR") @@ -1843,12 +2022,16 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdCopyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureNV") vtable.CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureToMemoryKHR") vtable.CmdCopyBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer") + vtable.CmdCopyBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2") vtable.CmdCopyBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2KHR") vtable.CmdCopyBufferToImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage") + vtable.CmdCopyBufferToImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2") vtable.CmdCopyBufferToImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2KHR") vtable.CmdCopyImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage") + vtable.CmdCopyImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2") vtable.CmdCopyImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2KHR") vtable.CmdCopyImageToBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer") + vtable.CmdCopyImageToBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2") vtable.CmdCopyImageToBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2KHR") vtable.CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyMemoryToAccelerationStructureKHR") vtable.CmdCopyQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkCmdCopyQueryPoolResults") @@ -1883,6 +2066,8 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdEndRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass") vtable.CmdEndRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2") vtable.CmdEndRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2KHR") + vtable.CmdEndRendering = auto_cast GetDeviceProcAddr(device, "vkCmdEndRendering") + vtable.CmdEndRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderingKHR") vtable.CmdEndTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndTransformFeedbackEXT") vtable.CmdExecuteCommands = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteCommands") vtable.CmdExecuteGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteGeneratedCommandsNV") @@ -1892,35 +2077,46 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdNextSubpass2 = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2") vtable.CmdNextSubpass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2KHR") vtable.CmdPipelineBarrier = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier") + vtable.CmdPipelineBarrier2 = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2") vtable.CmdPipelineBarrier2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2KHR") vtable.CmdPreprocessGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdPreprocessGeneratedCommandsNV") vtable.CmdPushConstants = auto_cast GetDeviceProcAddr(device, "vkCmdPushConstants") vtable.CmdPushDescriptorSetKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR") vtable.CmdPushDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetWithTemplateKHR") vtable.CmdResetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent") + vtable.CmdResetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2") vtable.CmdResetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2KHR") vtable.CmdResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkCmdResetQueryPool") vtable.CmdResolveImage = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage") + vtable.CmdResolveImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2") vtable.CmdResolveImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2KHR") vtable.CmdSetBlendConstants = auto_cast GetDeviceProcAddr(device, "vkCmdSetBlendConstants") vtable.CmdSetCheckpointNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCheckpointNV") vtable.CmdSetCoarseSampleOrderNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCoarseSampleOrderNV") + vtable.CmdSetCullMode = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullMode") vtable.CmdSetCullModeEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullModeEXT") vtable.CmdSetDepthBias = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBias") + vtable.CmdSetDepthBiasEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnable") vtable.CmdSetDepthBiasEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnableEXT") vtable.CmdSetDepthBounds = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBounds") + vtable.CmdSetDepthBoundsTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnable") vtable.CmdSetDepthBoundsTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT") + vtable.CmdSetDepthCompareOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOp") vtable.CmdSetDepthCompareOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT") + vtable.CmdSetDepthTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnable") vtable.CmdSetDepthTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT") + vtable.CmdSetDepthWriteEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnable") vtable.CmdSetDepthWriteEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT") vtable.CmdSetDeviceMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMask") vtable.CmdSetDeviceMaskKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMaskKHR") vtable.CmdSetDiscardRectangleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDiscardRectangleEXT") vtable.CmdSetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent") + vtable.CmdSetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2") vtable.CmdSetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2KHR") vtable.CmdSetExclusiveScissorNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetExclusiveScissorNV") vtable.CmdSetFragmentShadingRateEnumNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateEnumNV") vtable.CmdSetFragmentShadingRateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateKHR") + vtable.CmdSetFrontFace = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFace") vtable.CmdSetFrontFaceEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT") vtable.CmdSetLineStippleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineStippleEXT") vtable.CmdSetLineWidth = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineWidth") @@ -1929,22 +2125,29 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdSetPerformanceMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceMarkerINTEL") vtable.CmdSetPerformanceOverrideINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceOverrideINTEL") vtable.CmdSetPerformanceStreamMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceStreamMarkerINTEL") + vtable.CmdSetPrimitiveRestartEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnable") vtable.CmdSetPrimitiveRestartEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnableEXT") + vtable.CmdSetPrimitiveTopology = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopology") vtable.CmdSetPrimitiveTopologyEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT") + vtable.CmdSetRasterizerDiscardEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnable") vtable.CmdSetRasterizerDiscardEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnableEXT") vtable.CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetRayTracingPipelineStackSizeKHR") vtable.CmdSetSampleLocationsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetSampleLocationsEXT") vtable.CmdSetScissor = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissor") + vtable.CmdSetScissorWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCount") vtable.CmdSetScissorWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT") vtable.CmdSetStencilCompareMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilCompareMask") + vtable.CmdSetStencilOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOp") vtable.CmdSetStencilOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOpEXT") vtable.CmdSetStencilReference = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilReference") + vtable.CmdSetStencilTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnable") vtable.CmdSetStencilTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT") vtable.CmdSetStencilWriteMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilWriteMask") vtable.CmdSetVertexInputEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetVertexInputEXT") vtable.CmdSetViewport = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewport") vtable.CmdSetViewportShadingRatePaletteNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportShadingRatePaletteNV") vtable.CmdSetViewportWScalingNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWScalingNV") + vtable.CmdSetViewportWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCount") vtable.CmdSetViewportWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT") vtable.CmdSubpassShadingHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdSubpassShadingHUAWEI") vtable.CmdTraceRaysIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysIndirectKHR") @@ -1952,12 +2155,14 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CmdTraceRaysNV = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysNV") vtable.CmdUpdateBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdUpdateBuffer") vtable.CmdWaitEvents = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents") + vtable.CmdWaitEvents2 = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2") vtable.CmdWaitEvents2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2KHR") vtable.CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesKHR") vtable.CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesNV") vtable.CmdWriteBufferMarker2AMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarker2AMD") vtable.CmdWriteBufferMarkerAMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarkerAMD") vtable.CmdWriteTimestamp = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp") + vtable.CmdWriteTimestamp2 = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2") vtable.CmdWriteTimestamp2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2KHR") vtable.CompileDeferredNV = auto_cast GetDeviceProcAddr(device, "vkCompileDeferredNV") vtable.CopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureKHR") @@ -1985,6 +2190,7 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.CreateIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkCreateIndirectCommandsLayoutNV") vtable.CreatePipelineCache = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineCache") vtable.CreatePipelineLayout = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineLayout") + vtable.CreatePrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlot") vtable.CreatePrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlotEXT") vtable.CreateQueryPool = auto_cast GetDeviceProcAddr(device, "vkCreateQueryPool") vtable.CreateRayTracingPipelinesKHR = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR") @@ -2025,6 +2231,7 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.DestroyPipeline = auto_cast GetDeviceProcAddr(device, "vkDestroyPipeline") vtable.DestroyPipelineCache = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineCache") vtable.DestroyPipelineLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineLayout") + vtable.DestroyPrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlot") vtable.DestroyPrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlotEXT") vtable.DestroyQueryPool = auto_cast GetDeviceProcAddr(device, "vkDestroyQueryPool") vtable.DestroyRenderPass = auto_cast GetDeviceProcAddr(device, "vkDestroyRenderPass") @@ -2057,14 +2264,22 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.GetCalibratedTimestampsEXT = auto_cast GetDeviceProcAddr(device, "vkGetCalibratedTimestampsEXT") vtable.GetDeferredOperationMaxConcurrencyKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationMaxConcurrencyKHR") vtable.GetDeferredOperationResultKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationResultKHR") + vtable.GetDescriptorSetHostMappingVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetHostMappingVALVE") + vtable.GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") vtable.GetDescriptorSetLayoutSupport = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupport") vtable.GetDescriptorSetLayoutSupportKHR = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupportKHR") vtable.GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceAccelerationStructureCompatibilityKHR") + vtable.GetDeviceBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirements") + vtable.GetDeviceBufferMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirementsKHR") vtable.GetDeviceGroupPeerMemoryFeatures = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeatures") vtable.GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR") vtable.GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPresentCapabilitiesKHR") vtable.GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModes2EXT") vtable.GetDeviceGroupSurfacePresentModesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModesKHR") + vtable.GetDeviceImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirements") + vtable.GetDeviceImageMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirementsKHR") + vtable.GetDeviceImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirements") + vtable.GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirementsKHR") vtable.GetDeviceMemoryCommitment = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryCommitment") vtable.GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddress") vtable.GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") @@ -2100,6 +2315,7 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableInternalRepresentationsKHR") vtable.GetPipelineExecutablePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutablePropertiesKHR") vtable.GetPipelineExecutableStatisticsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableStatisticsKHR") + vtable.GetPrivateData = auto_cast GetDeviceProcAddr(device, "vkGetPrivateData") vtable.GetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetPrivateDataEXT") vtable.GetQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkGetQueryPoolResults") vtable.GetQueueCheckpointData2NV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointData2NV") @@ -2135,6 +2351,7 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.QueuePresentKHR = auto_cast GetDeviceProcAddr(device, "vkQueuePresentKHR") vtable.QueueSetPerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkQueueSetPerformanceConfigurationINTEL") vtable.QueueSubmit = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit") + vtable.QueueSubmit2 = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2") vtable.QueueSubmit2KHR = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2KHR") vtable.QueueWaitIdle = auto_cast GetDeviceProcAddr(device, "vkQueueWaitIdle") vtable.RegisterDeviceEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDeviceEventEXT") @@ -2155,6 +2372,7 @@ load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable vtable.SetEvent = auto_cast GetDeviceProcAddr(device, "vkSetEvent") vtable.SetHdrMetadataEXT = auto_cast GetDeviceProcAddr(device, "vkSetHdrMetadataEXT") vtable.SetLocalDimmingAMD = auto_cast GetDeviceProcAddr(device, "vkSetLocalDimmingAMD") + vtable.SetPrivateData = auto_cast GetDeviceProcAddr(device, "vkSetPrivateData") vtable.SetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkSetPrivateDataEXT") vtable.SignalSemaphore = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphore") vtable.SignalSemaphoreKHR = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphoreKHR") @@ -2197,6 +2415,8 @@ load_proc_addresses_device :: proc(device: Device) { CmdBeginRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass") CmdBeginRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2") CmdBeginRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2KHR") + CmdBeginRendering = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRendering") + CmdBeginRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderingKHR") CmdBeginTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginTransformFeedbackEXT") CmdBindDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkCmdBindDescriptorSets") CmdBindIndexBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdBindIndexBuffer") @@ -2206,8 +2426,10 @@ load_proc_addresses_device :: proc(device: Device) { CmdBindShadingRateImageNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindShadingRateImageNV") CmdBindTransformFeedbackBuffersEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindTransformFeedbackBuffersEXT") CmdBindVertexBuffers = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers") + CmdBindVertexBuffers2 = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2") CmdBindVertexBuffers2EXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2EXT") CmdBlitImage = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage") + CmdBlitImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2") CmdBlitImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2KHR") CmdBuildAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructureNV") CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresIndirectKHR") @@ -2219,12 +2441,16 @@ load_proc_addresses_device :: proc(device: Device) { CmdCopyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureNV") CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureToMemoryKHR") CmdCopyBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer") + CmdCopyBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2") CmdCopyBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2KHR") CmdCopyBufferToImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage") + CmdCopyBufferToImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2") CmdCopyBufferToImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2KHR") CmdCopyImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage") + CmdCopyImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2") CmdCopyImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2KHR") CmdCopyImageToBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer") + CmdCopyImageToBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2") CmdCopyImageToBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2KHR") CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyMemoryToAccelerationStructureKHR") CmdCopyQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkCmdCopyQueryPoolResults") @@ -2259,6 +2485,8 @@ load_proc_addresses_device :: proc(device: Device) { CmdEndRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass") CmdEndRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2") CmdEndRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2KHR") + CmdEndRendering = auto_cast GetDeviceProcAddr(device, "vkCmdEndRendering") + CmdEndRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderingKHR") CmdEndTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndTransformFeedbackEXT") CmdExecuteCommands = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteCommands") CmdExecuteGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteGeneratedCommandsNV") @@ -2268,35 +2496,46 @@ load_proc_addresses_device :: proc(device: Device) { CmdNextSubpass2 = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2") CmdNextSubpass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2KHR") CmdPipelineBarrier = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier") + CmdPipelineBarrier2 = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2") CmdPipelineBarrier2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2KHR") CmdPreprocessGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdPreprocessGeneratedCommandsNV") CmdPushConstants = auto_cast GetDeviceProcAddr(device, "vkCmdPushConstants") CmdPushDescriptorSetKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR") CmdPushDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetWithTemplateKHR") CmdResetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent") + CmdResetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2") CmdResetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2KHR") CmdResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkCmdResetQueryPool") CmdResolveImage = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage") + CmdResolveImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2") CmdResolveImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2KHR") CmdSetBlendConstants = auto_cast GetDeviceProcAddr(device, "vkCmdSetBlendConstants") CmdSetCheckpointNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCheckpointNV") CmdSetCoarseSampleOrderNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCoarseSampleOrderNV") + CmdSetCullMode = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullMode") CmdSetCullModeEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullModeEXT") CmdSetDepthBias = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBias") + CmdSetDepthBiasEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnable") CmdSetDepthBiasEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnableEXT") CmdSetDepthBounds = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBounds") + CmdSetDepthBoundsTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnable") CmdSetDepthBoundsTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT") + CmdSetDepthCompareOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOp") CmdSetDepthCompareOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT") + CmdSetDepthTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnable") CmdSetDepthTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT") + CmdSetDepthWriteEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnable") CmdSetDepthWriteEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT") CmdSetDeviceMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMask") CmdSetDeviceMaskKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMaskKHR") CmdSetDiscardRectangleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDiscardRectangleEXT") CmdSetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent") + CmdSetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2") CmdSetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2KHR") CmdSetExclusiveScissorNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetExclusiveScissorNV") CmdSetFragmentShadingRateEnumNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateEnumNV") CmdSetFragmentShadingRateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateKHR") + CmdSetFrontFace = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFace") CmdSetFrontFaceEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT") CmdSetLineStippleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineStippleEXT") CmdSetLineWidth = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineWidth") @@ -2305,22 +2544,29 @@ load_proc_addresses_device :: proc(device: Device) { CmdSetPerformanceMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceMarkerINTEL") CmdSetPerformanceOverrideINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceOverrideINTEL") CmdSetPerformanceStreamMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceStreamMarkerINTEL") + CmdSetPrimitiveRestartEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnable") CmdSetPrimitiveRestartEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnableEXT") + CmdSetPrimitiveTopology = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopology") CmdSetPrimitiveTopologyEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT") + CmdSetRasterizerDiscardEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnable") CmdSetRasterizerDiscardEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnableEXT") CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetRayTracingPipelineStackSizeKHR") CmdSetSampleLocationsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetSampleLocationsEXT") CmdSetScissor = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissor") + CmdSetScissorWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCount") CmdSetScissorWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT") CmdSetStencilCompareMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilCompareMask") + CmdSetStencilOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOp") CmdSetStencilOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOpEXT") CmdSetStencilReference = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilReference") + CmdSetStencilTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnable") CmdSetStencilTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT") CmdSetStencilWriteMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilWriteMask") CmdSetVertexInputEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetVertexInputEXT") CmdSetViewport = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewport") CmdSetViewportShadingRatePaletteNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportShadingRatePaletteNV") CmdSetViewportWScalingNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWScalingNV") + CmdSetViewportWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCount") CmdSetViewportWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT") CmdSubpassShadingHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdSubpassShadingHUAWEI") CmdTraceRaysIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysIndirectKHR") @@ -2328,12 +2574,14 @@ load_proc_addresses_device :: proc(device: Device) { CmdTraceRaysNV = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysNV") CmdUpdateBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdUpdateBuffer") CmdWaitEvents = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents") + CmdWaitEvents2 = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2") CmdWaitEvents2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2KHR") CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesKHR") CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesNV") CmdWriteBufferMarker2AMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarker2AMD") CmdWriteBufferMarkerAMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarkerAMD") CmdWriteTimestamp = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp") + CmdWriteTimestamp2 = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2") CmdWriteTimestamp2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2KHR") CompileDeferredNV = auto_cast GetDeviceProcAddr(device, "vkCompileDeferredNV") CopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureKHR") @@ -2361,6 +2609,7 @@ load_proc_addresses_device :: proc(device: Device) { CreateIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkCreateIndirectCommandsLayoutNV") CreatePipelineCache = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineCache") CreatePipelineLayout = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineLayout") + CreatePrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlot") CreatePrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlotEXT") CreateQueryPool = auto_cast GetDeviceProcAddr(device, "vkCreateQueryPool") CreateRayTracingPipelinesKHR = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR") @@ -2401,6 +2650,7 @@ load_proc_addresses_device :: proc(device: Device) { DestroyPipeline = auto_cast GetDeviceProcAddr(device, "vkDestroyPipeline") DestroyPipelineCache = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineCache") DestroyPipelineLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineLayout") + DestroyPrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlot") DestroyPrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlotEXT") DestroyQueryPool = auto_cast GetDeviceProcAddr(device, "vkDestroyQueryPool") DestroyRenderPass = auto_cast GetDeviceProcAddr(device, "vkDestroyRenderPass") @@ -2433,14 +2683,22 @@ load_proc_addresses_device :: proc(device: Device) { GetCalibratedTimestampsEXT = auto_cast GetDeviceProcAddr(device, "vkGetCalibratedTimestampsEXT") GetDeferredOperationMaxConcurrencyKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationMaxConcurrencyKHR") GetDeferredOperationResultKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationResultKHR") + GetDescriptorSetHostMappingVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetHostMappingVALVE") + GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") GetDescriptorSetLayoutSupport = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupport") GetDescriptorSetLayoutSupportKHR = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupportKHR") GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceAccelerationStructureCompatibilityKHR") + GetDeviceBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirements") + GetDeviceBufferMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirementsKHR") GetDeviceGroupPeerMemoryFeatures = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeatures") GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR") GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPresentCapabilitiesKHR") GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModes2EXT") GetDeviceGroupSurfacePresentModesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModesKHR") + GetDeviceImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirements") + GetDeviceImageMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirementsKHR") + GetDeviceImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirements") + GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirementsKHR") GetDeviceMemoryCommitment = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryCommitment") GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddress") GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") @@ -2476,6 +2734,7 @@ load_proc_addresses_device :: proc(device: Device) { GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableInternalRepresentationsKHR") GetPipelineExecutablePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutablePropertiesKHR") GetPipelineExecutableStatisticsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableStatisticsKHR") + GetPrivateData = auto_cast GetDeviceProcAddr(device, "vkGetPrivateData") GetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetPrivateDataEXT") GetQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkGetQueryPoolResults") GetQueueCheckpointData2NV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointData2NV") @@ -2511,6 +2770,7 @@ load_proc_addresses_device :: proc(device: Device) { QueuePresentKHR = auto_cast GetDeviceProcAddr(device, "vkQueuePresentKHR") QueueSetPerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkQueueSetPerformanceConfigurationINTEL") QueueSubmit = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit") + QueueSubmit2 = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2") QueueSubmit2KHR = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2KHR") QueueWaitIdle = auto_cast GetDeviceProcAddr(device, "vkQueueWaitIdle") RegisterDeviceEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDeviceEventEXT") @@ -2531,6 +2791,7 @@ load_proc_addresses_device :: proc(device: Device) { SetEvent = auto_cast GetDeviceProcAddr(device, "vkSetEvent") SetHdrMetadataEXT = auto_cast GetDeviceProcAddr(device, "vkSetHdrMetadataEXT") SetLocalDimmingAMD = auto_cast GetDeviceProcAddr(device, "vkSetLocalDimmingAMD") + SetPrivateData = auto_cast GetDeviceProcAddr(device, "vkSetPrivateData") SetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkSetPrivateDataEXT") SignalSemaphore = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphore") SignalSemaphoreKHR = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphoreKHR") @@ -2626,6 +2887,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { GetPhysicalDeviceSurfacePresentModes2EXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT") GetPhysicalDeviceSurfacePresentModesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR") GetPhysicalDeviceSurfaceSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceSupportKHR") + GetPhysicalDeviceToolProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolProperties") GetPhysicalDeviceToolPropertiesEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolPropertiesEXT") GetPhysicalDeviceWin32PresentationSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR") GetWinrtDisplayNV = auto_cast GetInstanceProcAddr(instance, "vkGetWinrtDisplayNV") @@ -2657,6 +2919,8 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdBeginRenderPass = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass") CmdBeginRenderPass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass2") CmdBeginRenderPass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass2KHR") + CmdBeginRendering = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRendering") + CmdBeginRenderingKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderingKHR") CmdBeginTransformFeedbackEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginTransformFeedbackEXT") CmdBindDescriptorSets = auto_cast GetInstanceProcAddr(instance, "vkCmdBindDescriptorSets") CmdBindIndexBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdBindIndexBuffer") @@ -2666,8 +2930,10 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdBindShadingRateImageNV = auto_cast GetInstanceProcAddr(instance, "vkCmdBindShadingRateImageNV") CmdBindTransformFeedbackBuffersEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBindTransformFeedbackBuffersEXT") CmdBindVertexBuffers = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers") + CmdBindVertexBuffers2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers2") CmdBindVertexBuffers2EXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers2EXT") CmdBlitImage = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage") + CmdBlitImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage2") CmdBlitImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage2KHR") CmdBuildAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructureNV") CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructuresIndirectKHR") @@ -2679,12 +2945,16 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdCopyAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyAccelerationStructureNV") CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyAccelerationStructureToMemoryKHR") CmdCopyBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer") + CmdCopyBuffer2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer2") CmdCopyBuffer2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer2KHR") CmdCopyBufferToImage = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage") + CmdCopyBufferToImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage2") CmdCopyBufferToImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage2KHR") CmdCopyImage = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage") + CmdCopyImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage2") CmdCopyImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage2KHR") CmdCopyImageToBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer") + CmdCopyImageToBuffer2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer2") CmdCopyImageToBuffer2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer2KHR") CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyMemoryToAccelerationStructureKHR") CmdCopyQueryPoolResults = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyQueryPoolResults") @@ -2719,6 +2989,8 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdEndRenderPass = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass") CmdEndRenderPass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass2") CmdEndRenderPass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass2KHR") + CmdEndRendering = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRendering") + CmdEndRenderingKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderingKHR") CmdEndTransformFeedbackEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdEndTransformFeedbackEXT") CmdExecuteCommands = auto_cast GetInstanceProcAddr(instance, "vkCmdExecuteCommands") CmdExecuteGeneratedCommandsNV = auto_cast GetInstanceProcAddr(instance, "vkCmdExecuteGeneratedCommandsNV") @@ -2728,35 +3000,46 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdNextSubpass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdNextSubpass2") CmdNextSubpass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdNextSubpass2KHR") CmdPipelineBarrier = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier") + CmdPipelineBarrier2 = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier2") CmdPipelineBarrier2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier2KHR") CmdPreprocessGeneratedCommandsNV = auto_cast GetInstanceProcAddr(instance, "vkCmdPreprocessGeneratedCommandsNV") CmdPushConstants = auto_cast GetInstanceProcAddr(instance, "vkCmdPushConstants") CmdPushDescriptorSetKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPushDescriptorSetKHR") CmdPushDescriptorSetWithTemplateKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPushDescriptorSetWithTemplateKHR") CmdResetEvent = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent") + CmdResetEvent2 = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent2") CmdResetEvent2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent2KHR") CmdResetQueryPool = auto_cast GetInstanceProcAddr(instance, "vkCmdResetQueryPool") CmdResolveImage = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage") + CmdResolveImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage2") CmdResolveImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage2KHR") CmdSetBlendConstants = auto_cast GetInstanceProcAddr(instance, "vkCmdSetBlendConstants") CmdSetCheckpointNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCheckpointNV") CmdSetCoarseSampleOrderNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCoarseSampleOrderNV") + CmdSetCullMode = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCullMode") CmdSetCullModeEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCullModeEXT") CmdSetDepthBias = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBias") + CmdSetDepthBiasEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBiasEnable") CmdSetDepthBiasEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBiasEnableEXT") CmdSetDepthBounds = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBounds") + CmdSetDepthBoundsTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBoundsTestEnable") CmdSetDepthBoundsTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBoundsTestEnableEXT") + CmdSetDepthCompareOp = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthCompareOp") CmdSetDepthCompareOpEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthCompareOpEXT") + CmdSetDepthTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthTestEnable") CmdSetDepthTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthTestEnableEXT") + CmdSetDepthWriteEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthWriteEnable") CmdSetDepthWriteEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthWriteEnableEXT") CmdSetDeviceMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDeviceMask") CmdSetDeviceMaskKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDeviceMaskKHR") CmdSetDiscardRectangleEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDiscardRectangleEXT") CmdSetEvent = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent") + CmdSetEvent2 = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent2") CmdSetEvent2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent2KHR") CmdSetExclusiveScissorNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetExclusiveScissorNV") CmdSetFragmentShadingRateEnumNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFragmentShadingRateEnumNV") CmdSetFragmentShadingRateKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFragmentShadingRateKHR") + CmdSetFrontFace = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFrontFace") CmdSetFrontFaceEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFrontFaceEXT") CmdSetLineStippleEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetLineStippleEXT") CmdSetLineWidth = auto_cast GetInstanceProcAddr(instance, "vkCmdSetLineWidth") @@ -2765,22 +3048,29 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdSetPerformanceMarkerINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceMarkerINTEL") CmdSetPerformanceOverrideINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceOverrideINTEL") CmdSetPerformanceStreamMarkerINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceStreamMarkerINTEL") + CmdSetPrimitiveRestartEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveRestartEnable") CmdSetPrimitiveRestartEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveRestartEnableEXT") + CmdSetPrimitiveTopology = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveTopology") CmdSetPrimitiveTopologyEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveTopologyEXT") + CmdSetRasterizerDiscardEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRasterizerDiscardEnable") CmdSetRasterizerDiscardEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRasterizerDiscardEnableEXT") CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRayTracingPipelineStackSizeKHR") CmdSetSampleLocationsEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetSampleLocationsEXT") CmdSetScissor = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissor") + CmdSetScissorWithCount = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissorWithCount") CmdSetScissorWithCountEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissorWithCountEXT") CmdSetStencilCompareMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilCompareMask") + CmdSetStencilOp = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilOp") CmdSetStencilOpEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilOpEXT") CmdSetStencilReference = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilReference") + CmdSetStencilTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilTestEnable") CmdSetStencilTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilTestEnableEXT") CmdSetStencilWriteMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilWriteMask") CmdSetVertexInputEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetVertexInputEXT") CmdSetViewport = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewport") CmdSetViewportShadingRatePaletteNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportShadingRatePaletteNV") CmdSetViewportWScalingNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWScalingNV") + CmdSetViewportWithCount = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWithCount") CmdSetViewportWithCountEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWithCountEXT") CmdSubpassShadingHUAWEI = auto_cast GetInstanceProcAddr(instance, "vkCmdSubpassShadingHUAWEI") CmdTraceRaysIndirectKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdTraceRaysIndirectKHR") @@ -2788,12 +3078,14 @@ load_proc_addresses_instance :: proc(instance: Instance) { CmdTraceRaysNV = auto_cast GetInstanceProcAddr(instance, "vkCmdTraceRaysNV") CmdUpdateBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdUpdateBuffer") CmdWaitEvents = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents") + CmdWaitEvents2 = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents2") CmdWaitEvents2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents2KHR") CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteAccelerationStructuresPropertiesKHR") CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteAccelerationStructuresPropertiesNV") CmdWriteBufferMarker2AMD = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteBufferMarker2AMD") CmdWriteBufferMarkerAMD = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteBufferMarkerAMD") CmdWriteTimestamp = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp") + CmdWriteTimestamp2 = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp2") CmdWriteTimestamp2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp2KHR") CompileDeferredNV = auto_cast GetInstanceProcAddr(instance, "vkCompileDeferredNV") CopyAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCopyAccelerationStructureKHR") @@ -2821,6 +3113,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { CreateIndirectCommandsLayoutNV = auto_cast GetInstanceProcAddr(instance, "vkCreateIndirectCommandsLayoutNV") CreatePipelineCache = auto_cast GetInstanceProcAddr(instance, "vkCreatePipelineCache") CreatePipelineLayout = auto_cast GetInstanceProcAddr(instance, "vkCreatePipelineLayout") + CreatePrivateDataSlot = auto_cast GetInstanceProcAddr(instance, "vkCreatePrivateDataSlot") CreatePrivateDataSlotEXT = auto_cast GetInstanceProcAddr(instance, "vkCreatePrivateDataSlotEXT") CreateQueryPool = auto_cast GetInstanceProcAddr(instance, "vkCreateQueryPool") CreateRayTracingPipelinesKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesKHR") @@ -2861,6 +3154,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { DestroyPipeline = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipeline") DestroyPipelineCache = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipelineCache") DestroyPipelineLayout = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipelineLayout") + DestroyPrivateDataSlot = auto_cast GetInstanceProcAddr(instance, "vkDestroyPrivateDataSlot") DestroyPrivateDataSlotEXT = auto_cast GetInstanceProcAddr(instance, "vkDestroyPrivateDataSlotEXT") DestroyQueryPool = auto_cast GetInstanceProcAddr(instance, "vkDestroyQueryPool") DestroyRenderPass = auto_cast GetInstanceProcAddr(instance, "vkDestroyRenderPass") @@ -2893,14 +3187,22 @@ load_proc_addresses_instance :: proc(instance: Instance) { GetCalibratedTimestampsEXT = auto_cast GetInstanceProcAddr(instance, "vkGetCalibratedTimestampsEXT") GetDeferredOperationMaxConcurrencyKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeferredOperationMaxConcurrencyKHR") GetDeferredOperationResultKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeferredOperationResultKHR") + GetDescriptorSetHostMappingVALVE = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetHostMappingVALVE") + GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") GetDescriptorSetLayoutSupport = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutSupport") GetDescriptorSetLayoutSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutSupportKHR") GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceAccelerationStructureCompatibilityKHR") + GetDeviceBufferMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceBufferMemoryRequirements") + GetDeviceBufferMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceBufferMemoryRequirementsKHR") GetDeviceGroupPeerMemoryFeatures = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPeerMemoryFeatures") GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPeerMemoryFeaturesKHR") GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPresentCapabilitiesKHR") GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupSurfacePresentModes2EXT") GetDeviceGroupSurfacePresentModesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupSurfacePresentModesKHR") + GetDeviceImageMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageMemoryRequirements") + GetDeviceImageMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageMemoryRequirementsKHR") + GetDeviceImageSparseMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageSparseMemoryRequirements") + GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageSparseMemoryRequirementsKHR") GetDeviceMemoryCommitment = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryCommitment") GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryOpaqueCaptureAddress") GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") @@ -2936,6 +3238,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutableInternalRepresentationsKHR") GetPipelineExecutablePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutablePropertiesKHR") GetPipelineExecutableStatisticsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutableStatisticsKHR") + GetPrivateData = auto_cast GetInstanceProcAddr(instance, "vkGetPrivateData") GetPrivateDataEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPrivateDataEXT") GetQueryPoolResults = auto_cast GetInstanceProcAddr(instance, "vkGetQueryPoolResults") GetQueueCheckpointData2NV = auto_cast GetInstanceProcAddr(instance, "vkGetQueueCheckpointData2NV") @@ -2971,6 +3274,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { QueuePresentKHR = auto_cast GetInstanceProcAddr(instance, "vkQueuePresentKHR") QueueSetPerformanceConfigurationINTEL = auto_cast GetInstanceProcAddr(instance, "vkQueueSetPerformanceConfigurationINTEL") QueueSubmit = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit") + QueueSubmit2 = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit2") QueueSubmit2KHR = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit2KHR") QueueWaitIdle = auto_cast GetInstanceProcAddr(instance, "vkQueueWaitIdle") RegisterDeviceEventEXT = auto_cast GetInstanceProcAddr(instance, "vkRegisterDeviceEventEXT") @@ -2991,6 +3295,7 @@ load_proc_addresses_instance :: proc(instance: Instance) { SetEvent = auto_cast GetInstanceProcAddr(instance, "vkSetEvent") SetHdrMetadataEXT = auto_cast GetInstanceProcAddr(instance, "vkSetHdrMetadataEXT") SetLocalDimmingAMD = auto_cast GetInstanceProcAddr(instance, "vkSetLocalDimmingAMD") + SetPrivateData = auto_cast GetInstanceProcAddr(instance, "vkSetPrivateData") SetPrivateDataEXT = auto_cast GetInstanceProcAddr(instance, "vkSetPrivateDataEXT") SignalSemaphore = auto_cast GetInstanceProcAddr(instance, "vkSignalSemaphore") SignalSemaphoreKHR = auto_cast GetInstanceProcAddr(instance, "vkSignalSemaphoreKHR") diff --git a/vendor/vulkan/structs.odin b/vendor/vulkan/structs.odin index 3c655a4fa..3bc3e1935 100644 --- a/vendor/vulkan/structs.odin +++ b/vendor/vulkan/structs.odin @@ -2170,6 +2170,537 @@ DeviceMemoryOpaqueCaptureAddressInfo :: struct { memory: DeviceMemory, } +PhysicalDeviceVulkan13Features :: struct { + sType: StructureType, + pNext: rawptr, + robustImageAccess: b32, + inlineUniformBlock: b32, + descriptorBindingInlineUniformBlockUpdateAfterBind: b32, + pipelineCreationCacheControl: b32, + privateData: b32, + shaderDemoteToHelperInvocation: b32, + shaderTerminateInvocation: b32, + subgroupSizeControl: b32, + computeFullSubgroups: b32, + synchronization2: b32, + textureCompressionASTC_HDR: b32, + shaderZeroInitializeWorkgroupMemory: b32, + dynamicRendering: b32, + shaderIntegerDotProduct: b32, + maintenance4: b32, +} + +PhysicalDeviceVulkan13Properties :: struct { + sType: StructureType, + pNext: rawptr, + minSubgroupSize: u32, + maxSubgroupSize: u32, + maxComputeWorkgroupSubgroups: u32, + requiredSubgroupSizeStages: ShaderStageFlags, + maxInlineUniformBlockSize: u32, + maxPerStageDescriptorInlineUniformBlocks: u32, + maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, + maxDescriptorSetInlineUniformBlocks: u32, + maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, + maxInlineUniformTotalSize: u32, + integerDotProduct8BitUnsignedAccelerated: b32, + integerDotProduct8BitSignedAccelerated: b32, + integerDotProduct8BitMixedSignednessAccelerated: b32, + integerDotProduct4x8BitPackedUnsignedAccelerated: b32, + integerDotProduct4x8BitPackedSignedAccelerated: b32, + integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProduct16BitUnsignedAccelerated: b32, + integerDotProduct16BitSignedAccelerated: b32, + integerDotProduct16BitMixedSignednessAccelerated: b32, + integerDotProduct32BitUnsignedAccelerated: b32, + integerDotProduct32BitSignedAccelerated: b32, + integerDotProduct32BitMixedSignednessAccelerated: b32, + integerDotProduct64BitUnsignedAccelerated: b32, + integerDotProduct64BitSignedAccelerated: b32, + integerDotProduct64BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, + storageTexelBufferOffsetAlignmentBytes: DeviceSize, + storageTexelBufferOffsetSingleTexelAlignment: b32, + uniformTexelBufferOffsetAlignmentBytes: DeviceSize, + uniformTexelBufferOffsetSingleTexelAlignment: b32, + maxBufferSize: DeviceSize, +} + +PipelineCreationFeedback :: struct { + flags: PipelineCreationFeedbackFlags, + duration: u64, +} + +PipelineCreationFeedbackCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + pPipelineCreationFeedback: ^PipelineCreationFeedback, + pipelineStageCreationFeedbackCount: u32, + pPipelineStageCreationFeedbacks: [^]PipelineCreationFeedback, +} + +PhysicalDeviceShaderTerminateInvocationFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderTerminateInvocation: b32, +} + +PhysicalDeviceToolProperties :: struct { + sType: StructureType, + pNext: rawptr, + name: [MAX_EXTENSION_NAME_SIZE]byte, + version: [MAX_EXTENSION_NAME_SIZE]byte, + purposes: ToolPurposeFlags, + description: [MAX_DESCRIPTION_SIZE]byte, + layer: [MAX_EXTENSION_NAME_SIZE]byte, +} + +PhysicalDeviceShaderDemoteToHelperInvocationFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderDemoteToHelperInvocation: b32, +} + +PhysicalDevicePrivateDataFeatures :: struct { + sType: StructureType, + pNext: rawptr, + privateData: b32, +} + +DevicePrivateDataCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + privateDataSlotRequestCount: u32, +} + +PrivateDataSlotCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: PrivateDataSlotCreateFlags, +} + +PhysicalDevicePipelineCreationCacheControlFeatures :: struct { + sType: StructureType, + pNext: rawptr, + pipelineCreationCacheControl: b32, +} + +MemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, +} + +BufferMemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, + srcQueueFamilyIndex: u32, + dstQueueFamilyIndex: u32, + buffer: Buffer, + offset: DeviceSize, + size: DeviceSize, +} + +ImageMemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, + oldLayout: ImageLayout, + newLayout: ImageLayout, + srcQueueFamilyIndex: u32, + dstQueueFamilyIndex: u32, + image: Image, + subresourceRange: ImageSubresourceRange, +} + +DependencyInfo :: struct { + sType: StructureType, + pNext: rawptr, + dependencyFlags: DependencyFlags, + memoryBarrierCount: u32, + pMemoryBarriers: [^]MemoryBarrier2, + bufferMemoryBarrierCount: u32, + pBufferMemoryBarriers: [^]BufferMemoryBarrier2, + imageMemoryBarrierCount: u32, + pImageMemoryBarriers: [^]ImageMemoryBarrier2, +} + +SemaphoreSubmitInfo :: struct { + sType: StructureType, + pNext: rawptr, + semaphore: Semaphore, + value: u64, + stageMask: PipelineStageFlags2, + deviceIndex: u32, +} + +CommandBufferSubmitInfo :: struct { + sType: StructureType, + pNext: rawptr, + commandBuffer: CommandBuffer, + deviceMask: u32, +} + +SubmitInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + flags: SubmitFlags, + waitSemaphoreInfoCount: u32, + pWaitSemaphoreInfos: [^]SemaphoreSubmitInfo, + commandBufferInfoCount: u32, + pCommandBufferInfos: [^]CommandBufferSubmitInfo, + signalSemaphoreInfoCount: u32, + pSignalSemaphoreInfos: [^]SemaphoreSubmitInfo, +} + +PhysicalDeviceSynchronization2Features :: struct { + sType: StructureType, + pNext: rawptr, + synchronization2: b32, +} + +PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderZeroInitializeWorkgroupMemory: b32, +} + +PhysicalDeviceImageRobustnessFeatures :: struct { + sType: StructureType, + pNext: rawptr, + robustImageAccess: b32, +} + +BufferCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + srcOffset: DeviceSize, + dstOffset: DeviceSize, + size: DeviceSize, +} + +CopyBufferInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcBuffer: Buffer, + dstBuffer: Buffer, + regionCount: u32, + pRegions: [^]BufferCopy2, +} + +ImageCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffset: Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffset: Offset3D, + extent: Extent3D, +} + +CopyImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageCopy2, +} + +BufferImageCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + bufferOffset: DeviceSize, + bufferRowLength: u32, + bufferImageHeight: u32, + imageSubresource: ImageSubresourceLayers, + imageOffset: Offset3D, + imageExtent: Extent3D, +} + +CopyBufferToImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcBuffer: Buffer, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]BufferImageCopy2, +} + +CopyImageToBufferInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstBuffer: Buffer, + regionCount: u32, + pRegions: [^]BufferImageCopy2, +} + +ImageBlit2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffsets: [2]Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffsets: [2]Offset3D, +} + +BlitImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageBlit2, + filter: Filter, +} + +ImageResolve2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffset: Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffset: Offset3D, + extent: Extent3D, +} + +ResolveImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageResolve2, +} + +PhysicalDeviceSubgroupSizeControlFeatures :: struct { + sType: StructureType, + pNext: rawptr, + subgroupSizeControl: b32, + computeFullSubgroups: b32, +} + +PhysicalDeviceSubgroupSizeControlProperties :: struct { + sType: StructureType, + pNext: rawptr, + minSubgroupSize: u32, + maxSubgroupSize: u32, + maxComputeWorkgroupSubgroups: u32, + requiredSubgroupSizeStages: ShaderStageFlags, +} + +PipelineShaderStageRequiredSubgroupSizeCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + requiredSubgroupSize: u32, +} + +PhysicalDeviceInlineUniformBlockFeatures :: struct { + sType: StructureType, + pNext: rawptr, + inlineUniformBlock: b32, + descriptorBindingInlineUniformBlockUpdateAfterBind: b32, +} + +PhysicalDeviceInlineUniformBlockProperties :: struct { + sType: StructureType, + pNext: rawptr, + maxInlineUniformBlockSize: u32, + maxPerStageDescriptorInlineUniformBlocks: u32, + maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, + maxDescriptorSetInlineUniformBlocks: u32, + maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, +} + +WriteDescriptorSetInlineUniformBlock :: struct { + sType: StructureType, + pNext: rawptr, + dataSize: u32, + pData: rawptr, +} + +DescriptorPoolInlineUniformBlockCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + maxInlineUniformBlockBindings: u32, +} + +PhysicalDeviceTextureCompressionASTCHDRFeatures :: struct { + sType: StructureType, + pNext: rawptr, + textureCompressionASTC_HDR: b32, +} + +RenderingAttachmentInfo :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, + resolveMode: ResolveModeFlags, + resolveImageView: ImageView, + resolveImageLayout: ImageLayout, + loadOp: AttachmentLoadOp, + storeOp: AttachmentStoreOp, + clearValue: ClearValue, +} + +RenderingInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: RenderingFlags, + renderArea: Rect2D, + layerCount: u32, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachments: [^]RenderingAttachmentInfo, + pDepthAttachment: ^RenderingAttachmentInfo, + pStencilAttachment: ^RenderingAttachmentInfo, +} + +PipelineRenderingCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachmentFormats: [^]Format, + depthAttachmentFormat: Format, + stencilAttachmentFormat: Format, +} + +PhysicalDeviceDynamicRenderingFeatures :: struct { + sType: StructureType, + pNext: rawptr, + dynamicRendering: b32, +} + +CommandBufferInheritanceRenderingInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: RenderingFlags, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachmentFormats: [^]Format, + depthAttachmentFormat: Format, + stencilAttachmentFormat: Format, + rasterizationSamples: SampleCountFlags, +} + +PhysicalDeviceShaderIntegerDotProductFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderIntegerDotProduct: b32, +} + +PhysicalDeviceShaderIntegerDotProductProperties :: struct { + sType: StructureType, + pNext: rawptr, + integerDotProduct8BitUnsignedAccelerated: b32, + integerDotProduct8BitSignedAccelerated: b32, + integerDotProduct8BitMixedSignednessAccelerated: b32, + integerDotProduct4x8BitPackedUnsignedAccelerated: b32, + integerDotProduct4x8BitPackedSignedAccelerated: b32, + integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProduct16BitUnsignedAccelerated: b32, + integerDotProduct16BitSignedAccelerated: b32, + integerDotProduct16BitMixedSignednessAccelerated: b32, + integerDotProduct32BitUnsignedAccelerated: b32, + integerDotProduct32BitSignedAccelerated: b32, + integerDotProduct32BitMixedSignednessAccelerated: b32, + integerDotProduct64BitUnsignedAccelerated: b32, + integerDotProduct64BitSignedAccelerated: b32, + integerDotProduct64BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, +} + +PhysicalDeviceTexelBufferAlignmentProperties :: struct { + sType: StructureType, + pNext: rawptr, + storageTexelBufferOffsetAlignmentBytes: DeviceSize, + storageTexelBufferOffsetSingleTexelAlignment: b32, + uniformTexelBufferOffsetAlignmentBytes: DeviceSize, + uniformTexelBufferOffsetSingleTexelAlignment: b32, +} + +FormatProperties3 :: struct { + sType: StructureType, + pNext: rawptr, + linearTilingFeatures: FormatFeatureFlags2, + optimalTilingFeatures: FormatFeatureFlags2, + bufferFeatures: FormatFeatureFlags2, +} + +PhysicalDeviceMaintenance4Features :: struct { + sType: StructureType, + pNext: rawptr, + maintenance4: b32, +} + +PhysicalDeviceMaintenance4Properties :: struct { + sType: StructureType, + pNext: rawptr, + maxBufferSize: DeviceSize, +} + +DeviceBufferMemoryRequirements :: struct { + sType: StructureType, + pNext: rawptr, + pCreateInfo: ^BufferCreateInfo, +} + +DeviceImageMemoryRequirements :: struct { + sType: StructureType, + pNext: rawptr, + pCreateInfo: ^ImageCreateInfo, + planeAspect: ImageAspectFlags, +} + SurfaceCapabilitiesKHR :: struct { minImageCount: u32, maxImageCount: u32, @@ -2329,6 +2860,36 @@ DisplayPresentInfoKHR :: struct { persistent: b32, } +RenderingFragmentShadingRateAttachmentInfoKHR :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, + shadingRateAttachmentTexelSize: Extent2D, +} + +RenderingFragmentDensityMapAttachmentInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, +} + +AttachmentSampleCountInfoAMD :: struct { + sType: StructureType, + pNext: rawptr, + colorAttachmentCount: u32, + pColorAttachmentSamples: [^]SampleCountFlags, + depthStencilAttachmentSamples: SampleCountFlags, +} + +MultiviewPerViewAttributesInfoNVX :: struct { + sType: StructureType, + pNext: rawptr, + perViewAttributes: b32, + perViewAttributesPositionXOnly: b32, +} + ImportMemoryFdInfoKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2528,10 +3089,23 @@ PhysicalDeviceShaderClockFeaturesKHR :: struct { shaderDeviceClock: b32, } -PhysicalDeviceShaderTerminateInvocationFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderTerminateInvocation: b32, +DeviceQueueGlobalPriorityCreateInfoKHR :: struct { + sType: StructureType, + pNext: rawptr, + globalPriority: QueueGlobalPriorityKHR, +} + +PhysicalDeviceGlobalPriorityQueryFeaturesKHR :: struct { + sType: StructureType, + pNext: rawptr, + globalPriorityQuery: b32, +} + +QueueFamilyGlobalPriorityPropertiesKHR :: struct { + sType: StructureType, + pNext: rawptr, + priorityCount: u32, + priorities: [MAX_GLOBAL_PRIORITY_SIZE_KHR]QueueGlobalPriorityKHR, } FragmentShadingRateAttachmentInfoKHR :: struct { @@ -2651,47 +3225,6 @@ PipelineExecutableInternalRepresentationKHR :: struct { pData: rawptr, } -PhysicalDeviceShaderIntegerDotProductFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderIntegerDotProduct: b32, -} - -PhysicalDeviceShaderIntegerDotProductPropertiesKHR :: struct { - sType: StructureType, - pNext: rawptr, - integerDotProduct8BitUnsignedAccelerated: b32, - integerDotProduct8BitSignedAccelerated: b32, - integerDotProduct8BitMixedSignednessAccelerated: b32, - integerDotProduct4x8BitPackedUnsignedAccelerated: b32, - integerDotProduct4x8BitPackedSignedAccelerated: b32, - integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, - integerDotProduct16BitUnsignedAccelerated: b32, - integerDotProduct16BitSignedAccelerated: b32, - integerDotProduct16BitMixedSignednessAccelerated: b32, - integerDotProduct32BitUnsignedAccelerated: b32, - integerDotProduct32BitSignedAccelerated: b32, - integerDotProduct32BitMixedSignednessAccelerated: b32, - integerDotProduct64BitUnsignedAccelerated: b32, - integerDotProduct64BitSignedAccelerated: b32, - integerDotProduct64BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, -} - PipelineLibraryCreateInfoKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2712,100 +3245,16 @@ PhysicalDevicePresentIdFeaturesKHR :: struct { presentId: b32, } -MemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, -} - -BufferMemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, - srcQueueFamilyIndex: u32, - dstQueueFamilyIndex: u32, - buffer: Buffer, - offset: DeviceSize, - size: DeviceSize, -} - -ImageMemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, - oldLayout: ImageLayout, - newLayout: ImageLayout, - srcQueueFamilyIndex: u32, - dstQueueFamilyIndex: u32, - image: Image, - subresourceRange: ImageSubresourceRange, -} - -DependencyInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - dependencyFlags: DependencyFlags, - memoryBarrierCount: u32, - pMemoryBarriers: [^]MemoryBarrier2KHR, - bufferMemoryBarrierCount: u32, - pBufferMemoryBarriers: [^]BufferMemoryBarrier2KHR, - imageMemoryBarrierCount: u32, - pImageMemoryBarriers: [^]ImageMemoryBarrier2KHR, -} - -SemaphoreSubmitInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - semaphore: Semaphore, - value: u64, - stageMask: PipelineStageFlags2KHR, - deviceIndex: u32, -} - -CommandBufferSubmitInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - commandBuffer: CommandBuffer, - deviceMask: u32, -} - -SubmitInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - flags: SubmitFlagsKHR, - waitSemaphoreInfoCount: u32, - pWaitSemaphoreInfos: [^]SemaphoreSubmitInfoKHR, - commandBufferInfoCount: u32, - pCommandBufferInfos: [^]CommandBufferSubmitInfoKHR, - signalSemaphoreInfoCount: u32, - pSignalSemaphoreInfos: [^]SemaphoreSubmitInfoKHR, -} - -PhysicalDeviceSynchronization2FeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - synchronization2: b32, -} - QueueFamilyCheckpointProperties2NV :: struct { sType: StructureType, pNext: rawptr, - checkpointExecutionStageMask: PipelineStageFlags2KHR, + checkpointExecutionStageMask: PipelineStageFlags2, } CheckpointData2NV :: struct { sType: StructureType, pNext: rawptr, - stage: PipelineStageFlags2KHR, + stage: PipelineStageFlags2, pCheckpointMarker: rawptr, } @@ -2815,12 +3264,6 @@ PhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR :: struct { shaderSubgroupUniformControlFlow: b32, } -PhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderZeroInitializeWorkgroupMemory: b32, -} - PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2830,117 +3273,6 @@ PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR :: struct { workgroupMemoryExplicitLayout16BitAccess: b32, } -BufferCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcOffset: DeviceSize, - dstOffset: DeviceSize, - size: DeviceSize, -} - -CopyBufferInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcBuffer: Buffer, - dstBuffer: Buffer, - regionCount: u32, - pRegions: [^]BufferCopy2KHR, -} - -ImageCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffset: Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffset: Offset3D, - extent: Extent3D, -} - -CopyImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageCopy2KHR, -} - -BufferImageCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - bufferOffset: DeviceSize, - bufferRowLength: u32, - bufferImageHeight: u32, - imageSubresource: ImageSubresourceLayers, - imageOffset: Offset3D, - imageExtent: Extent3D, -} - -CopyBufferToImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcBuffer: Buffer, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]BufferImageCopy2KHR, -} - -CopyImageToBufferInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstBuffer: Buffer, - regionCount: u32, - pRegions: [^]BufferImageCopy2KHR, -} - -ImageBlit2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffsets: [2]Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffsets: [2]Offset3D, -} - -BlitImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageBlit2KHR, - filter: Filter, -} - -ImageResolve2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffset: Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffset: Offset3D, - extent: Extent3D, -} - -ResolveImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageResolve2KHR, -} - DebugReportCallbackCreateInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3130,12 +3462,6 @@ ValidationFlagsEXT :: struct { pDisabledValidationChecks: [^]ValidationCheckEXT, } -PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - textureCompressionASTC_HDR: b32, -} - ImageViewASTCDecodeModeEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3385,36 +3711,6 @@ DebugUtilsObjectTagInfoEXT :: struct { pTag: rawptr, } -PhysicalDeviceInlineUniformBlockFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - inlineUniformBlock: b32, - descriptorBindingInlineUniformBlockUpdateAfterBind: b32, -} - -PhysicalDeviceInlineUniformBlockPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - maxInlineUniformBlockSize: u32, - maxPerStageDescriptorInlineUniformBlocks: u32, - maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, - maxDescriptorSetInlineUniformBlocks: u32, - maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, -} - -WriteDescriptorSetInlineUniformBlockEXT :: struct { - sType: StructureType, - pNext: rawptr, - dataSize: u32, - pData: rawptr, -} - -DescriptorPoolInlineUniformBlockCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - maxInlineUniformBlockBindings: u32, -} - SampleLocationEXT :: struct { x: f32, y: f32, @@ -3570,6 +3866,19 @@ ImageDrmFormatModifierPropertiesEXT :: struct { drmFormatModifier: u64, } +DrmFormatModifierProperties2EXT :: struct { + drmFormatModifier: u64, + drmFormatModifierPlaneCount: u32, + drmFormatModifierTilingFeatures: FormatFeatureFlags2, +} + +DrmFormatModifierPropertiesList2EXT :: struct { + sType: StructureType, + pNext: rawptr, + drmFormatModifierCount: u32, + pDrmFormatModifierProperties: [^]DrmFormatModifierProperties2EXT, +} + ValidationCacheCreateInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3792,12 +4101,6 @@ FilterCubicImageViewImageFormatPropertiesEXT :: struct { filterCubicMinmax: b32, } -DeviceQueueGlobalPriorityCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - globalPriority: QueueGlobalPriorityEXT, -} - ImportMemoryHostPointerInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3879,19 +4182,6 @@ PhysicalDeviceVertexAttributeDivisorFeaturesEXT :: struct { vertexAttributeInstanceRateZeroDivisor: b32, } -PipelineCreationFeedbackEXT :: struct { - flags: PipelineCreationFeedbackFlagsEXT, - duration: u64, -} - -PipelineCreationFeedbackCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - pPipelineCreationFeedback: ^PipelineCreationFeedbackEXT, - pipelineStageCreationFeedbackCount: u32, - pPipelineStageCreationFeedbacks: [^]PipelineCreationFeedbackEXT, -} - PhysicalDeviceComputeShaderDerivativesFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4067,28 +4357,6 @@ RenderPassFragmentDensityMapCreateInfoEXT :: struct { fragmentDensityMapAttachment: AttachmentReference, } -PhysicalDeviceSubgroupSizeControlFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - subgroupSizeControl: b32, - computeFullSubgroups: b32, -} - -PhysicalDeviceSubgroupSizeControlPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - minSubgroupSize: u32, - maxSubgroupSize: u32, - maxComputeWorkgroupSubgroups: u32, - requiredSubgroupSizeStages: ShaderStageFlags, -} - -PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - requiredSubgroupSize: u32, -} - PhysicalDeviceShaderCoreProperties2AMD :: struct { sType: StructureType, pNext: rawptr, @@ -4148,16 +4416,6 @@ BufferDeviceAddressCreateInfoEXT :: struct { deviceAddress: DeviceAddress, } -PhysicalDeviceToolPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - name: [MAX_EXTENSION_NAME_SIZE]byte, - version: [MAX_EXTENSION_NAME_SIZE]byte, - purposes: ToolPurposeFlagsEXT, - description: [MAX_DESCRIPTION_SIZE]byte, - layer: [MAX_EXTENSION_NAME_SIZE]byte, -} - ValidationFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4327,12 +4585,6 @@ PhysicalDeviceShaderAtomicFloat2FeaturesEXT :: struct { sparseImageFloat32AtomicMinMax: b32, } -PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - shaderDemoteToHelperInvocation: b32, -} - PhysicalDeviceDeviceGeneratedCommandsPropertiesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4472,15 +4724,6 @@ PhysicalDeviceTexelBufferAlignmentFeaturesEXT :: struct { texelBufferAlignment: b32, } -PhysicalDeviceTexelBufferAlignmentPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - storageTexelBufferOffsetAlignmentBytes: DeviceSize, - storageTexelBufferOffsetSingleTexelAlignment: b32, - uniformTexelBufferOffsetAlignmentBytes: DeviceSize, - uniformTexelBufferOffsetSingleTexelAlignment: b32, -} - RenderPassTransformBeginInfoQCOM :: struct { sType: StructureType, pNext: rawptr, @@ -4555,30 +4798,6 @@ PhysicalDeviceCustomBorderColorFeaturesEXT :: struct { customBorderColorWithoutFormat: b32, } -PhysicalDevicePrivateDataFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - privateData: b32, -} - -DevicePrivateDataCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - privateDataSlotRequestCount: u32, -} - -PrivateDataSlotCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - flags: PrivateDataSlotCreateFlagsEXT, -} - -PhysicalDevicePipelineCreationCacheControlFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - pipelineCreationCacheControl: b32, -} - PhysicalDeviceDiagnosticsConfigFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4591,6 +4810,25 @@ DeviceDiagnosticsConfigCreateInfoNV :: struct { flags: DeviceDiagnosticsConfigFlagsNV, } +PhysicalDeviceGraphicsPipelineLibraryFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + graphicsPipelineLibrary: b32, +} + +PhysicalDeviceGraphicsPipelineLibraryPropertiesEXT :: struct { + sType: StructureType, + pNext: rawptr, + graphicsPipelineLibraryFastLinking: b32, + graphicsPipelineLibraryIndependentInterpolationDecoration: b32, +} + +GraphicsPipelineLibraryCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + flags: GraphicsPipelineLibraryFlagsEXT, +} + PhysicalDeviceFragmentShadingRateEnumsFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4708,12 +4946,6 @@ CopyCommandTransformInfoQCOM :: struct { transform: SurfaceTransformFlagsKHR, } -PhysicalDeviceImageRobustnessFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - robustImageAccess: b32, -} - PhysicalDevice4444FormatsFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4721,6 +4953,20 @@ PhysicalDevice4444FormatsFeaturesEXT :: struct { formatA4B4G4R4: b32, } +PhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM :: struct { + sType: StructureType, + pNext: rawptr, + rasterizationOrderColorAttachmentAccess: b32, + rasterizationOrderDepthAttachmentAccess: b32, + rasterizationOrderStencilAttachmentAccess: b32, +} + +PhysicalDeviceRGBA10X6FormatsFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + formatRgba10x6WithoutYCbCrSampler: b32, +} + PhysicalDeviceMutableDescriptorTypeFeaturesVALVE :: struct { sType: StructureType, pNext: rawptr, @@ -4774,6 +5020,18 @@ PhysicalDeviceDrmPropertiesEXT :: struct { renderMinor: i64, } +PhysicalDeviceDepthClipControlFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + depthClipControl: b32, +} + +PipelineViewportDepthClipControlCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + negativeOneToOne: b32, +} + PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4840,17 +5098,24 @@ PipelineColorWriteCreateInfoEXT :: struct { pColorWriteEnables: [^]b32, } -PhysicalDeviceGlobalPriorityQueryFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - globalPriorityQuery: b32, +PhysicalDevicePrimitivesGeneratedQueryFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + primitivesGeneratedQuery: b32, + primitivesGeneratedQueryWithRasterizerDiscard: b32, + primitivesGeneratedQueryWithNonZeroStreams: b32, } -QueueFamilyGlobalPriorityPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - priorityCount: u32, - priorities: [MAX_GLOBAL_PRIORITY_SIZE_EXT]QueueGlobalPriorityEXT, +PhysicalDeviceImageViewMinLodFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + minLod: b32, +} + +ImageViewMinLodCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + minLod: f32, } PhysicalDeviceMultiDrawFeaturesEXT :: struct { @@ -4876,12 +5141,78 @@ MultiDrawIndexedInfoEXT :: struct { vertexOffset: i32, } +PhysicalDeviceImage2DViewOf3DFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + image2DViewOf3D: b32, + sampler2DViewOf3D: b32, +} + +PhysicalDeviceBorderColorSwizzleFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + borderColorSwizzle: b32, + borderColorSwizzleFromImage: b32, +} + +SamplerBorderColorComponentMappingCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + components: ComponentMapping, + srgb: b32, +} + PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, pageableDeviceLocalMemory: b32, } +PhysicalDeviceDescriptorSetHostMappingFeaturesVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorSetHostMapping: b32, +} + +DescriptorSetBindingReferenceVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorSetLayout: DescriptorSetLayout, + binding: u32, +} + +DescriptorSetLayoutHostMappingInfoVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorOffset: int, + descriptorSize: u32, +} + +PhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityMapOffset: b32, +} + +PhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityOffsetGranularity: Extent2D, +} + +SubpassFragmentDensityMapOffsetEndInfoQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityOffsetCount: u32, + pFragmentDensityOffsets: [^]Offset2D, +} + +PhysicalDeviceLinearColorAttachmentFeaturesNV :: struct { + sType: StructureType, + pNext: rawptr, + linearColorAttachment: b32, +} + DeviceOrHostAddressKHR :: struct #raw_union { deviceAddress: DeviceAddress, hostAddress: rawptr, @@ -5283,178 +5614,252 @@ IOSSurfaceCreateInfoMVK :: struct { } // Aliases -PhysicalDeviceVariablePointerFeatures :: PhysicalDeviceVariablePointersFeatures -PhysicalDeviceShaderDrawParameterFeatures :: PhysicalDeviceShaderDrawParametersFeatures -RenderPassMultiviewCreateInfoKHR :: RenderPassMultiviewCreateInfo -PhysicalDeviceMultiviewFeaturesKHR :: PhysicalDeviceMultiviewFeatures -PhysicalDeviceMultiviewPropertiesKHR :: PhysicalDeviceMultiviewProperties -PhysicalDeviceFeatures2KHR :: PhysicalDeviceFeatures2 -PhysicalDeviceProperties2KHR :: PhysicalDeviceProperties2 -FormatProperties2KHR :: FormatProperties2 -ImageFormatProperties2KHR :: ImageFormatProperties2 -PhysicalDeviceImageFormatInfo2KHR :: PhysicalDeviceImageFormatInfo2 -QueueFamilyProperties2KHR :: QueueFamilyProperties2 -PhysicalDeviceMemoryProperties2KHR :: PhysicalDeviceMemoryProperties2 -SparseImageFormatProperties2KHR :: SparseImageFormatProperties2 -PhysicalDeviceSparseImageFormatInfo2KHR :: PhysicalDeviceSparseImageFormatInfo2 -PeerMemoryFeatureFlagsKHR :: PeerMemoryFeatureFlags -PeerMemoryFeatureFlagKHR :: PeerMemoryFeatureFlag -MemoryAllocateFlagsKHR :: MemoryAllocateFlags -MemoryAllocateFlagKHR :: MemoryAllocateFlag -MemoryAllocateFlagsInfoKHR :: MemoryAllocateFlagsInfo -DeviceGroupRenderPassBeginInfoKHR :: DeviceGroupRenderPassBeginInfo -DeviceGroupCommandBufferBeginInfoKHR :: DeviceGroupCommandBufferBeginInfo -DeviceGroupSubmitInfoKHR :: DeviceGroupSubmitInfo -DeviceGroupBindSparseInfoKHR :: DeviceGroupBindSparseInfo -BindBufferMemoryDeviceGroupInfoKHR :: BindBufferMemoryDeviceGroupInfo -BindImageMemoryDeviceGroupInfoKHR :: BindImageMemoryDeviceGroupInfo -CommandPoolTrimFlagsKHR :: CommandPoolTrimFlags -PhysicalDeviceGroupPropertiesKHR :: PhysicalDeviceGroupProperties -DeviceGroupDeviceCreateInfoKHR :: DeviceGroupDeviceCreateInfo -ExternalMemoryHandleTypeFlagsKHR :: ExternalMemoryHandleTypeFlags -ExternalMemoryHandleTypeFlagKHR :: ExternalMemoryHandleTypeFlag -ExternalMemoryFeatureFlagsKHR :: ExternalMemoryFeatureFlags -ExternalMemoryFeatureFlagKHR :: ExternalMemoryFeatureFlag -ExternalMemoryPropertiesKHR :: ExternalMemoryProperties -PhysicalDeviceExternalImageFormatInfoKHR :: PhysicalDeviceExternalImageFormatInfo -ExternalImageFormatPropertiesKHR :: ExternalImageFormatProperties -PhysicalDeviceExternalBufferInfoKHR :: PhysicalDeviceExternalBufferInfo -ExternalBufferPropertiesKHR :: ExternalBufferProperties -PhysicalDeviceIDPropertiesKHR :: PhysicalDeviceIDProperties -ExternalMemoryImageCreateInfoKHR :: ExternalMemoryImageCreateInfo -ExternalMemoryBufferCreateInfoKHR :: ExternalMemoryBufferCreateInfo -ExportMemoryAllocateInfoKHR :: ExportMemoryAllocateInfo -ExternalSemaphoreHandleTypeFlagsKHR :: ExternalSemaphoreHandleTypeFlags -ExternalSemaphoreHandleTypeFlagKHR :: ExternalSemaphoreHandleTypeFlag -ExternalSemaphoreFeatureFlagsKHR :: ExternalSemaphoreFeatureFlags -ExternalSemaphoreFeatureFlagKHR :: ExternalSemaphoreFeatureFlag -PhysicalDeviceExternalSemaphoreInfoKHR :: PhysicalDeviceExternalSemaphoreInfo -ExternalSemaphorePropertiesKHR :: ExternalSemaphoreProperties -SemaphoreImportFlagsKHR :: SemaphoreImportFlags -SemaphoreImportFlagKHR :: SemaphoreImportFlag -ExportSemaphoreCreateInfoKHR :: ExportSemaphoreCreateInfo -PhysicalDeviceShaderFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features -PhysicalDeviceFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features -PhysicalDevice16BitStorageFeaturesKHR :: PhysicalDevice16BitStorageFeatures -DescriptorUpdateTemplateKHR :: DescriptorUpdateTemplate -DescriptorUpdateTemplateTypeKHR :: DescriptorUpdateTemplateType -DescriptorUpdateTemplateCreateFlagsKHR :: DescriptorUpdateTemplateCreateFlags -DescriptorUpdateTemplateEntryKHR :: DescriptorUpdateTemplateEntry -DescriptorUpdateTemplateCreateInfoKHR :: DescriptorUpdateTemplateCreateInfo -PhysicalDeviceImagelessFramebufferFeaturesKHR :: PhysicalDeviceImagelessFramebufferFeatures -FramebufferAttachmentsCreateInfoKHR :: FramebufferAttachmentsCreateInfo -FramebufferAttachmentImageInfoKHR :: FramebufferAttachmentImageInfo -RenderPassAttachmentBeginInfoKHR :: RenderPassAttachmentBeginInfo -RenderPassCreateInfo2KHR :: RenderPassCreateInfo2 -AttachmentDescription2KHR :: AttachmentDescription2 -AttachmentReference2KHR :: AttachmentReference2 -SubpassDescription2KHR :: SubpassDescription2 -SubpassDependency2KHR :: SubpassDependency2 -SubpassBeginInfoKHR :: SubpassBeginInfo -SubpassEndInfoKHR :: SubpassEndInfo -ExternalFenceHandleTypeFlagsKHR :: ExternalFenceHandleTypeFlags -ExternalFenceHandleTypeFlagKHR :: ExternalFenceHandleTypeFlag -ExternalFenceFeatureFlagsKHR :: ExternalFenceFeatureFlags -ExternalFenceFeatureFlagKHR :: ExternalFenceFeatureFlag -PhysicalDeviceExternalFenceInfoKHR :: PhysicalDeviceExternalFenceInfo -ExternalFencePropertiesKHR :: ExternalFenceProperties -FenceImportFlagsKHR :: FenceImportFlags -FenceImportFlagKHR :: FenceImportFlag -ExportFenceCreateInfoKHR :: ExportFenceCreateInfo -PointClippingBehaviorKHR :: PointClippingBehavior -TessellationDomainOriginKHR :: TessellationDomainOrigin -PhysicalDevicePointClippingPropertiesKHR :: PhysicalDevicePointClippingProperties -RenderPassInputAttachmentAspectCreateInfoKHR :: RenderPassInputAttachmentAspectCreateInfo -InputAttachmentAspectReferenceKHR :: InputAttachmentAspectReference -ImageViewUsageCreateInfoKHR :: ImageViewUsageCreateInfo -PipelineTessellationDomainOriginStateCreateInfoKHR :: PipelineTessellationDomainOriginStateCreateInfo -PhysicalDeviceVariablePointerFeaturesKHR :: PhysicalDeviceVariablePointersFeatures -PhysicalDeviceVariablePointersFeaturesKHR :: PhysicalDeviceVariablePointersFeatures -MemoryDedicatedRequirementsKHR :: MemoryDedicatedRequirements -MemoryDedicatedAllocateInfoKHR :: MemoryDedicatedAllocateInfo -BufferMemoryRequirementsInfo2KHR :: BufferMemoryRequirementsInfo2 -ImageMemoryRequirementsInfo2KHR :: ImageMemoryRequirementsInfo2 -ImageSparseMemoryRequirementsInfo2KHR :: ImageSparseMemoryRequirementsInfo2 -MemoryRequirements2KHR :: MemoryRequirements2 -SparseImageMemoryRequirements2KHR :: SparseImageMemoryRequirements2 -ImageFormatListCreateInfoKHR :: ImageFormatListCreateInfo -SamplerYcbcrConversionKHR :: SamplerYcbcrConversion -SamplerYcbcrModelConversionKHR :: SamplerYcbcrModelConversion -SamplerYcbcrRangeKHR :: SamplerYcbcrRange -ChromaLocationKHR :: ChromaLocation -SamplerYcbcrConversionCreateInfoKHR :: SamplerYcbcrConversionCreateInfo -SamplerYcbcrConversionInfoKHR :: SamplerYcbcrConversionInfo -BindImagePlaneMemoryInfoKHR :: BindImagePlaneMemoryInfo -ImagePlaneMemoryRequirementsInfoKHR :: ImagePlaneMemoryRequirementsInfo -PhysicalDeviceSamplerYcbcrConversionFeaturesKHR :: PhysicalDeviceSamplerYcbcrConversionFeatures -SamplerYcbcrConversionImageFormatPropertiesKHR :: SamplerYcbcrConversionImageFormatProperties -BindBufferMemoryInfoKHR :: BindBufferMemoryInfo -BindImageMemoryInfoKHR :: BindImageMemoryInfo -PhysicalDeviceMaintenance3PropertiesKHR :: PhysicalDeviceMaintenance3Properties -DescriptorSetLayoutSupportKHR :: DescriptorSetLayoutSupport -PhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR :: PhysicalDeviceShaderSubgroupExtendedTypesFeatures -PhysicalDevice8BitStorageFeaturesKHR :: PhysicalDevice8BitStorageFeatures -PhysicalDeviceShaderAtomicInt64FeaturesKHR :: PhysicalDeviceShaderAtomicInt64Features -DriverIdKHR :: DriverId -ConformanceVersionKHR :: ConformanceVersion -PhysicalDeviceDriverPropertiesKHR :: PhysicalDeviceDriverProperties -ShaderFloatControlsIndependenceKHR :: ShaderFloatControlsIndependence -PhysicalDeviceFloatControlsPropertiesKHR :: PhysicalDeviceFloatControlsProperties -ResolveModeFlagKHR :: ResolveModeFlag -ResolveModeFlagsKHR :: ResolveModeFlags -SubpassDescriptionDepthStencilResolveKHR :: SubpassDescriptionDepthStencilResolve -PhysicalDeviceDepthStencilResolvePropertiesKHR :: PhysicalDeviceDepthStencilResolveProperties -SemaphoreTypeKHR :: SemaphoreType -SemaphoreWaitFlagKHR :: SemaphoreWaitFlag -SemaphoreWaitFlagsKHR :: SemaphoreWaitFlags -PhysicalDeviceTimelineSemaphoreFeaturesKHR :: PhysicalDeviceTimelineSemaphoreFeatures -PhysicalDeviceTimelineSemaphorePropertiesKHR :: PhysicalDeviceTimelineSemaphoreProperties -SemaphoreTypeCreateInfoKHR :: SemaphoreTypeCreateInfo -TimelineSemaphoreSubmitInfoKHR :: TimelineSemaphoreSubmitInfo -SemaphoreWaitInfoKHR :: SemaphoreWaitInfo -SemaphoreSignalInfoKHR :: SemaphoreSignalInfo -PhysicalDeviceVulkanMemoryModelFeaturesKHR :: PhysicalDeviceVulkanMemoryModelFeatures -PhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR :: PhysicalDeviceSeparateDepthStencilLayoutsFeatures -AttachmentReferenceStencilLayoutKHR :: AttachmentReferenceStencilLayout -AttachmentDescriptionStencilLayoutKHR :: AttachmentDescriptionStencilLayout -PhysicalDeviceUniformBufferStandardLayoutFeaturesKHR :: PhysicalDeviceUniformBufferStandardLayoutFeatures -PhysicalDeviceBufferDeviceAddressFeaturesKHR :: PhysicalDeviceBufferDeviceAddressFeatures -BufferDeviceAddressInfoKHR :: BufferDeviceAddressInfo -BufferOpaqueCaptureAddressCreateInfoKHR :: BufferOpaqueCaptureAddressCreateInfo -MemoryOpaqueCaptureAddressAllocateInfoKHR :: MemoryOpaqueCaptureAddressAllocateInfo -DeviceMemoryOpaqueCaptureAddressInfoKHR :: DeviceMemoryOpaqueCaptureAddressInfo -PipelineStageFlags2KHR :: Flags64 -PipelineStageFlag2KHR :: Flags64 -AccessFlags2KHR :: Flags64 -AccessFlag2KHR :: Flags64 -SamplerReductionModeEXT :: SamplerReductionMode -SamplerReductionModeCreateInfoEXT :: SamplerReductionModeCreateInfo -PhysicalDeviceSamplerFilterMinmaxPropertiesEXT :: PhysicalDeviceSamplerFilterMinmaxProperties -DescriptorBindingFlagEXT :: DescriptorBindingFlag -DescriptorBindingFlagsEXT :: DescriptorBindingFlags -DescriptorSetLayoutBindingFlagsCreateInfoEXT :: DescriptorSetLayoutBindingFlagsCreateInfo -PhysicalDeviceDescriptorIndexingFeaturesEXT :: PhysicalDeviceDescriptorIndexingFeatures -PhysicalDeviceDescriptorIndexingPropertiesEXT :: PhysicalDeviceDescriptorIndexingProperties -DescriptorSetVariableDescriptorCountAllocateInfoEXT :: DescriptorSetVariableDescriptorCountAllocateInfo -DescriptorSetVariableDescriptorCountLayoutSupportEXT :: DescriptorSetVariableDescriptorCountLayoutSupport -RayTracingShaderGroupTypeNV :: RayTracingShaderGroupTypeKHR -GeometryTypeNV :: GeometryTypeKHR -AccelerationStructureTypeNV :: AccelerationStructureTypeKHR -CopyAccelerationStructureModeNV :: CopyAccelerationStructureModeKHR -GeometryFlagsNV :: GeometryFlagsKHR -GeometryFlagNV :: GeometryFlagKHR -GeometryInstanceFlagsNV :: GeometryInstanceFlagsKHR -GeometryInstanceFlagNV :: GeometryInstanceFlagKHR -BuildAccelerationStructureFlagsNV :: BuildAccelerationStructureFlagsKHR -BuildAccelerationStructureFlagNV :: BuildAccelerationStructureFlagKHR -TransformMatrixNV :: TransformMatrixKHR -AabbPositionsNV :: AabbPositionsKHR -AccelerationStructureInstanceNV :: AccelerationStructureInstanceKHR -QueryPoolCreateInfoINTEL :: QueryPoolPerformanceQueryCreateInfoINTEL -PhysicalDeviceScalarBlockLayoutFeaturesEXT :: PhysicalDeviceScalarBlockLayoutFeatures -PhysicalDeviceBufferAddressFeaturesEXT :: PhysicalDeviceBufferDeviceAddressFeaturesEXT -BufferDeviceAddressInfoEXT :: BufferDeviceAddressInfo -ImageStencilUsageCreateInfoEXT :: ImageStencilUsageCreateInfo -PhysicalDeviceHostQueryResetFeaturesEXT :: PhysicalDeviceHostQueryResetFeatures +PhysicalDeviceVariablePointerFeatures :: PhysicalDeviceVariablePointersFeatures +PhysicalDeviceShaderDrawParameterFeatures :: PhysicalDeviceShaderDrawParametersFeatures +PipelineStageFlags2 :: Flags64 +PipelineStageFlag2 :: Flags64 +AccessFlags2 :: Flags64 +AccessFlag2 :: Flags64 +FormatFeatureFlags2 :: Flags64 +FormatFeatureFlag2 :: Flags64 +RenderingFlagsKHR :: RenderingFlags +RenderingFlagKHR :: RenderingFlag +RenderingInfoKHR :: RenderingInfo +RenderingAttachmentInfoKHR :: RenderingAttachmentInfo +PipelineRenderingCreateInfoKHR :: PipelineRenderingCreateInfo +PhysicalDeviceDynamicRenderingFeaturesKHR :: PhysicalDeviceDynamicRenderingFeatures +CommandBufferInheritanceRenderingInfoKHR :: CommandBufferInheritanceRenderingInfo +AttachmentSampleCountInfoNV :: AttachmentSampleCountInfoAMD +RenderPassMultiviewCreateInfoKHR :: RenderPassMultiviewCreateInfo +PhysicalDeviceMultiviewFeaturesKHR :: PhysicalDeviceMultiviewFeatures +PhysicalDeviceMultiviewPropertiesKHR :: PhysicalDeviceMultiviewProperties +PhysicalDeviceFeatures2KHR :: PhysicalDeviceFeatures2 +PhysicalDeviceProperties2KHR :: PhysicalDeviceProperties2 +FormatProperties2KHR :: FormatProperties2 +ImageFormatProperties2KHR :: ImageFormatProperties2 +PhysicalDeviceImageFormatInfo2KHR :: PhysicalDeviceImageFormatInfo2 +QueueFamilyProperties2KHR :: QueueFamilyProperties2 +PhysicalDeviceMemoryProperties2KHR :: PhysicalDeviceMemoryProperties2 +SparseImageFormatProperties2KHR :: SparseImageFormatProperties2 +PhysicalDeviceSparseImageFormatInfo2KHR :: PhysicalDeviceSparseImageFormatInfo2 +PeerMemoryFeatureFlagsKHR :: PeerMemoryFeatureFlags +PeerMemoryFeatureFlagKHR :: PeerMemoryFeatureFlag +MemoryAllocateFlagsKHR :: MemoryAllocateFlags +MemoryAllocateFlagKHR :: MemoryAllocateFlag +MemoryAllocateFlagsInfoKHR :: MemoryAllocateFlagsInfo +DeviceGroupRenderPassBeginInfoKHR :: DeviceGroupRenderPassBeginInfo +DeviceGroupCommandBufferBeginInfoKHR :: DeviceGroupCommandBufferBeginInfo +DeviceGroupSubmitInfoKHR :: DeviceGroupSubmitInfo +DeviceGroupBindSparseInfoKHR :: DeviceGroupBindSparseInfo +BindBufferMemoryDeviceGroupInfoKHR :: BindBufferMemoryDeviceGroupInfo +BindImageMemoryDeviceGroupInfoKHR :: BindImageMemoryDeviceGroupInfo +CommandPoolTrimFlagsKHR :: CommandPoolTrimFlags +PhysicalDeviceGroupPropertiesKHR :: PhysicalDeviceGroupProperties +DeviceGroupDeviceCreateInfoKHR :: DeviceGroupDeviceCreateInfo +ExternalMemoryHandleTypeFlagsKHR :: ExternalMemoryHandleTypeFlags +ExternalMemoryHandleTypeFlagKHR :: ExternalMemoryHandleTypeFlag +ExternalMemoryFeatureFlagsKHR :: ExternalMemoryFeatureFlags +ExternalMemoryFeatureFlagKHR :: ExternalMemoryFeatureFlag +ExternalMemoryPropertiesKHR :: ExternalMemoryProperties +PhysicalDeviceExternalImageFormatInfoKHR :: PhysicalDeviceExternalImageFormatInfo +ExternalImageFormatPropertiesKHR :: ExternalImageFormatProperties +PhysicalDeviceExternalBufferInfoKHR :: PhysicalDeviceExternalBufferInfo +ExternalBufferPropertiesKHR :: ExternalBufferProperties +PhysicalDeviceIDPropertiesKHR :: PhysicalDeviceIDProperties +ExternalMemoryImageCreateInfoKHR :: ExternalMemoryImageCreateInfo +ExternalMemoryBufferCreateInfoKHR :: ExternalMemoryBufferCreateInfo +ExportMemoryAllocateInfoKHR :: ExportMemoryAllocateInfo +ExternalSemaphoreHandleTypeFlagsKHR :: ExternalSemaphoreHandleTypeFlags +ExternalSemaphoreHandleTypeFlagKHR :: ExternalSemaphoreHandleTypeFlag +ExternalSemaphoreFeatureFlagsKHR :: ExternalSemaphoreFeatureFlags +ExternalSemaphoreFeatureFlagKHR :: ExternalSemaphoreFeatureFlag +PhysicalDeviceExternalSemaphoreInfoKHR :: PhysicalDeviceExternalSemaphoreInfo +ExternalSemaphorePropertiesKHR :: ExternalSemaphoreProperties +SemaphoreImportFlagsKHR :: SemaphoreImportFlags +SemaphoreImportFlagKHR :: SemaphoreImportFlag +ExportSemaphoreCreateInfoKHR :: ExportSemaphoreCreateInfo +PhysicalDeviceShaderFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features +PhysicalDeviceFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features +PhysicalDevice16BitStorageFeaturesKHR :: PhysicalDevice16BitStorageFeatures +DescriptorUpdateTemplateKHR :: DescriptorUpdateTemplate +DescriptorUpdateTemplateTypeKHR :: DescriptorUpdateTemplateType +DescriptorUpdateTemplateCreateFlagsKHR :: DescriptorUpdateTemplateCreateFlags +DescriptorUpdateTemplateEntryKHR :: DescriptorUpdateTemplateEntry +DescriptorUpdateTemplateCreateInfoKHR :: DescriptorUpdateTemplateCreateInfo +PhysicalDeviceImagelessFramebufferFeaturesKHR :: PhysicalDeviceImagelessFramebufferFeatures +FramebufferAttachmentsCreateInfoKHR :: FramebufferAttachmentsCreateInfo +FramebufferAttachmentImageInfoKHR :: FramebufferAttachmentImageInfo +RenderPassAttachmentBeginInfoKHR :: RenderPassAttachmentBeginInfo +RenderPassCreateInfo2KHR :: RenderPassCreateInfo2 +AttachmentDescription2KHR :: AttachmentDescription2 +AttachmentReference2KHR :: AttachmentReference2 +SubpassDescription2KHR :: SubpassDescription2 +SubpassDependency2KHR :: SubpassDependency2 +SubpassBeginInfoKHR :: SubpassBeginInfo +SubpassEndInfoKHR :: SubpassEndInfo +ExternalFenceHandleTypeFlagsKHR :: ExternalFenceHandleTypeFlags +ExternalFenceHandleTypeFlagKHR :: ExternalFenceHandleTypeFlag +ExternalFenceFeatureFlagsKHR :: ExternalFenceFeatureFlags +ExternalFenceFeatureFlagKHR :: ExternalFenceFeatureFlag +PhysicalDeviceExternalFenceInfoKHR :: PhysicalDeviceExternalFenceInfo +ExternalFencePropertiesKHR :: ExternalFenceProperties +FenceImportFlagsKHR :: FenceImportFlags +FenceImportFlagKHR :: FenceImportFlag +ExportFenceCreateInfoKHR :: ExportFenceCreateInfo +PointClippingBehaviorKHR :: PointClippingBehavior +TessellationDomainOriginKHR :: TessellationDomainOrigin +PhysicalDevicePointClippingPropertiesKHR :: PhysicalDevicePointClippingProperties +RenderPassInputAttachmentAspectCreateInfoKHR :: RenderPassInputAttachmentAspectCreateInfo +InputAttachmentAspectReferenceKHR :: InputAttachmentAspectReference +ImageViewUsageCreateInfoKHR :: ImageViewUsageCreateInfo +PipelineTessellationDomainOriginStateCreateInfoKHR :: PipelineTessellationDomainOriginStateCreateInfo +PhysicalDeviceVariablePointerFeaturesKHR :: PhysicalDeviceVariablePointersFeatures +PhysicalDeviceVariablePointersFeaturesKHR :: PhysicalDeviceVariablePointersFeatures +MemoryDedicatedRequirementsKHR :: MemoryDedicatedRequirements +MemoryDedicatedAllocateInfoKHR :: MemoryDedicatedAllocateInfo +BufferMemoryRequirementsInfo2KHR :: BufferMemoryRequirementsInfo2 +ImageMemoryRequirementsInfo2KHR :: ImageMemoryRequirementsInfo2 +ImageSparseMemoryRequirementsInfo2KHR :: ImageSparseMemoryRequirementsInfo2 +MemoryRequirements2KHR :: MemoryRequirements2 +SparseImageMemoryRequirements2KHR :: SparseImageMemoryRequirements2 +ImageFormatListCreateInfoKHR :: ImageFormatListCreateInfo +SamplerYcbcrConversionKHR :: SamplerYcbcrConversion +SamplerYcbcrModelConversionKHR :: SamplerYcbcrModelConversion +SamplerYcbcrRangeKHR :: SamplerYcbcrRange +ChromaLocationKHR :: ChromaLocation +SamplerYcbcrConversionCreateInfoKHR :: SamplerYcbcrConversionCreateInfo +SamplerYcbcrConversionInfoKHR :: SamplerYcbcrConversionInfo +BindImagePlaneMemoryInfoKHR :: BindImagePlaneMemoryInfo +ImagePlaneMemoryRequirementsInfoKHR :: ImagePlaneMemoryRequirementsInfo +PhysicalDeviceSamplerYcbcrConversionFeaturesKHR :: PhysicalDeviceSamplerYcbcrConversionFeatures +SamplerYcbcrConversionImageFormatPropertiesKHR :: SamplerYcbcrConversionImageFormatProperties +BindBufferMemoryInfoKHR :: BindBufferMemoryInfo +BindImageMemoryInfoKHR :: BindImageMemoryInfo +PhysicalDeviceMaintenance3PropertiesKHR :: PhysicalDeviceMaintenance3Properties +DescriptorSetLayoutSupportKHR :: DescriptorSetLayoutSupport +PhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR :: PhysicalDeviceShaderSubgroupExtendedTypesFeatures +PhysicalDevice8BitStorageFeaturesKHR :: PhysicalDevice8BitStorageFeatures +PhysicalDeviceShaderAtomicInt64FeaturesKHR :: PhysicalDeviceShaderAtomicInt64Features +DriverIdKHR :: DriverId +ConformanceVersionKHR :: ConformanceVersion +PhysicalDeviceDriverPropertiesKHR :: PhysicalDeviceDriverProperties +ShaderFloatControlsIndependenceKHR :: ShaderFloatControlsIndependence +PhysicalDeviceFloatControlsPropertiesKHR :: PhysicalDeviceFloatControlsProperties +ResolveModeFlagKHR :: ResolveModeFlag +ResolveModeFlagsKHR :: ResolveModeFlags +SubpassDescriptionDepthStencilResolveKHR :: SubpassDescriptionDepthStencilResolve +PhysicalDeviceDepthStencilResolvePropertiesKHR :: PhysicalDeviceDepthStencilResolveProperties +SemaphoreTypeKHR :: SemaphoreType +SemaphoreWaitFlagKHR :: SemaphoreWaitFlag +SemaphoreWaitFlagsKHR :: SemaphoreWaitFlags +PhysicalDeviceTimelineSemaphoreFeaturesKHR :: PhysicalDeviceTimelineSemaphoreFeatures +PhysicalDeviceTimelineSemaphorePropertiesKHR :: PhysicalDeviceTimelineSemaphoreProperties +SemaphoreTypeCreateInfoKHR :: SemaphoreTypeCreateInfo +TimelineSemaphoreSubmitInfoKHR :: TimelineSemaphoreSubmitInfo +SemaphoreWaitInfoKHR :: SemaphoreWaitInfo +SemaphoreSignalInfoKHR :: SemaphoreSignalInfo +PhysicalDeviceVulkanMemoryModelFeaturesKHR :: PhysicalDeviceVulkanMemoryModelFeatures +PhysicalDeviceShaderTerminateInvocationFeaturesKHR :: PhysicalDeviceShaderTerminateInvocationFeatures +PhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR :: PhysicalDeviceSeparateDepthStencilLayoutsFeatures +AttachmentReferenceStencilLayoutKHR :: AttachmentReferenceStencilLayout +AttachmentDescriptionStencilLayoutKHR :: AttachmentDescriptionStencilLayout +PhysicalDeviceUniformBufferStandardLayoutFeaturesKHR :: PhysicalDeviceUniformBufferStandardLayoutFeatures +PhysicalDeviceBufferDeviceAddressFeaturesKHR :: PhysicalDeviceBufferDeviceAddressFeatures +BufferDeviceAddressInfoKHR :: BufferDeviceAddressInfo +BufferOpaqueCaptureAddressCreateInfoKHR :: BufferOpaqueCaptureAddressCreateInfo +MemoryOpaqueCaptureAddressAllocateInfoKHR :: MemoryOpaqueCaptureAddressAllocateInfo +DeviceMemoryOpaqueCaptureAddressInfoKHR :: DeviceMemoryOpaqueCaptureAddressInfo +PhysicalDeviceShaderIntegerDotProductFeaturesKHR :: PhysicalDeviceShaderIntegerDotProductFeatures +PhysicalDeviceShaderIntegerDotProductPropertiesKHR :: PhysicalDeviceShaderIntegerDotProductProperties +PipelineStageFlags2KHR :: PipelineStageFlags2 +PipelineStageFlag2KHR :: PipelineStageFlag2 +AccessFlags2KHR :: AccessFlags2 +AccessFlag2KHR :: AccessFlag2 +SubmitFlagKHR :: SubmitFlag +SubmitFlagsKHR :: SubmitFlags +MemoryBarrier2KHR :: MemoryBarrier2 +BufferMemoryBarrier2KHR :: BufferMemoryBarrier2 +ImageMemoryBarrier2KHR :: ImageMemoryBarrier2 +DependencyInfoKHR :: DependencyInfo +SubmitInfo2KHR :: SubmitInfo2 +SemaphoreSubmitInfoKHR :: SemaphoreSubmitInfo +CommandBufferSubmitInfoKHR :: CommandBufferSubmitInfo +PhysicalDeviceSynchronization2FeaturesKHR :: PhysicalDeviceSynchronization2Features +PhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR :: PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures +CopyBufferInfo2KHR :: CopyBufferInfo2 +CopyImageInfo2KHR :: CopyImageInfo2 +CopyBufferToImageInfo2KHR :: CopyBufferToImageInfo2 +CopyImageToBufferInfo2KHR :: CopyImageToBufferInfo2 +BlitImageInfo2KHR :: BlitImageInfo2 +ResolveImageInfo2KHR :: ResolveImageInfo2 +BufferCopy2KHR :: BufferCopy2 +ImageCopy2KHR :: ImageCopy2 +ImageBlit2KHR :: ImageBlit2 +BufferImageCopy2KHR :: BufferImageCopy2 +ImageResolve2KHR :: ImageResolve2 +FormatFeatureFlags2KHR :: FormatFeatureFlags2 +FormatFeatureFlag2KHR :: FormatFeatureFlag2 +FormatProperties3KHR :: FormatProperties3 +PhysicalDeviceMaintenance4FeaturesKHR :: PhysicalDeviceMaintenance4Features +PhysicalDeviceMaintenance4PropertiesKHR :: PhysicalDeviceMaintenance4Properties +DeviceBufferMemoryRequirementsKHR :: DeviceBufferMemoryRequirements +DeviceImageMemoryRequirementsKHR :: DeviceImageMemoryRequirements +PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT :: PhysicalDeviceTextureCompressionASTCHDRFeatures +SamplerReductionModeEXT :: SamplerReductionMode +SamplerReductionModeCreateInfoEXT :: SamplerReductionModeCreateInfo +PhysicalDeviceSamplerFilterMinmaxPropertiesEXT :: PhysicalDeviceSamplerFilterMinmaxProperties +PhysicalDeviceInlineUniformBlockFeaturesEXT :: PhysicalDeviceInlineUniformBlockFeatures +PhysicalDeviceInlineUniformBlockPropertiesEXT :: PhysicalDeviceInlineUniformBlockProperties +WriteDescriptorSetInlineUniformBlockEXT :: WriteDescriptorSetInlineUniformBlock +DescriptorPoolInlineUniformBlockCreateInfoEXT :: DescriptorPoolInlineUniformBlockCreateInfo +DescriptorBindingFlagEXT :: DescriptorBindingFlag +DescriptorBindingFlagsEXT :: DescriptorBindingFlags +DescriptorSetLayoutBindingFlagsCreateInfoEXT :: DescriptorSetLayoutBindingFlagsCreateInfo +PhysicalDeviceDescriptorIndexingFeaturesEXT :: PhysicalDeviceDescriptorIndexingFeatures +PhysicalDeviceDescriptorIndexingPropertiesEXT :: PhysicalDeviceDescriptorIndexingProperties +DescriptorSetVariableDescriptorCountAllocateInfoEXT :: DescriptorSetVariableDescriptorCountAllocateInfo +DescriptorSetVariableDescriptorCountLayoutSupportEXT :: DescriptorSetVariableDescriptorCountLayoutSupport +RayTracingShaderGroupTypeNV :: RayTracingShaderGroupTypeKHR +GeometryTypeNV :: GeometryTypeKHR +AccelerationStructureTypeNV :: AccelerationStructureTypeKHR +CopyAccelerationStructureModeNV :: CopyAccelerationStructureModeKHR +GeometryFlagsNV :: GeometryFlagsKHR +GeometryFlagNV :: GeometryFlagKHR +GeometryInstanceFlagsNV :: GeometryInstanceFlagsKHR +GeometryInstanceFlagNV :: GeometryInstanceFlagKHR +BuildAccelerationStructureFlagsNV :: BuildAccelerationStructureFlagsKHR +BuildAccelerationStructureFlagNV :: BuildAccelerationStructureFlagKHR +TransformMatrixNV :: TransformMatrixKHR +AabbPositionsNV :: AabbPositionsKHR +AccelerationStructureInstanceNV :: AccelerationStructureInstanceKHR +QueueGlobalPriorityEXT :: QueueGlobalPriorityKHR +DeviceQueueGlobalPriorityCreateInfoEXT :: DeviceQueueGlobalPriorityCreateInfoKHR +PipelineCreationFeedbackFlagEXT :: PipelineCreationFeedbackFlag +PipelineCreationFeedbackFlagsEXT :: PipelineCreationFeedbackFlags +PipelineCreationFeedbackCreateInfoEXT :: PipelineCreationFeedbackCreateInfo +PipelineCreationFeedbackEXT :: PipelineCreationFeedback +QueryPoolCreateInfoINTEL :: QueryPoolPerformanceQueryCreateInfoINTEL +PhysicalDeviceScalarBlockLayoutFeaturesEXT :: PhysicalDeviceScalarBlockLayoutFeatures +PhysicalDeviceSubgroupSizeControlFeaturesEXT :: PhysicalDeviceSubgroupSizeControlFeatures +PhysicalDeviceSubgroupSizeControlPropertiesEXT :: PhysicalDeviceSubgroupSizeControlProperties +PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT :: PipelineShaderStageRequiredSubgroupSizeCreateInfo +PhysicalDeviceBufferAddressFeaturesEXT :: PhysicalDeviceBufferDeviceAddressFeaturesEXT +BufferDeviceAddressInfoEXT :: BufferDeviceAddressInfo +ToolPurposeFlagEXT :: ToolPurposeFlag +ToolPurposeFlagsEXT :: ToolPurposeFlags +PhysicalDeviceToolPropertiesEXT :: PhysicalDeviceToolProperties +ImageStencilUsageCreateInfoEXT :: ImageStencilUsageCreateInfo +PhysicalDeviceHostQueryResetFeaturesEXT :: PhysicalDeviceHostQueryResetFeatures +PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT :: PhysicalDeviceShaderDemoteToHelperInvocationFeatures +PhysicalDeviceTexelBufferAlignmentPropertiesEXT :: PhysicalDeviceTexelBufferAlignmentProperties +PrivateDataSlotEXT :: PrivateDataSlot +PrivateDataSlotCreateFlagsEXT :: PrivateDataSlotCreateFlags +PhysicalDevicePrivateDataFeaturesEXT :: PhysicalDevicePrivateDataFeatures +DevicePrivateDataCreateInfoEXT :: DevicePrivateDataCreateInfo +PrivateDataSlotCreateInfoEXT :: PrivateDataSlotCreateInfo +PhysicalDevicePipelineCreationCacheControlFeaturesEXT :: PhysicalDevicePipelineCreationCacheControlFeatures +PhysicalDeviceImageRobustnessFeaturesEXT :: PhysicalDeviceImageRobustnessFeatures +PhysicalDeviceGlobalPriorityQueryFeaturesEXT :: PhysicalDeviceGlobalPriorityQueryFeaturesKHR +QueueFamilyGlobalPriorityPropertiesEXT :: QueueFamilyGlobalPriorityPropertiesKHR From cfae39c29d4c795c3236670bf7453f16d4b5b4cf Mon Sep 17 00:00:00 2001 From: hikari Date: Fri, 15 Apr 2022 19:16:31 +0300 Subject: [PATCH 035/245] sys/windows: add procedures and types --- core/sys/windows/kernel32.odin | 14 +++++++++ core/sys/windows/types.odin | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index f81c51311..735e065e2 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -92,6 +92,20 @@ foreign kernel32 { CreateSemaphoreW :: proc(attributes: LPSECURITY_ATTRIBUTES, initial_count, maximum_count: LONG, name: LPCSTR) -> HANDLE --- ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: LONG, previous_count: ^LONG) -> BOOL --- + CreateWaitableTimerW :: proc( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, + bManualReset: BOOL, + lpTimerName: LPCWSTR, + ) -> HANDLE --- + SetWaitableTimerEx :: proc( + hTimer: HANDLE, + lpDueTime: ^LARGE_INTEGER, + lPeriod: LONG, + pfnCompletionRoutine: PTIMERAPCROUTINE, + lpArgToCompletionRoutine: LPVOID, + WakeContext: PREASON_CONTEXT, + TolerableDelay: ULONG, + ) -> BOOL --- WaitForSingleObject :: proc(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD --- Sleep :: proc(dwMilliseconds: DWORD) --- GetProcessId :: proc(handle: HANDLE) -> DWORD --- diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index de19cd6cc..f05dd3310 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -123,6 +123,8 @@ PCONDITION_VARIABLE :: ^CONDITION_VARIABLE PLARGE_INTEGER :: ^LARGE_INTEGER PSRWLOCK :: ^SRWLOCK +MMRESULT :: UINT + SOCKET :: distinct uintptr // TODO socklen_t :: c_int ADDRESS_FAMILY :: USHORT @@ -195,6 +197,56 @@ GET_FILEEX_INFO_LEVELS :: distinct i32 GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0 GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1 +// String resource number bases (internal use) + +MMSYSERR_BASE :: 0 +WAVERR_BASE :: 32 +MIDIERR_BASE :: 64 +TIMERR_BASE :: 96 +JOYERR_BASE :: 160 +MCIERR_BASE :: 256 +MIXERR_BASE :: 1024 + +MCI_STRING_OFFSET :: 512 +MCI_VD_OFFSET :: 1024 +MCI_CD_OFFSET :: 1088 +MCI_WAVE_OFFSET :: 1152 +MCI_SEQ_OFFSET :: 1216 + +// timer error return values +TIMERR_NOERROR :: 0 // no error +TIMERR_NOCANDO :: TIMERR_BASE + 1 // request not completed +TIMERR_STRUCT :: TIMERR_BASE + 33 // time struct size + +DIAGNOSTIC_REASON_VERSION :: 0 + +DIAGNOSTIC_REASON_SIMPLE_STRING :: 0x00000001 +DIAGNOSTIC_REASON_DETAILED_STRING :: 0x00000002 +DIAGNOSTIC_REASON_NOT_SPECIFIED :: 0x80000000 + +// Defines for power request APIs + +POWER_REQUEST_CONTEXT_VERSION :: DIAGNOSTIC_REASON_VERSION + +POWER_REQUEST_CONTEXT_SIMPLE_STRING :: DIAGNOSTIC_REASON_SIMPLE_STRING +POWER_REQUEST_CONTEXT_DETAILED_STRING :: DIAGNOSTIC_REASON_DETAILED_STRING + +REASON_CONTEXT :: struct { + Version: ULONG, + Flags: DWORD, + Reason: struct #raw_union { + Detailed: struct { + LocalizedReasonModule: HMODULE, + LocalizedReasonId: ULONG, + ReasonStringCount: ULONG, + ReasonStrings: ^LPWSTR, + }, + SimpleReasonString: LPWSTR, + }, +} +PREASON_CONTEXT :: ^REASON_CONTEXT + +PTIMERAPCROUTINE :: #type proc "stdcall" (lpArgToCompletionRoutine: LPVOID, dwTimerLowValue, dwTimerHighValue: DWORD) TIMERPROC :: #type proc "stdcall" (HWND, UINT, UINT_PTR, DWORD) From d3fbf36df7cddf2cf69f7d761ccf4dfea863a40c Mon Sep 17 00:00:00 2001 From: hikari Date: Fri, 15 Apr 2022 19:18:22 +0300 Subject: [PATCH 036/245] sys/windows: add winmm bindings file --- core/sys/windows/winmm.odin | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 core/sys/windows/winmm.odin diff --git a/core/sys/windows/winmm.odin b/core/sys/windows/winmm.odin new file mode 100644 index 000000000..6d3fc409e --- /dev/null +++ b/core/sys/windows/winmm.odin @@ -0,0 +1,9 @@ +// +build windows +package sys_windows + +foreign import winmm "system:Winmm.lib" + +@(default_calling_convention="stdcall") +foreign winmm { + timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT --- +} From 1b4d5b73abf8d582e3493f0d52c91d0f0d3ec102 Mon Sep 17 00:00:00 2001 From: hikari Date: Fri, 15 Apr 2022 22:04:34 +0300 Subject: [PATCH 037/245] sys/windows: add some constants --- core/sys/windows/types.odin | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index f05dd3310..6bded29e1 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -786,6 +786,10 @@ HOVER_DEFAULT :: 0xFFFFFFFF USER_TIMER_MAXIMUM :: 0x7FFFFFFF USER_TIMER_MINIMUM :: 0x0000000A +// WM_ACTIVATE state values +WA_INACTIVE :: 0 +WA_ACTIVE :: 1 +WA_CLICKACTIVE :: 2 // SetWindowsHook() codes WH_MIN :: -1 From b05fbaacdaf8ffe37ad04f9d4439b06d8b538869 Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 00:32:17 +0300 Subject: [PATCH 038/245] time: add accurate sleep procedure --- core/time/time.odin | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/time/time.odin b/core/time/time.odin index fddb09d85..7056f83f8 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -213,6 +213,37 @@ time_add :: proc(t: Time, d: Duration) -> Time { return Time{t._nsec + i64(d)} } +// Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ +accurate_sleep :: proc(d: Duration) { + to_sleep, estimate, mean, m2, count: Duration + + to_sleep = d + estimate = 5 * Millisecond + mean = 5 * Millisecond + count = 1 + + for to_sleep > estimate { + start := tick_now() + sleep(1 * Millisecond) + + observed := tick_since(start) + to_sleep -= observed + + count += 1 + + delta := observed - mean + mean += delta / count + m2 += delta * (observed - mean) + stddev := intrinsics.sqrt(f64(m2) / f64(count - 1)) + estimate = mean + Duration(stddev) + } + + start := tick_now() + for to_sleep > tick_since(start) { + intrinsics.cpu_relax() // prevent the spinlock from taking the thread hostage, still accurate enough + // NOTE: it is possible that sometimes cpu can relax a bit too much, in that case it should spinlock freely for a while (TODO) + } +} ABSOLUTE_ZERO_YEAR :: i64(-292277022399) // Day is chosen so that 2001-01-01 is Monday in the calculations ABSOLUTE_TO_INTERNAL :: i64(-9223371966579724800) // i64((ABSOLUTE_ZERO_YEAR - 1) * 365.2425 * SECONDS_PER_DAY); From 44316401c915cd96a9c97a0747d7487bac905ac7 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 16 Apr 2022 02:07:57 +0200 Subject: [PATCH 039/245] Add uleb128 byte-at-a-time decoder. --- core/encoding/varint/leb128.odin | 54 +++++++++++------- .../encoding/varint/test_core_varint.odin | 2 +- tests/core/encoding/varint/varint | Bin 0 -> 308984 bytes 3 files changed, 34 insertions(+), 22 deletions(-) create mode 100755 tests/core/encoding/varint/varint diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin index 476b9c2c9..4cad1da76 100644 --- a/core/encoding/varint/leb128.odin +++ b/core/encoding/varint/leb128.odin @@ -10,8 +10,6 @@ // the LEB128 format as used by DWARF debug info, Android .dex and other file formats. package varint -import "core:fmt" - // In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file. // Instead we'll set limits on the values we'll encode/decode // 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`. @@ -25,32 +23,47 @@ Error :: enum { // Decode a slice of bytes encoding an unsigned LEB128 integer into value and number of bytes used. // Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. -decode_uleb128 :: proc(buf: []u8) -> (val: u128, size: int, err: Error) { - more := true +decode_uleb128_buffer :: proc(buf: []u8) -> (val: u128, size: int, err: Error) { + if len(buf) == 0 { + return 0, 0, .Buffer_Too_Small + } - for v, i in buf { - size = i + 1 - - // 18 * 7 bits = 126, which means that a possible 19th byte may at most be 0b0000_0011. - if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && v > 0b0000_0011 { - return 0, 0, .Value_Too_Large - } - - val |= u128(v & 0x7f) << uint(i * 7) - - if v < 128 { - more = false - break + for v in buf { + val, size, err = decode_uleb128_byte(v, size, val) + if err != .Buffer_Too_Small { + return } } - // If the buffer runs out before the number ends, return an error. - if more { - return 0, 0, .Buffer_Too_Small + if err == .Buffer_Too_Small { + val, size = 0, 0 } return } +// Decodes an unsigned LEB128 integer into value a byte at a time. +// Returns `.None` when decoded properly, `.Value_Too_Large` when they value +// exceeds the limits of a u128, and `.Buffer_Too_Small` when it's not yet fully decoded. +decode_uleb128_byte :: proc(input: u8, offset: int, accumulator: u128) -> (val: u128, size: int, err: Error) { + size = offset + 1 + + // 18 * 7 bits = 126, which means that a possible 19th byte may at most be 0b0000_0011. + if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0b0000_0011 { + return 0, 0, .Value_Too_Large + } + + val = accumulator | u128(input & 0x7f) << uint(offset * 7) + + if input < 128 { + // We're done + return + } + + // If the buffer runs out before the number ends, return an error. + return val, size, .Buffer_Too_Small +} +decode_uleb128 :: proc {decode_uleb128_buffer, decode_uleb128_byte} + // Decode a slice of bytes encoding a signed LEB128 integer into value and number of bytes used. // Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. decode_ileb128 :: proc(buf: []u8) -> (val: i128, size: int, err: Error) { @@ -89,7 +102,6 @@ encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) { size += 1 if size > len(buf) { - fmt.println(val, buf[:size - 1]) return 0, .Buffer_Too_Small } diff --git a/tests/core/encoding/varint/test_core_varint.odin b/tests/core/encoding/varint/test_core_varint.odin index 093b043d7..2c3669afa 100644 --- a/tests/core/encoding/varint/test_core_varint.odin +++ b/tests/core/encoding/varint/test_core_varint.odin @@ -51,7 +51,7 @@ test_leb128 :: proc(t: ^testing.T) { msg := fmt.tprintf("Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size) expect(t, size == vector.size && val == vector.value, msg) - msg = fmt.tprintf("Expected decoder to return error %v, got %v", vector.error, err) + msg = fmt.tprintf("Expected decoder to return error %v, got %v for vector %v", vector.error, err, vector) expect(t, err == vector.error, msg) if err == .None { // Try to roundtrip diff --git a/tests/core/encoding/varint/varint b/tests/core/encoding/varint/varint new file mode 100755 index 0000000000000000000000000000000000000000..1e982544582db7a8f719d5229759a019afa45103 GIT binary patch literal 308984 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�(1)x9! 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 literal 0 HcmV?d00001 From b9dc81d808af3cd4db69bca8cffc0f3bbb48ef8a Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 13:46:36 +0300 Subject: [PATCH 040/245] runtime: update comment description --- core/runtime/core.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 4ab21d8cf..4269450de 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -401,6 +401,7 @@ Raw_Cstring :: struct { Linux, Essence, FreeBSD, + OpenBSD, WASI, JS, Freestanding, From 0a0440a6e869e8d8791608f14fb55f37f323a23e Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 14:08:37 +0300 Subject: [PATCH 041/245] time: yield accurate_sleep instead of relaxing the cpu --- core/time/time.odin | 10 ++++++++-- core/time/time_unix.odin | 6 ++++++ core/time/time_windows.odin | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/time/time.odin b/core/time/time.odin index 7056f83f8..f2e974647 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -213,6 +213,10 @@ time_add :: proc(t: Time, d: Duration) -> Time { return Time{t._nsec + i64(d)} } +yield :: proc "contextless" () { + _yield() +} + // Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ accurate_sleep :: proc(d: Duration) { to_sleep, estimate, mean, m2, count: Duration @@ -240,8 +244,10 @@ accurate_sleep :: proc(d: Duration) { start := tick_now() for to_sleep > tick_since(start) { - intrinsics.cpu_relax() // prevent the spinlock from taking the thread hostage, still accurate enough - // NOTE: it is possible that sometimes cpu can relax a bit too much, in that case it should spinlock freely for a while (TODO) + // prevent the spinlock from taking the thread hostage, still accurate enough + yield() + // NOTE: it might be possible that it yields for too long, in that case it should spinlock freely for a while + // TODO: needs actual testing done to check if that's the case } } diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 37fc1fd3e..db15a824a 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,6 +1,8 @@ //+build linux, darwin, freebsd, openbsd package time +import "core:sys/unix" + IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. when ODIN_OS == .Darwin { @@ -17,6 +19,10 @@ foreign libc { @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 --- } +_yield :: proc "contextless" () { + unix.sched_yield() +} + TimeSpec :: struct { tv_sec : i64, /* seconds */ tv_nsec : i64, /* nanoseconds */ diff --git a/core/time/time_windows.odin b/core/time/time_windows.odin index 0fb9eaa0f..397741126 100644 --- a/core/time/time_windows.odin +++ b/core/time/time_windows.odin @@ -35,3 +35,7 @@ _tick_now :: proc "contextless" () -> Tick { _nsec := mul_div_u64(i64(now), 1e9, i64(qpc_frequency)) return Tick{_nsec = _nsec} } + +_yield :: proc "contextless" () { + win32.SwitchToThread() +} From 4f4793817cfb1782c1b2e6cf55ffdbfb01bcffaf Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 14:35:49 +0300 Subject: [PATCH 042/245] time: fix unix build --- core/time/time_unix.odin | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index db15a824a..0cfa196a2 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,8 +1,6 @@ //+build linux, darwin, freebsd, openbsd package time -import "core:sys/unix" - IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. when ODIN_OS == .Darwin { @@ -19,8 +17,18 @@ foreign libc { @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 --- } +foreign import "system:pthread" + +import "core:c" + +@(private="file") +@(default_calling_convention="c") +foreign pthread { + sched_yield :: proc() -> c.int --- +} + _yield :: proc "contextless" () { - unix.sched_yield() + sched_yield() } TimeSpec :: struct { From 8bf73950fa3bfaea940f8c14e69824b06908aa5e Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 16 Apr 2022 14:36:48 +0300 Subject: [PATCH 043/245] time: remove unnecessary yield --- core/time/time.odin | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/time/time.odin b/core/time/time.odin index f2e974647..ac233fbd2 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -213,10 +213,6 @@ time_add :: proc(t: Time, d: Duration) -> Time { return Time{t._nsec + i64(d)} } -yield :: proc "contextless" () { - _yield() -} - // Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ accurate_sleep :: proc(d: Duration) { to_sleep, estimate, mean, m2, count: Duration @@ -245,7 +241,7 @@ accurate_sleep :: proc(d: Duration) { start := tick_now() for to_sleep > tick_since(start) { // prevent the spinlock from taking the thread hostage, still accurate enough - yield() + _yield() // NOTE: it might be possible that it yields for too long, in that case it should spinlock freely for a while // TODO: needs actual testing done to check if that's the case } From 91037766d2b583ac34d23eee5a46f10df9d3cba0 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 16 Apr 2022 16:48:08 +0200 Subject: [PATCH 044/245] Update time.odin Add caveats. --- core/time/time.odin | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/time/time.odin b/core/time/time.odin index ac233fbd2..1f778a8de 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -214,12 +214,17 @@ time_add :: proc(t: Time, d: Duration) -> Time { } // Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ +// +// Accuracy seems to be pretty good out of the box on Linux, to within around 4µs worst case. +// On Windows it depends but is comparable with regular sleep in the worst case. +// To get the same kind of accuracy as on Linux, have your program call `win32.time_begin_period(1)` to +// tell Windows to use a more accurate timer for your process. accurate_sleep :: proc(d: Duration) { to_sleep, estimate, mean, m2, count: Duration to_sleep = d estimate = 5 * Millisecond - mean = 5 * Millisecond + mean = 5 * Millisecond count = 1 for to_sleep > estimate { From 6d0ba8d1898adabceafc6a181395f5d158176a04 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 16 Apr 2022 18:14:01 +0200 Subject: [PATCH 045/245] [LEB128] Add byte-at-a-time ILEB decoder. --- core/encoding/varint/leb128.odin | 44 +++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin index 4cad1da76..f8fcc7de5 100644 --- a/core/encoding/varint/leb128.odin +++ b/core/encoding/varint/leb128.odin @@ -66,33 +66,47 @@ decode_uleb128 :: proc {decode_uleb128_buffer, decode_uleb128_byte} // Decode a slice of bytes encoding a signed LEB128 integer into value and number of bytes used. // Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. -decode_ileb128 :: proc(buf: []u8) -> (val: i128, size: int, err: Error) { - shift: uint - +decode_ileb128_buffer :: proc(buf: []u8) -> (val: i128, size: int, err: Error) { if len(buf) == 0 { return 0, 0, .Buffer_Too_Small } for v in buf { - size += 1 - - // 18 * 7 bits = 126, which including sign means we can have a 19th byte. - if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && v > 0x7f { - return 0, 0, .Value_Too_Large + val, size, err = decode_ileb128_byte(v, size, val) + if err != .Buffer_Too_Small { + return } - - val |= i128(v & 0x7f) << shift - shift += 7 - - if v < 128 { break } } - if buf[size - 1] & 0x40 == 0x40 { - val |= max(i128) << shift + if err == .Buffer_Too_Small { + val, size = 0, 0 } return } +// Decode a a signed LEB128 integer into value and number of bytes used, one byte at a time. +// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. +decode_ileb128_byte :: proc(input: u8, offset: int, accumulator: i128) -> (val: i128, size: int, err: Error) { + size = offset + 1 + shift := uint(offset * 7) + + // 18 * 7 bits = 126, which including sign means we can have a 19th byte. + if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0x7f { + return 0, 0, .Value_Too_Large + } + + val = accumulator | i128(input & 0x7f) << shift + + if input < 128 { + if input & 0x40 == 0x40 { + val |= max(i128) << (shift + 7) + } + return val, size, .None + } + return val, size, .Buffer_Too_Small +} +decode_ileb128 :: proc{decode_ileb128_buffer, decode_ileb128_byte} + // Encode `val` into `buf` as an unsigned LEB128 encoded series of bytes. // `buf` must be appropriately sized. encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) { From 939973acd7a8ea17cc9dfda2a55e79dd0109a49c Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 17 Apr 2022 12:35:34 +0200 Subject: [PATCH 046/245] [QOI] Add to examples/all. --- examples/all/all_main.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 6a039e4dd..4f5bfbdc1 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -61,6 +61,7 @@ import hash "core:hash" import image "core:image" import png "core:image/png" +import qoi "core:image/qoi" import io "core:io" import log "core:log" @@ -159,6 +160,7 @@ _ :: fmt _ :: hash _ :: image _ :: png +_ :: qoi _ :: io _ :: log _ :: math From b78f3a806930fe026c027aedf511696bc6691b96 Mon Sep 17 00:00:00 2001 From: hikari Date: Sun, 17 Apr 2022 19:17:38 +0300 Subject: [PATCH 047/245] sys/windows: add timeEndPeriod --- core/sys/windows/winmm.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/sys/windows/winmm.odin b/core/sys/windows/winmm.odin index 6d3fc409e..9edd56acc 100644 --- a/core/sys/windows/winmm.odin +++ b/core/sys/windows/winmm.odin @@ -6,4 +6,5 @@ foreign import winmm "system:Winmm.lib" @(default_calling_convention="stdcall") foreign winmm { timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT --- + timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT --- } From 4247ba67ed83a16c321363cdf8260f71826325ca Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Mon, 18 Apr 2022 15:24:54 +0800 Subject: [PATCH 048/245] Fix bugs in core:container/lru --- core/container/lru/lru_cache.odin | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin index f8e6f7b46..81f0142b0 100644 --- a/core/container/lru/lru_cache.odin +++ b/core/container/lru/lru_cache.odin @@ -60,6 +60,8 @@ clear :: proc(c: ^$C/Cache($Key, $Value), call_on_remove: bool) { set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Allocator_Error { if e, ok := c.entries[key]; ok { e.value = value + _pop_node(c, e) + _push_front_node(c, e) return nil } @@ -67,10 +69,14 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc e.key = key e.value = value - _push_front_node(c, e) - if c.count > c.capacity { + assert(c.count <= c.capacity) + if c.count == c.capacity { _remove_node(c, c.tail) } + else { + c.count += 1 + } + _push_front_node(c, e) c.entries[key] = e return nil @@ -122,6 +128,7 @@ remove :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool { return false } _remove_node(c, e) + c.count -= 1 return true } @@ -143,8 +150,6 @@ _remove_node :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) { node.prev = nil node.next = nil - c.count -= 1 - delete_key(&c.entries, node.key) _call_on_remove(c, node) @@ -171,8 +176,6 @@ _push_front_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) { c.tail = e } e.prev = nil - - c.count += 1 } @(private) @@ -180,6 +183,12 @@ _pop_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) { if e == nil { return } + if c.head == e { + c.head = e.next + } + if c.tail == e { + c.tail = e.prev + } if e.prev != nil { e.prev.next = e.next } From 7428e5226426d1d19601d5b557c3df51db233857 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Thu, 14 Apr 2022 16:53:48 +0000 Subject: [PATCH 049/245] Duplicate some basic slice procedures from core:mem into core:slice --- core/slice/slice.odin | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 520e3e1e0..b8fb29ab3 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -10,6 +10,53 @@ _ :: builtin _ :: bits _ :: mem +/* + Turn a pointer and a length into a slice. +*/ +from_ptr :: proc "contextless" (ptr: ^$T, count: int) -> []T { + return ([^]T)(ptr)[:count] +} + +/* + Turn a pointer and a length into a byte slice. +*/ +bytes_from_ptr :: proc "contextless" (ptr: rawptr, byte_count: int) -> []byte { + return ([^]byte)(ptr)[:byte_count] +} + +/* + Turn a slice into a byte slice. + + See `slice.reinterpret` to go the other way. +*/ +to_bytes :: proc "contextless" (s: []$T) -> []byte { + return ([^]byte)(raw_data(s))[:len(s) * size_of(T)] +} + +/* + Turn a slice of one type, into a slice of another type. + + Only converts the type and length of the slice itself. + The length is rounded down to the nearest whole number of items. + + ``` + large_items := []i64{1, 2, 3, 4} + small_items := slice.reinterpret([]i32, large_items) + assert(len(small_items) == 8) + ``` + ``` + small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0} + large_items := slice.reinterpret([]i64, small_items) + assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes. + ``` +*/ +reinterpret :: proc "contextless" ($T: typeid/[]$U, s: []$V) -> []U { + bytes := to_bytes(s) + n := len(bytes) / size_of(U) + return ([^]U)(raw_data(bytes))[:n] +} + swap :: proc(array: $T/[]$E, a, b: int) { when size_of(E) > 8 { From df4a0c62add28af74ac8c926b3a6e0612296ccd1 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 18 Apr 2022 19:10:53 +0200 Subject: [PATCH 050/245] Delete accidentally added test artefact. --- tests/core/encoding/varint/varint | Bin 308984 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 tests/core/encoding/varint/varint diff --git a/tests/core/encoding/varint/varint b/tests/core/encoding/varint/varint deleted file mode 100755 index 1e982544582db7a8f719d5229759a019afa45103..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 308984 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�(1)x9! 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 From 8d370fabdd7925f1856a998063ef5de49f4efa2a Mon Sep 17 00:00:00 2001 From: WalterPlinge <22519813+WalterPlinge@users.noreply.github.com> Date: Mon, 18 Apr 2022 01:00:19 +0100 Subject: [PATCH 051/245] Added initial Netpbm image format support --- core/image/common.odin | 46 +++ core/image/netpbm/doc.odin | 32 ++ core/image/netpbm/helpers.odin | 26 ++ core/image/netpbm/netpbm.odin | 681 +++++++++++++++++++++++++++++++++ 4 files changed, 785 insertions(+) create mode 100644 core/image/netpbm/doc.odin create mode 100644 core/image/netpbm/helpers.odin create mode 100644 core/image/netpbm/netpbm.odin diff --git a/core/image/common.odin b/core/image/common.odin index 2e7bca17e..bf93e9313 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -57,6 +57,7 @@ Image :: struct { } Image_Metadata :: union { + ^Netpbm_Info, ^PNG_Info, ^QOI_Info, } @@ -152,6 +153,7 @@ Options :: distinct bit_set[Option] Error :: union #shared_nil { General_Image_Error, + Netpbm_Error, PNG_Error, QOI_Error, @@ -171,6 +173,50 @@ General_Image_Error :: enum { Invalid_Output, } +/* + Netpbm-specific definitions +*/ +Netpbm_Format :: enum { + P1, P2, P3, P4, P5, P6, P7, Pf, PF, +} + +Netpbm_Header :: struct { + format: Netpbm_Format, + width: int, + height: int, + channels: int, + depth: int, + maxval: int, + tupltype: string, + scale: f32, + little_endian: bool, +} + +Netpbm_Info :: struct { + header: Netpbm_Header, +} + +Netpbm_Error :: enum { + None = 0, + + // reading + File_Not_Readable, + Invalid_Signature, + Invalid_Header_Token_Character, + Incomplete_Header, + Invalid_Header_Value, + Duplicate_Header_Field, + Buffer_Too_Small, + Invalid_Buffer_ASCII_Token, + Invalid_Buffer_Value, + + // writing + File_Not_Writable, + Invalid_Format, + Invalid_Number_Of_Channels, + Invalid_Image_Depth, +} + /* PNG-specific definitions */ diff --git a/core/image/netpbm/doc.odin b/core/image/netpbm/doc.odin new file mode 100644 index 000000000..baeb99968 --- /dev/null +++ b/core/image/netpbm/doc.odin @@ -0,0 +1,32 @@ +/* +Formats: + PBM (P1, P4): Portable Bit Map, stores black and white images (1 channel) + PGM (P2, P5): Portable Gray Map, stores greyscale images (1 channel, 1 or 2 bytes per value) + PPM (P3, P6): Portable Pixel Map, stores colour images (3 channel, 1 or 2 bytes per value) + PAM (P7 ): Portable Arbitrary Map, stores arbitrary channel images (1 or 2 bytes per value) + PFM (Pf, PF): Portable Float Map, stores floating-point images (Pf: 1 channel, PF: 3 channel) + +Reading + All formats fill out header fields `format`, `width`, `height`, `channels`, `depth` + Specific formats use more fields + PGM, PPM, and PAM set `maxval` + PAM also sets `tupltype`, and is able to set `channels` to an arbitrary value + PFM sets `scale` and `little_endian` + Currently doesn't support reading multiple images from one binary-format file + +Writing + All formats require the header field `format` to be specified + Additional header fields are required for specific formats + PGM, PPM, and PAM require `maxval` + PAM also uses `tupltype`, though it may be left as default (empty or nil string) + PFM requires `scale` and `little_endian`, though the latter may be left untouched (default is false) + +Some syntax differences from the specifications: + `channels` stores what the PAM specification calls `depth` + `depth` instead stores how many bytes will fit `maxval` (should only be 1, 2, or 4) + `scale` and `little_endian` are separated, so the `header` will always store a positive `scale` + `little_endian` will only be true for a negative `scale` PFM, every other format will be false + `little_endian` only describes the netpbm data being read/written, the image buffer will be native +*/ + +package netpbm diff --git a/core/image/netpbm/helpers.odin b/core/image/netpbm/helpers.odin new file mode 100644 index 000000000..5a3000a87 --- /dev/null +++ b/core/image/netpbm/helpers.odin @@ -0,0 +1,26 @@ +package netpbm + +import "core:bytes" +import "core:image" + +destroy :: proc(img: ^image.Image) -> bool { + if img == nil do return false + + //! TEMP CAST + info, ok := img.metadata.(^image.Netpbm_Info) + if !ok do return false + + bytes.buffer_destroy(&img.pixels) + header_destroy(&info.header) + free(info) + img.metadata = nil + + return true +} + +header_destroy :: proc(using header: ^Header) { + if format == .P7 && tupltype != "" { + delete(tupltype) + tupltype = "" + } +} diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin new file mode 100644 index 000000000..fa8ffc1db --- /dev/null +++ b/core/image/netpbm/netpbm.odin @@ -0,0 +1,681 @@ +package netpbm + +import "core:bytes" +import "core:fmt" +import "core:image" +import "core:mem" +import "core:os" +import "core:strconv" +import "core:strings" +import "core:unicode" + + + +Image :: image.Image +Format :: image.Netpbm_Format +Header :: image.Netpbm_Header +Info :: image.Netpbm_Info +Error :: image.Error +Format_Error :: image.Netpbm_Error + + + +Formats :: bit_set[Format] +PBM :: Formats{.P1, .P4} +PGM :: Formats{.P2, .P5} +PPM :: Formats{.P3, .P6} +PNM :: PBM + PGM + PPM +PAM :: Formats{.P7} +PFM :: Formats{.Pf, .PF} +ASCII :: Formats{.P1, .P2, .P3} +BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM + + + +read :: proc { + read_from_file, + read_from_buffer, +} + +read_from_file :: proc(filename: string, allocator := context.allocator) -> (img: Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename); defer delete(data) + if !ok { + err = .File_Not_Readable + return + } + + return read_from_buffer(data) +} + +read_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { + context.allocator = allocator + + header: Header; defer header_destroy(&header) + header_size: int + header, header_size = parse_header(data) or_return + + img_data := data[header_size:] + img = decode_image(header, img_data) or_return + + info := new(Info) + info.header = header + if header.format == .P7 && header.tupltype != "" { + info.header.tupltype = strings.clone(header.tupltype) + } + img.metadata = info + + err = Format_Error.None + return +} + + + +write :: proc { + write_to_file, + write_to_buffer, +} + +write_to_file :: proc(filename: string, img: Image, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + data: []byte; defer delete(data) + data = write_to_buffer(img) or_return + + if ok := os.write_entire_file(filename, data); !ok { + return .File_Not_Writable + } + + return Format_Error.None +} + +write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: []byte, err: Error) { + context.allocator = allocator + + info, ok := img.metadata.(^image.Netpbm_Info) + if !ok { + err = image.General_Image_Error.Invalid_Input_Image + return + } + // using info so we can just talk about the header + using info + + //? validation + if header.format in (PBM + PGM + Formats{.Pf}) && img.channels != 1 \ + || header.format in (PPM + Formats{.PF}) && img.channels != 3 { + err = Format_Error.Invalid_Number_Of_Channels + return + } + + if header.format in (PNM + PAM) { + if header.maxval <= int(max(u8)) && img.depth != 1 \ + || header.maxval > int(max(u8)) && header.maxval <= int(max(u16)) && img.depth != 2 { + err = Format_Error.Invalid_Image_Depth + return + } + } else if header.format in PFM && img.depth != 4 { + err = Format_Error.Invalid_Image_Depth + return + } + + // we will write to a string builder + data: strings.Builder + strings.init_builder(&data) + + // all PNM headers start with the format + fmt.sbprintf(&data, "%s\n", header.format) + if header.format in PNM { + fmt.sbprintf(&data, "%i %i\n", img.width, img.height) + if header.format not_in PBM { + fmt.sbprintf(&data, "%i\n", header.maxval) + } + } else if header.format in PAM { + fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nTUPLTYPE %s\nENDHDR\n", + img.width, img.height, header.maxval, img.channels, header.tupltype) + } else if header.format in PFM { + scale := -header.scale if header.little_endian else header.scale + fmt.sbprintf(&data, "%i %i\n%f\n", img.width, img.height, scale) + } + + switch header.format { + // Compressed binary + case .P4: + header_buf := data.buf[:] + pixels := img.pixels.buf[:] + + p4_buffer_size := (img.width / 8 + 1) * img.height + reserve(&data.buf, len(header_buf) + p4_buffer_size) + + // we build up a byte value until it is completely filled + // or we reach the end the row + for y in 0 ..< img.height { + b: byte + + for x in 0 ..< img.width { + i := y * img.width + x + bit := byte(7 - (x % 8)) + v : byte = 0 if pixels[i] == 0 else 1 + b |= (v << bit) + + if bit == 0 { + append(&data.buf, b) + b = 0 + } + } + + if b != 0 { + append(&data.buf, b) + b = 0 + } + } + + // Simple binary + case .P5, .P6, .P7, .Pf, .PF: + header_buf := data.buf[:] + pixels := img.pixels.buf[:] + + resize(&data.buf, len(header_buf) + len(pixels)) + mem.copy(raw_data(data.buf[len(header_buf):]), raw_data(pixels), len(pixels)) + + // convert from native endianness + if img.depth == 2 { + pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):]) + for p in &pixels { + p = u16be(transmute(u16) p) + } + } else if header.format in PFM { + if header.little_endian { + pixels := mem.slice_data_cast([]f32le, data.buf[len(header_buf):]) + for p in &pixels { + p = f32le(transmute(f32) p) + } + } else { + pixels := mem.slice_data_cast([]f32be, data.buf[len(header_buf):]) + for p in &pixels { + p = f32be(transmute(f32) p) + } + } + } + + // If-it-looks-like-a-bitmap ASCII + case .P1: + pixels := img.pixels.buf[:] + for y in 0 ..< img.height { + for x in 0 ..< img.width { + i := y * img.width + x + append(&data.buf, '0' if pixels[i] == 0 else '1') + } + append(&data.buf, '\n') + } + + // Token ASCII + case .P2, .P3: + switch img.depth { + case 1: + pixels := img.pixels.buf[:] + for y in 0 ..< img.height { + for x in 0 ..< img.width { + i := y * img.width + x + for c in 0 ..< img.channels { + i := i * img.channels + c + fmt.sbprintf(&data, "%i ", pixels[i]) + } + fmt.sbprint(&data, "\n") + } + fmt.sbprint(&data, "\n") + } + + case 2: + pixels := mem.slice_data_cast([]u16, img.pixels.buf[:]) + for y in 0 ..< img.height { + for x in 0 ..< img.width { + i := y * img.width + x + for c in 0 ..< img.channels { + i := i * img.channels + c + fmt.sbprintf(&data, "%i ", pixels[i]) + } + fmt.sbprint(&data, "\n") + } + fmt.sbprint(&data, "\n") + } + + case: + return data.buf[:], Format_Error.Invalid_Image_Depth + } + + case: + return data.buf[:], Format_Error.Invalid_Format + } + + return data.buf[:], Format_Error.None +} + + + +parse_header :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) { + context.allocator = allocator + + // we need the signature and a space + if len(data) < 3 { + err = Format_Error.Incomplete_Header + return + } + + if data[0] == 'P' { + switch data[1] { + case '1' ..= '6': + return _parse_header_pnm(data) + case '7': + return _parse_header_pam(data, allocator) + case 'F', 'f': + return _parse_header_pfm(data) + } + } + + err = Format_Error.Invalid_Signature + return +} + +@(private) +_parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Error) { + SIG_LENGTH :: 2 + + { + header_formats := []Format{.P1, .P2, .P3, .P4, .P5, .P6} + header.format = header_formats[data[1] - '0' - 1] + } + + // have a list of fielda for easy iteration + header_fields: []^int + if header.format in PBM { + header_fields = {&header.width, &header.height} + header.maxval = 1 // we know maxval for a bitmap + } else { + header_fields = {&header.width, &header.height, &header.maxval} + } + + // we're keeping track of the header byte length + length = SIG_LENGTH + + // loop state + in_comment := false + already_in_space := true + current_field := 0 + current_value := header_fields[0] + + parse_loop: for d, i in data[SIG_LENGTH:] { + length += 1 + + // handle comments + if in_comment { + switch d { + // comments only go up to next carriage return or line feed + case '\r', '\n': + in_comment = false + } + continue + } else if d == '#' { + in_comment = true + continue + } + + // handle whitespace + in_space := unicode.is_white_space(rune(d)) + if in_space { + if already_in_space { + continue + } + already_in_space = true + + // switch to next value + current_field += 1 + if current_field == len(header_fields) { + // header byte length is 1-index so we'll increment again + length += 1 + break parse_loop + } + current_value = header_fields[current_field] + } else { + already_in_space = false + + if !unicode.is_digit(rune(d)) { + err = Format_Error.Invalid_Header_Token_Character + return + } + + val := int(d - '0') + current_value^ = current_value^ * 10 + val + } + } + + // set extra info + header.channels = 3 if header.format in PPM else 1 + header.depth = 2 if header.maxval > int(max(u8)) else 1 + + // limit checking + if current_field < len(header_fields) { + err = Format_Error.Incomplete_Header + return + } + + if header.width < 1 \ + || header.height < 1 \ + || header.maxval < 1 || header.maxval > int(max(u16)) { + err = Format_Error.Invalid_Header_Value + return + } + + err = Format_Error.None + return +} + +@(private) +_parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) { + context.allocator = allocator + + // the spec needs the newline apparently + if string(data[0:3]) != "P7\n" { + err = Format_Error.Invalid_Signature + return + } + header.format = .P7 + + SIGNATURE_LENGTH :: 3 + HEADER_END :: "ENDHDR\n" + + // we can already work out the size of the header + header_end_index := strings.index(string(data), HEADER_END) + if header_end_index == -1 { + err = Format_Error.Incomplete_Header + return + } + length = header_end_index + len(HEADER_END) + + // string buffer for the tupltype + tupltype: strings.Builder + strings.init_builder(&tupltype, context.temp_allocator); defer strings.destroy_builder(&tupltype) + fmt.sbprint(&tupltype, "") + + // PAM uses actual lines, so we can iterate easily + line_iterator := string(data[SIGNATURE_LENGTH : header_end_index]) + parse_loop: for line in strings.split_lines_iterator(&line_iterator) { + line := line + + if len(line) == 0 || line[0] == '#' { + continue + } + + field, ok := strings.fields_iterator(&line) + value := strings.trim_space(line) + + // the field will change, but the logic stays the same + current_field: ^int + + switch field { + case "WIDTH": current_field = &header.width + case "HEIGHT": current_field = &header.height + case "DEPTH": current_field = &header.channels + case "MAXVAL": current_field = &header.maxval + + case "TUPLTYPE": + if len(value) == 0 { + err = Format_Error.Invalid_Header_Value + return + } + + if len(tupltype.buf) == 0 { + fmt.sbprint(&tupltype, value) + } else { + fmt.sbprint(&tupltype, "", value) + } + + continue + + case: + continue + } + + if current_field^ != 0 { + err = Format_Error.Duplicate_Header_Field + return + } + current_field^, ok = strconv.parse_int(value) + if !ok { + err = Format_Error.Invalid_Header_Value + return + } + } + + // extra info + header.depth = 2 if header.maxval > int(max(u8)) else 1 + + // limit checking + if header.width < 1 \ + || header.height < 1 \ + || header.depth < 1 \ + || header.maxval < 1 \ + || header.maxval > int(max(u16)) { + err = Format_Error.Invalid_Header_Value + return + } + + header.tupltype = strings.clone(strings.to_string(tupltype)) + err = Format_Error.None + return +} + +@(private) +_parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Error) { + // we can just cycle through tokens for PFM + field_iterator := string(data) + field, ok := strings.fields_iterator(&field_iterator) + + switch field { + case "Pf": + header.format = .Pf + header.channels = 1 + case "PF": + header.format = .PF + header.channels = 3 + case: + err = Format_Error.Invalid_Signature + return + } + + // floating point + header.depth = 4 + + // width + field, ok = strings.fields_iterator(&field_iterator) + if !ok { + err = Format_Error.Incomplete_Header + return + } + header.width, ok = strconv.parse_int(field) + if !ok { + err = Format_Error.Invalid_Header_Value + return + } + + // height + field, ok = strings.fields_iterator(&field_iterator) + if !ok { + err = Format_Error.Incomplete_Header + return + } + header.height, ok = strconv.parse_int(field) + if !ok { + err = Format_Error.Invalid_Header_Value + return + } + + // scale (sign is endianness) + field, ok = strings.fields_iterator(&field_iterator) + if !ok { + err = Format_Error.Incomplete_Header + return + } + header.scale, ok = strconv.parse_f32(field) + if !ok { + err = Format_Error.Invalid_Header_Value + return + } + + if header.scale < 0.0 { + header.little_endian = true + header.scale = -header.scale + } + + // pointer math to get header size + length = int((uintptr(raw_data(field_iterator)) + 1) - uintptr(raw_data(data))) + + // limit checking + if header.width < 1 \ + || header.height < 1 \ + || header.scale == 0.0 { + err = Format_Error.Invalid_Header_Value + return + } + + err = Format_Error.None + return +} + + + +decode_image :: proc(header: Header, data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { + context.allocator = allocator + + img = Image { + width = header.width, + height = header.height, + channels = header.channels, + depth = header.depth, + } + + buffer_size := img.width * img.height * img.channels * img.depth + + // we can check data size for binary formats + if header.format in BINARY { + if header.format == .P4 { + p4_size := (img.width / 8 + 1) * img.height + if len(data) < p4_size { + err = Format_Error.Buffer_Too_Small + return + } + } else { + if len(data) < buffer_size { + err = Format_Error.Buffer_Too_Small + return + } + } + } + + // for ASCII and P4, we use length for the termination condition, so start at 0 + // BINARY will be a simple memcopy so the buffer length should also be initialised + if header.format in ASCII || header.format == .P4 { + bytes.buffer_init_allocator(&img.pixels, 0, buffer_size) + } else { + bytes.buffer_init_allocator(&img.pixels, buffer_size, buffer_size) + } + + switch header.format { + // Compressed binary + case .P4: + for d in data { + for b in 1 ..= 8 { + bit := byte(8 - b) + pix := (d >> bit) & 1 + bytes.buffer_write_byte(&img.pixels, pix) + if len(img.pixels.buf) % img.width == 0 { + break + } + } + + if len(img.pixels.buf) == cap(img.pixels.buf) { + break + } + } + + // Simple binary + case .P5, .P6, .P7, .Pf, .PF: + mem.copy(raw_data(img.pixels.buf), raw_data(data), buffer_size) + + // convert to native endianness + if header.format in PFM { + pixels := mem.slice_data_cast([]f32, img.pixels.buf[:]) + if header.little_endian { + for p in &pixels { + p = f32(transmute(f32le) p) + } + } else { + for p in &pixels { + p = f32(transmute(f32be) p) + } + } + } else { + if img.depth == 2 { + pixels := mem.slice_data_cast([]u16, img.pixels.buf[:]) + for p in &pixels { + p = u16(transmute(u16be) p) + } + } + } + + // If-it-looks-like-a-bitmap ASCII + case .P1: + for c in data { + switch c { + case '0', '1': + bytes.buffer_write_byte(&img.pixels, c - '0') + } + + if len(img.pixels.buf) == cap(img.pixels.buf) { + break + } + } + + if len(img.pixels.buf) < cap(img.pixels.buf) { + err = Format_Error.Buffer_Too_Small + return + } + + // Token ASCII + case .P2, .P3: + field_iterator := string(data) + for field in strings.fields_iterator(&field_iterator) { + value, ok := strconv.parse_int(field) + if !ok { + err = Format_Error.Invalid_Buffer_ASCII_Token + return + } + + //? do we want to enforce the maxval, the limit, or neither + if value > int(max(u16)) /*header.maxval*/ { + err = Format_Error.Invalid_Buffer_Value + return + } + + switch img.depth { + case 1: + bytes.buffer_write_byte(&img.pixels, u8(value)) + case 2: + vb := transmute([2]u8) u16(value) + bytes.buffer_write(&img.pixels, vb[:]) + } + + if len(img.pixels.buf) == cap(img.pixels.buf) { + break + } + } + + if len(img.pixels.buf) < cap(img.pixels.buf) { + err = Format_Error.Buffer_Too_Small + return + } + } + + err = Format_Error.None + return +} From b6abd691f487d4583df65e7127d05b3feaf9f181 Mon Sep 17 00:00:00 2001 From: WalterPlinge <22519813+WalterPlinge@users.noreply.github.com> Date: Mon, 18 Apr 2022 20:42:50 +0100 Subject: [PATCH 052/245] Image: Fix implicit enum error --- core/image/common.odin | 3 +-- core/image/netpbm/netpbm.odin | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/image/common.odin b/core/image/common.odin index bf93e9313..0ebeb5b72 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -167,6 +167,7 @@ Error :: union #shared_nil { General_Image_Error :: enum { None = 0, Invalid_Image_Dimensions, + Invalid_Number_Of_Channels, Image_Dimensions_Too_Large, Image_Does_Not_Adhere_to_Spec, Invalid_Input_Image, @@ -213,7 +214,6 @@ Netpbm_Error :: enum { // writing File_Not_Writable, Invalid_Format, - Invalid_Number_Of_Channels, Invalid_Image_Depth, } @@ -339,7 +339,6 @@ PNG_Interlace_Method :: enum u8 { QOI_Error :: enum { None = 0, Invalid_QOI_Signature, - Invalid_Number_Of_Channels, // QOI allows 3 or 4 channel data. Invalid_Bit_Depth, // QOI supports only 8-bit images, error only returned from writer. Invalid_Color_Space, // QOI allows 0 = sRGB or 1 = linear. Corrupt, // More data than pixels to decode into, for example. diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index fa8ffc1db..5c082e384 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -104,7 +104,7 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: //? validation if header.format in (PBM + PGM + Formats{.Pf}) && img.channels != 1 \ || header.format in (PPM + Formats{.PF}) && img.channels != 3 { - err = Format_Error.Invalid_Number_Of_Channels + err = .Invalid_Number_Of_Channels return } From fdd24f787fd6df5c1f3339d6317c76a1bafe60f5 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 18 Apr 2022 23:28:34 +0200 Subject: [PATCH 053/245] [image/tga] Writer for RGB(A) 8-bit images. --- core/image/common.odin | 14 ++++++ core/image/tga/tga.odin | 103 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 core/image/tga/tga.odin diff --git a/core/image/common.odin b/core/image/common.odin index 2e7bca17e..8c77ec48a 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -320,6 +320,20 @@ QOI_Info :: struct { header: QOI_Header, } +TGA_Header :: struct #packed { + id_length: u8, + color_map_type: u8, + data_type_code: u8, + color_map_origin: u16le, + color_map_length: u16le, + color_map_depth: u8, + origin: [2]u16le, + dimensions: [2]u16le, + bits_per_pixel: u8, + image_descriptor: u8, +} +#assert(size_of(TGA_Header) == 18) + // Function to help with image buffer calculations compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) { size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin new file mode 100644 index 000000000..3c860cb62 --- /dev/null +++ b/core/image/tga/tga.odin @@ -0,0 +1,103 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + + +// package tga implements a TGA image writer for 8-bit RGB and RGBA images. +package tga + +import "core:mem" +import "core:image" +import "core:compress" +import "core:bytes" +import "core:os" + +Error :: image.Error +General :: compress.General_Error +Image :: image.Image +Options :: image.Options + +RGB_Pixel :: image.RGB_Pixel +RGBA_Pixel :: image.RGBA_Pixel + +save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if img == nil { + return .Invalid_Input_Image + } + + if output == nil { + return .Invalid_Output + } + + pixels := img.width * img.height + if pixels == 0 || pixels > image.MAX_DIMENSIONS || img.width > 65535 || img.height > 65535 { + return .Invalid_Input_Image + } + + // Our TGA writer supports only 8-bit images with 3 or 4 channels. + if img.depth != 8 || img.channels < 3 || img.channels > 4 { + return .Invalid_Input_Image + } + + if img.channels * pixels != len(img.pixels.buf) { + return .Invalid_Input_Image + } + + written := 0 + + // Calculate and allocate necessary space. + necessary := pixels * img.channels + size_of(image.TGA_Header) + + if !resize(&output.buf, necessary) { + return General.Resize_Failed + } + + header := image.TGA_Header{ + data_type_code = 0x02, // Color, uncompressed. + dimensions = {u16le(img.width), u16le(img.height)}, + bits_per_pixel = u8(img.depth * img.channels), + image_descriptor = 1 << 5, // Origin is top left. + } + header_bytes := transmute([size_of(image.TGA_Header)]u8)header + + copy(output.buf[written:], header_bytes[:]) + written += size_of(image.TGA_Header) + + /* + Encode loop starts here. + */ + if img.channels == 3 { + pix := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, output.buf[written:]) + for p, i in pix { + out[i] = p.bgr + } + } else if img.channels == 4 { + pix := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, output.buf[written:]) + for p, i in pix { + out[i] = p.bgra + } + } + return nil +} + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else General.Cannot_Open_File +} + +save :: proc{save_to_memory, save_to_file} \ No newline at end of file From aa4eb35671c519c520bd25ff90837c1d70558c6b Mon Sep 17 00:00:00 2001 From: hikari Date: Tue, 19 Apr 2022 05:58:22 +0300 Subject: [PATCH 054/245] sys/windows: add some procedures --- core/sys/windows/kernel32.odin | 7 +++++++ core/sys/windows/user32.odin | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 735e065e2..cb90f71da 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -62,6 +62,13 @@ foreign kernel32 { GetCurrentProcessId :: proc() -> DWORD --- GetCurrentThread :: proc() -> HANDLE --- GetCurrentThreadId :: proc() -> DWORD --- + GetProcessTimes :: proc( + hProcess: HANDLE, + lpCreationTime: LPFILETIME, + lpExitTime: LPFILETIME, + lpKernelTime: LPFILETIME, + lpUserTime: LPFILETIME, + ) -> BOOL --- GetStdHandle :: proc(which: DWORD) -> HANDLE --- ExitProcess :: proc(uExitCode: c_uint) -> ! --- DeviceIoControl :: proc( diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 2316d3363..dd45df42a 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -60,6 +60,12 @@ foreign user32 { DestroyWindow :: proc(hWnd: HWND) -> BOOL --- ShowWindow :: proc(hWnd: HWND, nCmdShow: c_int) -> BOOL --- + BringWindowToTop :: proc(hWnd: HWND) -> BOOL --- + GetTopWindow :: proc(hWnd: HWND) -> HWND --- + SetForegroundWindow :: proc(hWnd: HWND) -> BOOL --- + GetForegroundWindow :: proc() -> HWND --- + SetActiveWindow :: proc(hWnd: HWND) -> HWND --- + GetActiveWindow :: proc() -> HWND --- GetMessageA :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- From ded8342f3fdb176d6c264057f3bdcb890bfcfad7 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Tue, 19 Apr 2022 20:46:33 +0800 Subject: [PATCH 055/245] Reduce allocations --- core/container/lru/lru_cache.odin | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin index 81f0142b0..b59f29f0c 100644 --- a/core/container/lru/lru_cache.odin +++ b/core/container/lru/lru_cache.odin @@ -65,20 +65,22 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc return nil } - e := new(Node(Key, Value), c.node_allocator) or_return - e.key = key - e.value = value - + e : ^Node(Key, Value) = nil assert(c.count <= c.capacity) if c.count == c.capacity { - _remove_node(c, c.tail) + e = c.tail + _remove_node(c, e) } else { c.count += 1 + e = new(Node(Key, Value), c.node_allocator) or_return } - _push_front_node(c, e) + e.key = key + e.value = value + _push_front_node(c, e) c.entries[key] = e + return nil } @@ -128,6 +130,7 @@ remove :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool { return false } _remove_node(c, e) + free(node, c.node_allocator) c.count -= 1 return true } @@ -153,9 +156,6 @@ _remove_node :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) { delete_key(&c.entries, node.key) _call_on_remove(c, node) - - free(node, c.node_allocator) - } @(private) From 7654afc2db9e88b1803862310698ca047bf10a01 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 19 Apr 2022 15:01:54 +0200 Subject: [PATCH 056/245] Revert "Update `mem.nil_allocator` to match the same in `runtime`" The change broke JSON unmarshaling. This reverts commit 4484a3433d6c58f1d1c594a4c36317f323cb5102. --- core/mem/allocators.odin | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 4954122ed..b8bd9a065 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -6,24 +6,7 @@ import "core:runtime" nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) { - switch mode { - case .Alloc: - return nil, .Out_Of_Memory - case .Free: - return nil, .None - case .Free_All: - return nil, .Mode_Not_Implemented - case .Resize: - if size == 0 { - return nil, .None - } - return nil, .Out_Of_Memory - case .Query_Features: - return nil, .Mode_Not_Implemented - case .Query_Info: - return nil, .Mode_Not_Implemented - } - return nil, .None + return nil, nil } nil_allocator :: proc() -> Allocator { From 323e7a2d02819ef0b7137abbdfee8a0d48f5cecb Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 19 Apr 2022 15:03:09 +0200 Subject: [PATCH 057/245] Add JSON unmarshal test. --- tests/core/encoding/json/test_core_json.odin | 253 +++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/tests/core/encoding/json/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin index 285cc04a1..c83710352 100644 --- a/tests/core/encoding/json/test_core_json.odin +++ b/tests/core/encoding/json/test_core_json.odin @@ -31,6 +31,7 @@ main :: proc() { parse_json(&t) marshal_json(&t) + unmarshal_json(&t) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) if TEST_fail > 0 { @@ -90,3 +91,255 @@ marshal_json :: proc(t: ^testing.T) { expect(t, err == nil, "expected json error to be none") } + +PRODUCTS := ` +{ + "cash": "0", + "products": [ + { + "name": "Cog Cola", + "cost": "3", + "owned": "1", + + "profit": "4", + "seconds": 3, + "multiplier": 1, + "auto_click": false + }, + { + "name": "gingerBeer", + "cost": "9", + "owned": "0", + + "profit": "16", + "seconds": 5, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Coffee", + "cost": "27", + "owned": "0", + + "profit": "64", + "seconds": 7, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Haggis", + "cost": "81", + "owned": "0", + + "profit": "256", + "seconds": 11, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Lasagna", + "cost": "243", + "owned": "0", + + "profit": "1024", + "seconds": 13, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Asparagus", + "cost": "729", + "owned": "0", + + "profit": "4096", + "seconds": 17, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Yorkshire Pudding", + "cost": "2187", + "owned": "0", + + "profit": "16384", + "seconds": 19, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Salmon Wrap", + "cost": "6561", + "owned": "0", + + "profit": "65536", + "seconds": 23, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Poke Bowl", + "cost": "19683", + "owned": "0", + + "profit": "262144", + "seconds": 29, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Chili Con Carne", + "cost": "59049", + "owned": "0", + + "profit": "1048576", + "seconds": 59, + "multiplier": 1, + "auto_click": false + }, + ], +} +` + +original_data := Game_Marshal{ + cash = "0", + products = { + { + name = "Cog Cola", + cost = "3", + owned = "1", + profit = "4", + seconds = 3, + multiplier = 1, + auto_click = false, + }, + { + name = "gingerBeer", + cost = "9", + owned = "0", + profit = "16", + seconds = 5, + multiplier = 1, + auto_click = false, + }, + { + name = "Coffee", + cost = "27", + owned = "0", + profit = "64", + seconds = 7, + multiplier = 1, + auto_click = false, + }, + { + name = "Haggis", + cost = "81", + owned = "0", + profit = "256", + seconds = 11, + multiplier = 1, + auto_click = false, + }, + { + name = "Lasagna", + cost = "243", + owned = "0", + profit = "1024", + seconds = 13, + multiplier = 1, + auto_click = false, + }, + { + name = "Asparagus", + cost = "729", + owned = "0", + profit = "4096", + seconds = 17, + multiplier = 1, + auto_click = false, + }, + { + name = "Yorkshire Pudding", + cost = "2187", + owned = "0", + profit = "16384", + seconds = 19, + multiplier = 1, + auto_click = false, + }, + { + name = "Salmon Wrap", + cost = "6561", + owned = "0", + profit = "65536", + seconds = 23, + multiplier = 1, + auto_click = false, + }, + { + name = "Poke Bowl", + cost = "19683", + owned = "0", + profit = "262144", + seconds = 29, + multiplier = 1, + auto_click = false, + }, + { + name = "Chili Con Carne", + cost = "59049", + owned = "0", + profit = "1048576", + seconds = 59, + multiplier = 1, + auto_click = false, + }, + }, +} + +Product_Marshal :: struct { + name: cstring, + owned: string, + + cost: string, + + profit: string, + seconds: int, + multiplier: int, + + auto_click: bool, +} + +Game_Marshal :: struct { + cash: string, + products: []Product_Marshal, +} + +cleanup :: proc(g: Game_Marshal) { + for p in g.products { + delete(p.name) + delete(p.owned) + delete(p.cost) + delete(p.profit) + } + delete(g.products) + delete(g.cash) +} + +@test +unmarshal_json :: proc(t: ^testing.T) { + g: Game_Marshal + err := json.unmarshal(transmute([]u8)PRODUCTS, &g, json.DEFAULT_SPECIFICATION) + defer cleanup(g) + + expect(t, err == nil, "Expected json error to be nil") + + msg := fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products)) + expect(t, len(g.products) == len(original_data.products), msg) + + msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash) + expect(t, original_data.cash == g.cash, "Cash unmarshaled improperly") + + for p, i in g.products { + expect(t, p == original_data.products[i], "Producted unmarshaled improperly") + } +} \ No newline at end of file From 581255bf23af90b77bb2b6e2671b40e2b565754e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 19 Apr 2022 20:04:38 +0200 Subject: [PATCH 058/245] Fix unmarshal for escaped strings. --- core/encoding/json/parser.odin | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index c682ec9bd..0b9a1cf33 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -281,6 +281,11 @@ parse_object :: proc(p: ^Parser) -> (value: Value, err: Error) { // IMPORTANT NOTE(bill): unquote_string assumes a mostly valid string unquote_string :: proc(token: Token, spec: Specification, allocator := context.allocator) -> (value: string, err: Error) { + if allocator.data == nil { + // We were called from `unmarshal_count_array`, return early. + return "", nil + } + get_u2_rune :: proc(s: string) -> rune { if len(s) < 4 || s[0] != '\\' || s[1] != 'x' { return -1 From 29b2c0476698d0f4b240e87945cfa278da82b57a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 19 Apr 2022 20:11:02 +0200 Subject: [PATCH 059/245] Revert "Fix unmarshal for escaped strings." This reverts commit 581255bf23af90b77bb2b6e2671b40e2b565754e. --- core/encoding/json/parser.odin | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index 0b9a1cf33..c682ec9bd 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -281,11 +281,6 @@ parse_object :: proc(p: ^Parser) -> (value: Value, err: Error) { // IMPORTANT NOTE(bill): unquote_string assumes a mostly valid string unquote_string :: proc(token: Token, spec: Specification, allocator := context.allocator) -> (value: string, err: Error) { - if allocator.data == nil { - // We were called from `unmarshal_count_array`, return early. - return "", nil - } - get_u2_rune :: proc(s: string) -> rune { if len(s) < 4 || s[0] != '\\' || s[1] != 'x' { return -1 From a30b9b17b3a91bc856a037c1e1025e389a8524b3 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 19 Apr 2022 20:32:22 +0200 Subject: [PATCH 060/245] [json/unmarshal] Fix quoted strings. --- core/encoding/json/parser.odin | 6 ++++++ tests/core/encoding/json/test_core_json.odin | 20 +++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index c682ec9bd..7bf88c565 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -354,6 +354,12 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a b := bytes_make(len(s) + 2*utf8.UTF_MAX, 1, allocator) or_return w := copy(b, s[0:i]) + + if len(b) == 0 && allocator.data == nil { + // `unmarshal_count_array` calls us with a nil allocator + return string(b[:w]), nil + } + loop: for i < len(s) { c := s[i] switch { diff --git a/tests/core/encoding/json/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin index c83710352..0e6a6412f 100644 --- a/tests/core/encoding/json/test_core_json.odin +++ b/tests/core/encoding/json/test_core_json.odin @@ -71,7 +71,8 @@ parse_json :: proc(t: ^testing.T) { _, err := json.parse(transmute([]u8)json_data) - expect(t, err == .None, "expected json error to be none") + msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err) + expect(t, err == nil, msg) } @test @@ -88,8 +89,8 @@ marshal_json :: proc(t: ^testing.T) { } _, err := json.marshal(my_struct) - - expect(t, err == nil, "expected json error to be none") + msg := fmt.tprintf("Expected `json.marshal` to return nil, got %v", err) + expect(t, err == nil, msg) } PRODUCTS := ` @@ -97,7 +98,7 @@ PRODUCTS := ` "cash": "0", "products": [ { - "name": "Cog Cola", + "name": "Cog\nCola", "cost": "3", "owned": "1", @@ -204,7 +205,7 @@ original_data := Game_Marshal{ cash = "0", products = { { - name = "Cog Cola", + name = "Cog\nCola", cost = "3", owned = "1", profit = "4", @@ -331,13 +332,14 @@ unmarshal_json :: proc(t: ^testing.T) { err := json.unmarshal(transmute([]u8)PRODUCTS, &g, json.DEFAULT_SPECIFICATION) defer cleanup(g) - expect(t, err == nil, "Expected json error to be nil") + msg := fmt.tprintf("Expected `json.unmarshal` to return nil, got %v", err) + expect(t, err == nil, msg) - msg := fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products)) + msg = fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products)) expect(t, len(g.products) == len(original_data.products), msg) - msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash) - expect(t, original_data.cash == g.cash, "Cash unmarshaled improperly") + msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash) + expect(t, original_data.cash == g.cash, msg) for p, i in g.products { expect(t, p == original_data.products[i], "Producted unmarshaled improperly") From eee97f7f62bbd65dd03ea3ec8668fef3fcfc685c Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 21 Apr 2022 20:49:32 +0300 Subject: [PATCH 061/245] strings: add levenshtein_distance procedure --- core/strings/strings.odin | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 8e774b367..87bbb42cf 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1809,3 +1809,62 @@ fields_iterator :: proc(s: ^string) -> (field: string, ok: bool) { s^ = s[len(s):] return } + +// `levenshtein_distance` returns the Levenshtein edit distance between 2 strings. +// This is a single-row-version of the Wagner–Fischer algorithm, based on C code by Martin Ettl. +// Note: allocator isn't used if the length of string b in runes is smaller than 70. +levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> int { + LEVENSHTEIN_DEFAULT_COSTS: []int : { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + } + + m, n := utf8.rune_count_in_string(a), utf8.rune_count_in_string(b) + + if m == 0 do return n + if n == 0 do return m + + costs: []int + + if n + 1 > len(LEVENSHTEIN_DEFAULT_COSTS) { + costs = make([]int, n + 1, allocator) + } else { + costs = LEVENSHTEIN_DEFAULT_COSTS + } + + defer if n + 1 > len(LEVENSHTEIN_DEFAULT_COSTS) { + delete(costs, allocator) + } + + for k in 0..=n { + costs[k] = k + } + + i: int + for c1 in a { + costs[0] = i + 1 + corner := i + j: int + for c2 in b { + upper := costs[j + 1] + if c1 == c2 { + costs[j + 1] = corner + } else { + t := upper if upper < corner else corner + costs[j + 1] = (costs[j] if costs[j] < t else t) + 1 + } + + corner = upper + j += 1 + } + + i += 1 + } + + return costs[n] +} From 591732f347c094e706471994996fcffa44687e89 Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 21 Apr 2022 20:58:50 +0300 Subject: [PATCH 062/245] strings: levenshtein_distance: remove costs calculation for default array --- core/strings/strings.odin | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 87bbb42cf..3b33a5dc8 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1833,6 +1833,9 @@ levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> in if n + 1 > len(LEVENSHTEIN_DEFAULT_COSTS) { costs = make([]int, n + 1, allocator) + for k in 0..=n { + costs[k] = k + } } else { costs = LEVENSHTEIN_DEFAULT_COSTS } @@ -1841,10 +1844,6 @@ levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> in delete(costs, allocator) } - for k in 0..=n { - costs[k] = k - } - i: int for c1 in a { costs[0] = i + 1 From d8f0da164b92f52eda045d77e5f6abb5c5146f2a Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 21 Apr 2022 21:15:11 +0300 Subject: [PATCH 063/245] strings: levenshtein_distance: improve potential caching --- core/strings/strings.odin | 43 ++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 3b33a5dc8..f876aab3d 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -15,7 +15,7 @@ clone :: proc(s: string, allocator := context.allocator, loc := #caller_location } // returns a clone of the string `s` allocated using the `allocator` as a cstring -// a nul byte is appended to the clone, to make the cstring safe +// a nul byte is appended to the clone, to make the cstring safe clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> cstring { c := make([]byte, len(s)+1, allocator, loc) copy(c, s) @@ -37,7 +37,7 @@ string_from_nul_terminated_ptr :: proc(ptr: ^byte, len: int) -> string { return s } -// returns the raw ^byte start of the string `str` +// returns the raw ^byte start of the string `str` ptr_from_string :: proc(str: string) -> ^byte { d := transmute(mem.Raw_String)str return d.data @@ -969,7 +969,7 @@ count :: proc(s, substr: string) -> int { repeats the string `s` multiple `count` times and returns the allocated string panics when `count` is below 0 - strings.repeat("abc", 2) -> "abcabc" + strings.repeat("abc", 2) -> "abcabc" */ repeat :: proc(s: string, count: int, allocator := context.allocator) -> string { if count < 0 { @@ -1378,7 +1378,7 @@ split_multi :: proc(s: string, substrs: []string, allocator := context.allocator // skip when no results if substrings_found < 1 { - return + return } buf = make([]string, substrings_found + 1, allocator) @@ -1812,16 +1812,35 @@ fields_iterator :: proc(s: ^string) -> (field: string, ok: bool) { // `levenshtein_distance` returns the Levenshtein edit distance between 2 strings. // This is a single-row-version of the Wagner–Fischer algorithm, based on C code by Martin Ettl. -// Note: allocator isn't used if the length of string b in runes is smaller than 70. +// Note: allocator isn't used if the length of string b in runes is smaller than 256. levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> int { LEVENSHTEIN_DEFAULT_COSTS: []int : { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, } m, n := utf8.rune_count_in_string(a), utf8.rune_count_in_string(b) From 71b1cce517e421fd7eeff4d5ac15e5165dd318c0 Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 21 Apr 2022 21:19:11 +0300 Subject: [PATCH 064/245] strings: levenshtein_distance: 64 is actually faster than 256 --- core/strings/strings.odin | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index f876aab3d..6e01f5c8a 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1812,7 +1812,7 @@ fields_iterator :: proc(s: ^string) -> (field: string, ok: bool) { // `levenshtein_distance` returns the Levenshtein edit distance between 2 strings. // This is a single-row-version of the Wagner–Fischer algorithm, based on C code by Martin Ettl. -// Note: allocator isn't used if the length of string b in runes is smaller than 256. +// Note: allocator isn't used if the length of string b in runes is smaller than 64. levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> int { LEVENSHTEIN_DEFAULT_COSTS: []int : { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, @@ -1821,26 +1821,7 @@ levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> in 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, + 60, 61, 62, 63, } m, n := utf8.rune_count_in_string(a), utf8.rune_count_in_string(b) From f0267536929c5909a8098baf95cb5eb1a4fa6522 Mon Sep 17 00:00:00 2001 From: hikari Date: Thu, 21 Apr 2022 21:19:43 +0300 Subject: [PATCH 065/245] strings: levenshtein_distance: remove `do` --- core/strings/strings.odin | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 6e01f5c8a..a3d9fa93e 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1826,8 +1826,12 @@ levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> in m, n := utf8.rune_count_in_string(a), utf8.rune_count_in_string(b) - if m == 0 do return n - if n == 0 do return m + if m == 0 { + return n + } + if n == 0 { + return m + } costs: []int From e799476f90537ca173205a64da1fbf87b894b42e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 22 Apr 2022 16:55:47 +0200 Subject: [PATCH 066/245] [compress/shoco] Add short string compressor. --- core/compress/shoco/model.odin | 148 +++++++++ core/compress/shoco/shoco.odin | 318 ++++++++++++++++++++ examples/all/all_main.odin | 2 + tests/core/assets/Shoco/LICENSE | 26 ++ tests/core/assets/Shoco/LICENSE.shoco | Bin 0 -> 1269 bytes tests/core/assets/Shoco/README.md | 95 ++++++ tests/core/assets/Shoco/README.md.shoco | Bin 0 -> 2227 bytes tests/core/compress/test_core_compress.odin | 57 +++- 8 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 core/compress/shoco/model.odin create mode 100644 core/compress/shoco/shoco.odin create mode 100644 tests/core/assets/Shoco/LICENSE create mode 100644 tests/core/assets/Shoco/LICENSE.shoco create mode 100644 tests/core/assets/Shoco/README.md create mode 100644 tests/core/assets/Shoco/README.md.shoco diff --git a/core/compress/shoco/model.odin b/core/compress/shoco/model.odin new file mode 100644 index 000000000..49e3dd97e --- /dev/null +++ b/core/compress/shoco/model.odin @@ -0,0 +1,148 @@ +/* + This file was generated, so don't edit this by hand. + Transliterated from https://github.com/Ed-von-Schleck/shoco/blob/master/shoco_model.h, + which is an English word model. +*/ + +// package shoco is an implementation of the shoco short string compressor +package shoco + +DEFAULT_MODEL :: Shoco_Model { + min_char = 39, + max_char = 122, + characters_by_id = { + 'e', 'a', 'i', 'o', 't', 'h', 'n', 'r', 's', 'l', 'u', 'c', 'w', 'm', 'd', 'b', 'p', 'f', 'g', 'v', 'y', 'k', '-', 'H', 'M', 'T', '\'', 'B', 'x', 'I', 'W', 'L', + }, + ids_by_character = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, 23, 29, -1, -1, 31, 24, -1, -1, -1, -1, -1, -1, 25, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 15, 11, 14, 0, 17, 18, 5, 2, -1, 21, 9, 13, 6, 3, 16, -1, 7, 8, 4, 10, 19, 12, 28, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + successors_by_bigram = { + {7, 4, 12, -1, 6, -1, 1, 0, 3, 5, -1, 9, -1, 8, 2, -1, 15, 14, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1}, + {-1, -1, 6, -1, 1, -1, 0, 3, 2, 4, 15, 11, -1, 9, 5, 10, 13, -1, 12, 8, 7, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 11, -1, 4, 2, -1, 0, 8, 1, 5, -1, 6, -1, 3, 7, 15, -1, 12, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, 14, 7, 5, -1, 1, 2, 8, 9, 0, 15, 6, 4, 11, -1, 12, 3, -1, 10, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 4, 3, 1, 5, 0, -1, 6, 10, 9, 7, 12, 11, -1, -1, -1, -1, 13, -1, -1, 8, -1, 15, -1, -1, -1, 14, -1, -1, -1, -1, -1}, + {0, 1, 2, 3, 4, -1, -1, 5, 9, 10, 6, -1, -1, 8, 15, 11, -1, 14, -1, -1, 7, -1, 13, -1, -1, -1, 12, -1, -1, -1, -1, -1}, + {2, 8, 7, 4, 3, -1, 9, -1, 6, 11, -1, 5, -1, -1, 0, -1, -1, 14, 1, 15, 10, 12, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1}, + {0, 3, 1, 2, 6, -1, 9, 8, 4, 12, 13, 10, -1, 11, 7, -1, -1, 15, 14, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 6, 3, 4, 1, 2, -1, -1, 5, 10, 7, 9, 11, 12, -1, -1, 8, 14, -1, -1, 15, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 6, 2, 5, 9, -1, -1, -1, 10, 1, 8, -1, 12, 14, 4, -1, 15, 7, -1, 13, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 10, 9, 15, 1, -1, 4, 0, 3, 2, -1, 6, -1, 12, 11, 13, 7, 14, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 6, 0, 4, 2, -1, 7, 13, 8, 9, 11, -1, -1, 15, -1, -1, -1, -1, -1, 10, 5, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 1, 4, -1, 2, 5, 6, 7, 8, -1, 14, -1, -1, 9, 15, -1, 12, -1, -1, -1, 10, 11, -1, -1, -1, 13, -1, -1, -1, -1, -1}, + {0, 1, 3, 2, 15, -1, 12, -1, 7, 14, 4, -1, -1, 9, -1, 8, 5, 10, -1, -1, 6, -1, 13, -1, -1, -1, 11, -1, -1, -1, -1, -1}, + {0, 3, 1, 2, -1, -1, 12, 6, 4, 9, 7, -1, -1, 14, 8, -1, -1, 15, 11, 13, 5, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 7, 2, 10, 13, -1, 6, 8, 1, 3, -1, -1, 14, 15, 11, -1, -1, -1, 12, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 2, 6, 3, 7, 10, -1, 1, 9, 4, 8, -1, -1, 15, -1, 12, 5, -1, -1, -1, 11, -1, 13, -1, -1, -1, 14, -1, -1, -1, -1, -1}, + {1, 3, 4, 0, 7, -1, 12, 2, 11, 8, 6, 13, -1, -1, -1, -1, -1, 5, -1, -1, 10, 15, 9, -1, -1, -1, 14, -1, -1, -1, -1, -1}, + {1, 3, 5, 2, 13, 0, 9, 4, 7, 6, 8, -1, -1, 15, -1, 11, -1, -1, 10, -1, 14, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 2, 1, 3, -1, -1, -1, 6, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 4, 0, 3, -1, 13, 12, 2, 7, -1, -1, 15, 10, 5, 8, 14, -1, -1, -1, -1, -1, 9, -1, -1, -1, 6, -1, -1, -1, -1, -1}, + {0, 9, 2, 14, 15, 4, 1, 13, 3, 5, -1, -1, 10, -1, -1, -1, -1, 6, 12, -1, 7, -1, 8, -1, -1, -1, 11, -1, -1, -1, -1, -1}, + {-1, 2, 14, -1, 1, 5, 8, 7, 4, 12, -1, 6, 9, 11, 13, 3, 10, 15, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 3, 2, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 1, 5, -1, -1, -1, 0, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 8, 4, 1, -1, 0, -1, 6, -1, -1, 5, -1, 7, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1}, + {12, 5, -1, -1, 1, -1, -1, 7, 0, 3, -1, 2, -1, 4, 6, -1, -1, -1, -1, 8, -1, -1, 15, -1, 13, 9, -1, -1, -1, -1, -1, 11}, + {1, 3, 2, 4, -1, -1, -1, 5, -1, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1}, + {5, 3, 4, 12, 1, 6, -1, -1, -1, -1, 8, 2, -1, -1, -1, -1, 0, 9, -1, -1, 11, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, 0, -1, 1, 12, 3, -1, -1, -1, -1, 5, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 6, -1, 10}, + {2, 3, 1, 4, -1, 0, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1}, + {5, 1, 3, 0, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 9, -1, -1, 6, -1, 7}, + }, + successors_reversed = { + {'s', 't', 'c', 'l', 'm', 'a', 'd', 'r', 'v', 'T', 'A', 'L', 'e', 'M', 'Y', '-'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'-', 't', 'a', 'b', 's', 'h', 'c', 'r', 'n', 'w', 'p', 'm', 'l', 'd', 'i', 'f'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'u', 'e', 'i', 'a', 'o', 'r', 'y', 'l', 'I', 'E', 'R', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'e', 'a', 'o', 'i', 'u', 'A', 'y', 'E', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'t', 'n', 'f', 's', '\'', 'm', 'I', 'N', 'A', 'E', 'L', 'Z', 'r', 'V', 'R', 'C'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'o', 'a', 'y', 'i', 'u', 'e', 'I', 'L', 'D', '\'', 'E', 'Y', '\x00', '\x00', '\x00', '\x00'}, + {'r', 'i', 'y', 'a', 'e', 'o', 'u', 'Y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'h', 'o', 'e', 'E', 'i', 'u', 'r', 'w', 'a', 'H', 'y', 'R', 'Z', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'h', 'i', 'e', 'a', 'o', 'r', 'I', 'y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'n', 't', 's', 'r', 'l', 'd', 'i', 'y', 'v', 'm', 'b', 'c', 'g', 'p', 'k', 'u'}, + {'e', 'l', 'o', 'u', 'y', 'a', 'r', 'i', 's', 'j', 't', 'b', 'v', 'h', 'm', 'd'}, + {'o', 'e', 'h', 'a', 't', 'k', 'i', 'r', 'l', 'u', 'y', 'c', 'q', 's', '-', 'd'}, + {'e', 'i', 'o', 'a', 's', 'y', 'r', 'u', 'd', 'l', '-', 'g', 'n', 'v', 'm', 'f'}, + {'r', 'n', 'd', 's', 'a', 'l', 't', 'e', 'm', 'c', 'v', 'y', 'i', 'x', 'f', 'p'}, + {'o', 'e', 'r', 'a', 'i', 'f', 'u', 't', 'l', '-', 'y', 's', 'n', 'c', '\'', 'k'}, + {'h', 'e', 'o', 'a', 'r', 'i', 'l', 's', 'u', 'n', 'g', 'b', '-', 't', 'y', 'm'}, + {'e', 'a', 'i', 'o', 't', 'r', 'u', 'y', 'm', 's', 'l', 'b', '\'', '-', 'f', 'd'}, + {'n', 's', 't', 'm', 'o', 'l', 'c', 'd', 'r', 'e', 'g', 'a', 'f', 'v', 'z', 'b'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'e', 'n', 'i', 's', 'h', 'l', 'f', 'y', '-', 'a', 'w', '\'', 'g', 'r', 'o', 't'}, + {'e', 'l', 'i', 'y', 'd', 'o', 'a', 'f', 'u', 't', 's', 'k', 'w', 'v', 'm', 'p'}, + {'e', 'a', 'o', 'i', 'u', 'p', 'y', 's', 'b', 'm', 'f', '\'', 'n', '-', 'l', 't'}, + {'d', 'g', 'e', 't', 'o', 'c', 's', 'i', 'a', 'n', 'y', 'l', 'k', '\'', 'f', 'v'}, + {'u', 'n', 'r', 'f', 'm', 't', 'w', 'o', 's', 'l', 'v', 'd', 'p', 'k', 'i', 'c'}, + {'e', 'r', 'a', 'o', 'l', 'p', 'i', 't', 'u', 's', 'h', 'y', 'b', '-', '\'', 'm'}, + {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'e', 'i', 'o', 'a', 's', 'y', 't', 'd', 'r', 'n', 'c', 'm', 'l', 'u', 'g', 'f'}, + {'e', 't', 'h', 'i', 'o', 's', 'a', 'u', 'p', 'c', 'l', 'w', 'm', 'k', 'f', 'y'}, + {'h', 'o', 'e', 'i', 'a', 't', 'r', 'u', 'y', 'l', 's', 'w', 'c', 'f', '\'', '-'}, + {'r', 't', 'l', 's', 'n', 'g', 'c', 'p', 'e', 'i', 'a', 'd', 'm', 'b', 'f', 'o'}, + {'e', 'i', 'a', 'o', 'y', 'u', 'r', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, + {'a', 'i', 'h', 'e', 'o', 'n', 'r', 's', 'l', 'd', 'k', '-', 'f', '\'', 'c', 'b'}, + {'p', 't', 'c', 'a', 'i', 'e', 'h', 'q', 'u', 'f', '-', 'y', 'o', '\x00', '\x00', '\x00'}, + {'o', 'e', 's', 't', 'i', 'd', '\'', 'l', 'b', '-', 'm', 'a', 'r', 'n', 'p', 'w'}, + }, + + character_count = 32, + successor_count = 16, + + max_successor_n = 7, + packs = { + { 0x80000000, 1, 2, { 26, 24, 24, 24, 24, 24, 24, 24 }, { 15, 3, 0, 0, 0, 0, 0, 0 }, 0xc0, 0x80 }, + { 0xc0000000, 2, 4, { 25, 22, 19, 16, 16, 16, 16, 16 }, { 15, 7, 7, 7, 0, 0, 0, 0 }, 0xe0, 0xc0 }, + { 0xe0000000, 4, 8, { 23, 19, 15, 11, 8, 5, 2, 0 }, { 31, 15, 15, 15, 7, 7, 7, 3 }, 0xf0, 0xe0 }, + }, +} \ No newline at end of file diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin new file mode 100644 index 000000000..9c5008f5d --- /dev/null +++ b/core/compress/shoco/shoco.odin @@ -0,0 +1,318 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. + + An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm. +*/ + +// package shoco is an implementation of the shoco short string compressor +package shoco + +import "core:intrinsics" +import "core:compress" + +Shoco_Pack :: struct { + word: u32, + bytes_packed: i8, + bytes_unpacked: i8, + offsets: [8]u16, + masks: [8]i16, + header_mask: u8, + header: u8, +} + +Shoco_Model :: struct { + min_char: u8, + max_char: u8, + characters_by_id: []u8, + ids_by_character: [256]i16, + successors_by_bigram: [][]i8, + successors_reversed: [][]u8, + + character_count: u8, + successor_count: u8, + max_successor_n: i8, + packs: []Shoco_Pack, +} + +compress_bound :: proc(uncompressed_size: int) -> (worst_case_compressed_size: int) { + // Worst case compression happens when input is non-ASCII (128-255) + // Encoded as 0x00 + the byte in question. + return uncompressed_size * 2 +} + +decompress_bound :: proc(compressed_size: int, model := DEFAULT_MODEL) -> (maximum_decompressed_size: int) { + // Best case compression is 2:1 + most: f64 + for pack in model.packs { + val := f64(compressed_size) / f64(pack.bytes_packed) * f64(pack.bytes_unpacked) + most = max(most, val) + } + return int(most) +} + +find_best_encoding :: proc(indices: []i16, n_consecutive: i8, model := DEFAULT_MODEL) -> (res: int) { + for p := len(model.packs); p > 0; p -= 1 { + pack := model.packs[p - 1] + if n_consecutive >= pack.bytes_unpacked { + have_index := true + for i := 0; i < int(pack.bytes_unpacked); i += 1 { + if indices[i] > pack.masks[i] { + have_index = false + break + } + } + if have_index { + return p - 1 + } + } + } + return -1 +} + +validate_model :: proc(model: Shoco_Model) -> (int, compress.Error) { + if len(model.successors_reversed) != int(model.max_char - model.min_char) { + return 0, .Unknown_Compression_Method + } + + if len(model.characters_by_id) != int(model.character_count) { + return 0, .Unknown_Compression_Method + } + + if len(model.successors_by_bigram) != int(model.character_count) || len(model.successors_by_bigram[0]) != int(model.character_count) { + return 0, .Unknown_Compression_Method + } + + if len(model.successors_reversed[0]) != int(model.successor_count) { + return 0, .Unknown_Compression_Method + } + + // Model seems legit. + return 0, nil +} + +// Decompresses into provided buffer. +decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DEFAULT_MODEL) -> (size: int, err: compress.Error) { + inp, inp_end := 0, len(input) + out, out_end := 0, len(output) + + validate_model(model) or_return + + for inp < inp_end { + val := transmute(i8)input[inp] + mark := int(-1) + + for val < 0 { + val <<= 1 + mark += 1 + } + + if mark > len(model.packs) { + return out, .Unknown_Compression_Method + } + + if mark < 0 { + if out >= out_end { + return out, .Output_Too_Short + } + + // Ignore the sentinel value for non-ASCII chars + if input[inp] == 0x00 { + inp += 1 + if inp >= inp_end { + return out, .Stream_Too_Short + } + } + output[out] = input[inp] + inp, out = inp + 1, out + 1 + + } else { + pack := model.packs[mark] + + if out + int(pack.bytes_unpacked) > out_end { + return out, .Output_Too_Short + } else if inp + int(pack.bytes_packed) > inp_end { + return out, .Stream_Too_Short + } + + code := intrinsics.unaligned_load((^u32)(&input[inp])) + when ODIN_ENDIAN == .Little { + code = intrinsics.byte_swap(code) + } + + // Unpack the leading char + offset := pack.offsets[0] + mask := pack.masks[0] + + last_chr := model.characters_by_id[(code >> offset) & u32(mask)] + output[out] = last_chr + + // Unpack the successor chars + for i := 1; i < int(pack.bytes_unpacked); i += 1 { + offset = pack.offsets[i] + mask = pack.masks[i] + + last_chr = model.successors_reversed[last_chr - model.min_char][(code >> offset) & u32(mask)] + output[out + i] = last_chr + } + + out += int(pack.bytes_unpacked) + inp += int(pack.bytes_packed) + } + } + + return out, nil +} + +decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (res: string, err: compress.Error) { + context.allocator = allocator + + if len(input) == 0 { + return "", .Stream_Too_Short + } + + max_output_size := decompress_bound(len(input), model) + + buf: [dynamic]u8 + if !resize(&buf, max_output_size) { + return "", .Out_Of_Memory + } + + length, result := decompress_slice_to_output_buffer(input, buf[:]) + resize(&buf, length) + return string(buf[:]), result +} +decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string} + +compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (size: int, err: compress.Error) { + inp, inp_end := 0, len(input) + out, out_end := 0, len(output) + output := output + + validate_model(model) or_return + + indices := make([]i16, model.max_successor_n + 1) + defer delete(indices) + + last_resort := false + + encode: for inp < inp_end { + if last_resort { + last_resort = false + + if input[inp] & 0x80 == 0x80 { + // Non-ASCII case + if out + 2 > out_end { + return out, .Output_Too_Short + } + + // Put in a sentinel byte + output[out] = 0x00 + out += 1 + } else { + // An ASCII byte + if out + 1 > out_end { + return out, .Output_Too_Short + } + } + output[out] = input[inp] + out, inp = out + 1, inp + 1 + } else { + // Find the longest string of known successors + indices[0] = model.ids_by_character[input[inp]] + last_chr_index := indices[0] + + if last_chr_index < 0 { + last_resort = true + continue encode + } + + rest := inp_end - inp + n_consecutive: i8 = 1 + for ; n_consecutive <= model.max_successor_n; n_consecutive += 1 { + if inp_end > 0 && int(n_consecutive) == rest { + break + } + + current_index := model.ids_by_character[input[inp + int(n_consecutive)]] + if current_index < 0 { // '\0' is always -1 + break + } + + successor_index := model.successors_by_bigram[last_chr_index][current_index] + if successor_index < 0 { + break + } + + indices[n_consecutive] = i16(successor_index) + last_chr_index = current_index + } + + if n_consecutive < 2 { + last_resort = true + continue encode + } + + pack_n := find_best_encoding(indices, n_consecutive) + if pack_n >= 0 { + if out + int(model.packs[pack_n].bytes_packed) > out_end { + return out, .Output_Too_Short + } + + pack := model.packs[pack_n] + code := pack.word + + for i := 0; i < int(pack.bytes_unpacked); i += 1 { + code |= u32(indices[i]) << pack.offsets[i] + } + + // In the little-endian world, we need to swap what's in the register to match the memory representation. + when ODIN_ENDIAN == .Little { + code = intrinsics.byte_swap(code) + } + out_ptr := raw_data(output[out:]) + + switch pack.bytes_packed { + case 4: + intrinsics.unaligned_store(transmute(^u32)out_ptr, code) + case 2: + intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code)) + case 1: + intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code)) + case: + return out, .Unknown_Compression_Method + } + + out += int(pack.bytes_packed) + inp += int(pack.bytes_unpacked) + } else { + last_resort = true + continue encode + } + } + } + return out, nil +} + +compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := context.allocator) -> (output: []u8, err: compress.Error) { + context.allocator = allocator + + if len(input) == 0 { + return {}, .Stream_Too_Short + } + + max_output_size := compress_bound(len(input)) + + buf: [dynamic]u8 + if !resize(&buf, max_output_size) { + return {}, .Out_Of_Memory + } + + length, result := compress_string_to_buffer(input, buf[:]) + resize(&buf, length) + return buf[:length], result +} +compress :: proc{compress_string_to_buffer, compress_string} \ No newline at end of file diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 4f5bfbdc1..27f199062 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -10,6 +10,7 @@ import c "core:c" import libc "core:c/libc" import compress "core:compress" +import shoco "core:compress/shoco" import gzip "core:compress/gzip" import zlib "core:compress/zlib" @@ -115,6 +116,7 @@ _ :: bytes _ :: c _ :: libc _ :: compress +_ :: shoco _ :: gzip _ :: zlib _ :: bit_array diff --git a/tests/core/assets/Shoco/LICENSE b/tests/core/assets/Shoco/LICENSE new file mode 100644 index 000000000..9ca94bcdf --- /dev/null +++ b/tests/core/assets/Shoco/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2016-2021 Ginger Bill. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tests/core/assets/Shoco/LICENSE.shoco b/tests/core/assets/Shoco/LICENSE.shoco new file mode 100644 index 0000000000000000000000000000000000000000..5d5e4d6236019bf208cc2ebb7a81ed06469b78a8 GIT binary patch literal 1269 zcmZ?HFQ}ZGo>8Kpk*uj;WMF8fYh++#sNjBtvq-@ybE%$!<5C5Xe6hkgiK4P5Jua@G z1Dz$0`)3v^w4^AkPF3hoxX7>;#7^pHuT)6u%PrPXxDlYxr*I>nr-WM6i1C|2kPo4sa- z!fi=~b0!@iO^N%;QWe%f-F#Mit&YM8K`sRag-e|Z{V=myQa~yp#_xRMW0s)D#btzS zZifQQu^^M@6wJH(5u^jdY>>ex1o4}#0Cv`{r{@?8GkZZAT2l1;6plL-Dctg!o0wA! z@$roSkOg-?@7#bvCg;Fo%&p$H_Hm$*ftAH;z9YWigcg}gqHNM7O=P#|;_gUr3g zJ@?+pqGE-ul?r(YOC^-B3g#>vzg@*VC1uG~y1}k_5 zD{+A&9Q`5{Tq6R4T!VuZ{DTxceFJUI-tSznemE zs8eu=XGmy>tAe|~zY8d!xq@AT!aSW_gRK>O{6RtQrVtwJs-xiI7~%-FI3UR1%`+s} z8srG4&|pt+pn3X*xCRA<284L}`)Mk8_=mfOxdw4LJB9|kx`0F1-%kM)p&=fw{y~wT zC;){4IPi58!aZC=JY0i70SXQ&M^In{hXi>#gW?k!M><^oK?))MK_N(fRPb|k_wjUh z^>cOwxyB!4O1NjRtEPfukY})`pF7A%khS5CkqZ8yAs~A}DKRwImCN5v0VT!ifMZg@ i(@nwACCn4#Y_JMfg#iEHU{7c|0SB40hXN$H^|%1|ER=2l literal 0 HcmV?d00001 diff --git a/tests/core/assets/Shoco/README.md b/tests/core/assets/Shoco/README.md new file mode 100644 index 000000000..9e46f80d0 --- /dev/null +++ b/tests/core/assets/Shoco/README.md @@ -0,0 +1,95 @@ + + +# The Odin Programming Language + + +Odin is a general-purpose programming language with distinct typing, built for high performance, modern systems, and built-in data-oriented data types. The Odin Programming Language, the C alternative for the joy of programming. + +Website: [https://odin-lang.org/](https://odin-lang.org/) + +```odin +package main + +import "core:fmt" + +main :: proc() { + program := "+ + * 😃 - /" + accumulator := 0 + + for token in program { + switch token { + case '+': accumulator += 1 + case '-': accumulator -= 1 + case '*': accumulator *= 2 + case '/': accumulator /= 2 + case '😃': accumulator *= accumulator + case: // Ignore everything else + } + } + + fmt.printf("The program \"%s\" calculates the value %d\n", + program, accumulator) +} + +``` + +## Documentation + +#### [Getting Started](https://odin-lang.org/docs/install) + +Instructions for downloading and installing the Odin compiler and libraries. + +#### [Nightly Builds](https://odin-lang.org/docs/nightly/) + +Get the latest nightly builds of Odin. + +### Learning Odin + +#### [Overview of Odin](https://odin-lang.org/docs/overview) + +An overview of the Odin programming language. + +#### [Frequently Asked Questions (FAQ)](https://odin-lang.org/docs/faq) + +Answers to common questions about Odin. + +#### [Packages](https://pkg.odin-lang.org/) + +Documentation for all the official packages part of the [core](https://pkg.odin-lang.org/core/) and [vendor](https://pkg.odin-lang.org/vendor/) library collections. + +#### [The Odin Wiki](https://github.com/odin-lang/Odin/wiki) + +A wiki maintained by the Odin community. + +#### [Odin Discord](https://discord.gg/sVBPHEv) + +Get live support and talk with other odiners on the Odin Discord. + +### Articles + +#### [The Odin Blog](https://odin-lang.org/news/) + +The official blog of the Odin programming language, featuring announcements, news, and in-depth articles by the Odin team and guests. + +## Warnings + +* The Odin compiler is still in development. diff --git a/tests/core/assets/Shoco/README.md.shoco b/tests/core/assets/Shoco/README.md.shoco new file mode 100644 index 0000000000000000000000000000000000000000..013f4f46928fb3d5c6ea62d76ddda91f29c6e420 GIT binary patch literal 2227 zcmcC1P)J;so@c9c&AUO#j!Qv7LBXawU7@%r*;Z+Lak73+etN!c@v>aKf|*JRi8&>< zO8z_Z6hNX%3JWWj*eY#InP6pRstVJaRHP3!C1i?%OKYO8|J(ynDGEL<>7|M3sS0U* z3c)R@3c>v)HzX8XQp-|v@(XTp>p^UV=~S>muo4wA=A_vwWt5Z@6kF-*ryprc(p!_O zpT9Ft_i`hM(tq64;;etUYa!Hr6!*ilb*Jks$~>5&mzfVXLI0daTPjF1)C|4ivUI3+ z8~sGE>lJLMZgWy%N_wh(K~8I0Uv9B(_z|Y^VpSu98dW0$pN`TBD06GFf3R-)IZLcg zN-Dzcww=Y-#P!nCK|Z?N2=xe|Z~*DiH#M^`G`6rbHMB4`Gc-3cF*39VMXW7I5^4@9 z0g`xKCa)N(53BuHqOZI!JMD70zO$!3IDA0nQBc%qan-%xUQv3Iz=>8Y4w@6t?Xs%2Oz=T$q|$tfSD90#>8j zp>XGn?!yTuvlQ-}0cmd5!{H1ag$bz&&I*Y+lZx_MGt0o~enP53R(_>IKg=%fB5T%4TOE-0vLt6M2Rb!pow7(zvL5u&;X zQ7we1maT#jRINTjR39M_4{ov}E3c)Akny|&ruH<6$;pjshf~G%FOemq2_FeN6zDIoAaAH9;{FU3S2!2$v#|oW7>Q zviq|u71liI@F^^YI}=(Sg=c1GB6Opbcm6x`^fzW_f;_IUF*{S?SvT{HCWWL*kdr}y z`?SetUM1W_kcdm?HF1P-pkf(R&KHL{1$elYK@-8UvQ&kOfBQ;6t}jW<$yT@#pm5xw zNFo1@Q&F)(FU)X|Q4q5g9M8{NQVdHJP=`C^5#w# zxeqlt=qSAC;%7-$c+j$7>MibK9feutkkYe5cSpelg+rf{mlPv;cT!?5$j#}c%_Wd< fR0wZBd$5>`OAA)4g0o4d!iCrzg${)s@YVtV8=oH9 literal 0 HcmV?d00001 diff --git a/tests/core/compress/test_core_compress.odin b/tests/core/compress/test_core_compress.odin index 51952a568..ee7233e52 100644 --- a/tests/core/compress/test_core_compress.odin +++ b/tests/core/compress/test_core_compress.odin @@ -7,13 +7,14 @@ package test_core_compress List of contributors: Jeroen van Rijn: Initial implementation. - A test suite for ZLIB, GZIP. + A test suite for ZLIB, GZIP and Shoco. */ import "core:testing" import "core:compress/zlib" import "core:compress/gzip" +import "core:compress/shoco" import "core:bytes" import "core:fmt" @@ -48,6 +49,7 @@ main :: proc() { t := testing.T{w=w} zlib_test(&t) gzip_test(&t) + shoco_test(&t) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) if TEST_fail > 0 { @@ -134,3 +136,56 @@ gzip_test :: proc(t: ^testing.T) { expect(t, false, error) } } + +@test +shoco_test :: proc(t: ^testing.T) { + + Shoco_Tests :: []struct{ + compressed: []u8, + raw: []u8, + short_pack: int, + short_sentinel: int, + }{ + { #load("../assets/Shoco/README.md.shoco"), #load("../assets/Shoco/README.md"), 10, 1006 }, + { #load("../assets/Shoco/LICENSE.shoco"), #load("../assets/Shoco/LICENSE"), 25, 68 }, + } + + for v in Shoco_Tests { + expected_raw := len(v.raw) + expected_compressed := len(v.compressed) + + biggest_unpacked := shoco.decompress_bound(expected_compressed) + biggest_packed := shoco.compress_bound(expected_raw) + + buffer := make([]u8, max(biggest_packed, biggest_unpacked)) + defer delete(buffer) + + size, err := shoco.decompress(v.compressed, buffer[:]) + msg := fmt.tprintf("Expected `decompress` to return `nil`, got %v", err) + expect(t, err == nil, msg) + + msg = fmt.tprintf("Decompressed %v bytes into %v. Expected to decompress into %v bytes.", len(v.compressed), size, expected_raw) + expect(t, size == expected_raw, msg) + expect(t, string(buffer[:size]) == string(v.raw), "Decompressed contents don't match.") + + size, err = shoco.compress(string(v.raw), buffer[:]) + expect(t, err == nil, "Expected `compress` to return `nil`.") + + msg = fmt.tprintf("Compressed %v bytes into %v. Expected to compress into %v bytes.", expected_raw, size, expected_compressed) + expect(t, size == expected_compressed, msg) + + size, err = shoco.decompress(v.compressed, buffer[:expected_raw - 10]) + msg = fmt.tprintf("Decompressing into too small a buffer returned %v, expected `.Output_Too_Short`", err) + expect(t, err == .Output_Too_Short, msg) + + size, err = shoco.compress(string(v.raw), buffer[:expected_compressed - 10]) + msg = fmt.tprintf("Compressing into too small a buffer returned %v, expected `.Output_Too_Short`", err) + expect(t, err == .Output_Too_Short, msg) + + size, err = shoco.decompress(v.compressed[:v.short_pack], buffer[:]) + expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after selecting a pack.") + + size, err = shoco.decompress(v.compressed[:v.short_sentinel], buffer[:]) + expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after non-ASCII sentinel.") + } +} \ No newline at end of file From ac9a358c65820894968cc11b55b08de0646d98d4 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 22 Apr 2022 17:52:38 +0200 Subject: [PATCH 067/245] [shoco] Replace 2D slices in model with 1D slices. --- core/compress/shoco/model.odin | 230 ++++++++++++++++----------------- core/compress/shoco/shoco.odin | 22 ++-- 2 files changed, 127 insertions(+), 125 deletions(-) diff --git a/core/compress/shoco/model.odin b/core/compress/shoco/model.odin index 49e3dd97e..bbc38903d 100644 --- a/core/compress/shoco/model.odin +++ b/core/compress/shoco/model.odin @@ -17,123 +17,123 @@ DEFAULT_MODEL :: Shoco_Model { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, 23, 29, -1, -1, 31, 24, -1, -1, -1, -1, -1, -1, 25, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 15, 11, 14, 0, 17, 18, 5, 2, -1, 21, 9, 13, 6, 3, 16, -1, 7, 8, 4, 10, 19, 12, 28, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, successors_by_bigram = { - {7, 4, 12, -1, 6, -1, 1, 0, 3, 5, -1, 9, -1, 8, 2, -1, 15, 14, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1}, - {-1, -1, 6, -1, 1, -1, 0, 3, 2, 4, 15, 11, -1, 9, 5, 10, 13, -1, 12, 8, 7, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 11, -1, 4, 2, -1, 0, 8, 1, 5, -1, 6, -1, 3, 7, 15, -1, 12, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, -1, 14, 7, 5, -1, 1, 2, 8, 9, 0, 15, 6, 4, 11, -1, 12, 3, -1, 10, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 4, 3, 1, 5, 0, -1, 6, 10, 9, 7, 12, 11, -1, -1, -1, -1, 13, -1, -1, 8, -1, 15, -1, -1, -1, 14, -1, -1, -1, -1, -1}, - {0, 1, 2, 3, 4, -1, -1, 5, 9, 10, 6, -1, -1, 8, 15, 11, -1, 14, -1, -1, 7, -1, 13, -1, -1, -1, 12, -1, -1, -1, -1, -1}, - {2, 8, 7, 4, 3, -1, 9, -1, 6, 11, -1, 5, -1, -1, 0, -1, -1, 14, 1, 15, 10, 12, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1}, - {0, 3, 1, 2, 6, -1, 9, 8, 4, 12, 13, 10, -1, 11, 7, -1, -1, 15, 14, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 6, 3, 4, 1, 2, -1, -1, 5, 10, 7, 9, 11, 12, -1, -1, 8, 14, -1, -1, 15, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 6, 2, 5, 9, -1, -1, -1, 10, 1, 8, -1, 12, 14, 4, -1, 15, 7, -1, 13, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 10, 9, 15, 1, -1, 4, 0, 3, 2, -1, 6, -1, 12, 11, 13, 7, 14, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 6, 0, 4, 2, -1, 7, 13, 8, 9, 11, -1, -1, 15, -1, -1, -1, -1, -1, 10, 5, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 1, 4, -1, 2, 5, 6, 7, 8, -1, 14, -1, -1, 9, 15, -1, 12, -1, -1, -1, 10, 11, -1, -1, -1, 13, -1, -1, -1, -1, -1}, - {0, 1, 3, 2, 15, -1, 12, -1, 7, 14, 4, -1, -1, 9, -1, 8, 5, 10, -1, -1, 6, -1, 13, -1, -1, -1, 11, -1, -1, -1, -1, -1}, - {0, 3, 1, 2, -1, -1, 12, 6, 4, 9, 7, -1, -1, 14, 8, -1, -1, 15, 11, 13, 5, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 7, 2, 10, 13, -1, 6, 8, 1, 3, -1, -1, 14, 15, 11, -1, -1, -1, 12, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 2, 6, 3, 7, 10, -1, 1, 9, 4, 8, -1, -1, 15, -1, 12, 5, -1, -1, -1, 11, -1, 13, -1, -1, -1, 14, -1, -1, -1, -1, -1}, - {1, 3, 4, 0, 7, -1, 12, 2, 11, 8, 6, 13, -1, -1, -1, -1, -1, 5, -1, -1, 10, 15, 9, -1, -1, -1, 14, -1, -1, -1, -1, -1}, - {1, 3, 5, 2, 13, 0, 9, 4, 7, 6, 8, -1, -1, 15, -1, 11, -1, -1, 10, -1, 14, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 2, 1, 3, -1, -1, -1, 6, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 4, 0, 3, -1, 13, 12, 2, 7, -1, -1, 15, 10, 5, 8, 14, -1, -1, -1, -1, -1, 9, -1, -1, -1, 6, -1, -1, -1, -1, -1}, - {0, 9, 2, 14, 15, 4, 1, 13, 3, 5, -1, -1, 10, -1, -1, -1, -1, 6, 12, -1, 7, -1, 8, -1, -1, -1, 11, -1, -1, -1, -1, -1}, - {-1, 2, 14, -1, 1, 5, 8, 7, 4, 12, -1, 6, 9, 11, 13, 3, 10, 15, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 3, 2, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 1, 5, -1, -1, -1, 0, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 8, 4, 1, -1, 0, -1, 6, -1, -1, 5, -1, 7, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1}, - {12, 5, -1, -1, 1, -1, -1, 7, 0, 3, -1, 2, -1, 4, 6, -1, -1, -1, -1, 8, -1, -1, 15, -1, 13, 9, -1, -1, -1, -1, -1, 11}, - {1, 3, 2, 4, -1, -1, -1, 5, -1, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1}, - {5, 3, 4, 12, 1, 6, -1, -1, -1, -1, 8, 2, -1, -1, -1, -1, 0, 9, -1, -1, 11, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, -1, -1, -1, 0, -1, 1, 12, 3, -1, -1, -1, -1, 5, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 6, -1, 10}, - {2, 3, 1, 4, -1, 0, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1}, - {5, 1, 3, 0, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 9, -1, -1, 6, -1, 7}, + 7, 4, 12, -1, 6, -1, 1, 0, 3, 5, -1, 9, -1, 8, 2, -1, 15, 14, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, + 1, -1, 6, -1, 1, -1, 0, 3, 2, 4, 15, 11, -1, 9, 5, 10, 13, -1, 12, 8, 7, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 9, 11, -1, 4, 2, -1, 0, 8, 1, 5, -1, 6, -1, 3, 7, 15, -1, 12, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 14, 7, 5, -1, 1, 2, 8, 9, 0, 15, 6, 4, 11, -1, 12, 3, -1, 10, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 4, 3, 1, 5, 0, -1, 6, 10, 9, 7, 12, 11, -1, -1, -1, -1, 13, -1, -1, 8, -1, 15, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, -1, -1, 5, 9, 10, 6, -1, -1, 8, 15, 11, -1, 14, -1, -1, 7, -1, 13, -1, -1, -1, 12, -1, -1, -1, -1, -1, + 2, 8, 7, 4, 3, -1, 9, -1, 6, 11, -1, 5, -1, -1, 0, -1, -1, 14, 1, 15, 10, 12, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1, + 0, 3, 1, 2, 6, -1, 9, 8, 4, 12, 13, 10, -1, 11, 7, -1, -1, 15, 14, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 6, 3, 4, 1, 2, -1, -1, 5, 10, 7, 9, 11, 12, -1, -1, 8, 14, -1, -1, 15, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 6, 2, 5, 9, -1, -1, -1, 10, 1, 8, -1, 12, 14, 4, -1, 15, 7, -1, 13, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 8, 10, 9, 15, 1, -1, 4, 0, 3, 2, -1, 6, -1, 12, 11, 13, 7, 14, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 3, 6, 0, 4, 2, -1, 7, 13, 8, 9, 11, -1, -1, 15, -1, -1, -1, -1, -1, 10, 5, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 0, 1, 4, -1, 2, 5, 6, 7, 8, -1, 14, -1, -1, 9, 15, -1, 12, -1, -1, -1, 10, 11, -1, -1, -1, 13, -1, -1, -1, -1, -1, + 0, 1, 3, 2, 15, -1, 12, -1, 7, 14, 4, -1, -1, 9, -1, 8, 5, 10, -1, -1, 6, -1, 13, -1, -1, -1, 11, -1, -1, -1, -1, -1, + 0, 3, 1, 2, -1, -1, 12, 6, 4, 9, 7, -1, -1, 14, 8, -1, -1, 15, 11, 13, 5, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 5, 7, 2, 10, 13, -1, 6, 8, 1, 3, -1, -1, 14, 15, 11, -1, -1, -1, 12, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 2, 6, 3, 7, 10, -1, 1, 9, 4, 8, -1, -1, 15, -1, 12, 5, -1, -1, -1, 11, -1, 13, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 1, 3, 4, 0, 7, -1, 12, 2, 11, 8, 6, 13, -1, -1, -1, -1, -1, 5, -1, -1, 10, 15, 9, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 1, 3, 5, 2, 13, 0, 9, 4, 7, 6, 8, -1, -1, 15, -1, 11, -1, -1, 10, -1, 14, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 2, 1, 3, -1, -1, -1, 6, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 11, 4, 0, 3, -1, 13, 12, 2, 7, -1, -1, 15, 10, 5, 8, 14, -1, -1, -1, -1, -1, 9, -1, -1, -1, 6, -1, -1, -1, -1, -1, + 0, 9, 2, 14, 15, 4, 1, 13, 3, 5, -1, -1, 10, -1, -1, -1, -1, 6, 12, -1, 7, -1, 8, -1, -1, -1, 11, -1, -1, -1, -1, -1, + -1, 2, 14, -1, 1, 5, 8, 7, 4, 12, -1, 6, 9, 11, 13, 3, 10, 15, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 3, 2, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 4, 3, 1, 5, -1, -1, -1, 0, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 8, 4, 1, -1, 0, -1, 6, -1, -1, 5, -1, 7, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, + 12, 5, -1, -1, 1, -1, -1, 7, 0, 3, -1, 2, -1, 4, 6, -1, -1, -1, -1, 8, -1, -1, 15, -1, 13, 9, -1, -1, -1, -1, -1, 11, + 1, 3, 2, 4, -1, -1, -1, 5, -1, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, + 5, 3, 4, 12, 1, 6, -1, -1, -1, -1, 8, 2, -1, -1, -1, -1, 0, 9, -1, -1, 11, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0, -1, 1, 12, 3, -1, -1, -1, -1, 5, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 6, -1, 10, + 2, 3, 1, 4, -1, 0, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, + 5, 1, 3, 0, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 9, -1, -1, 6, -1, 7, }, successors_reversed = { - {'s', 't', 'c', 'l', 'm', 'a', 'd', 'r', 'v', 'T', 'A', 'L', 'e', 'M', 'Y', '-'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'-', 't', 'a', 'b', 's', 'h', 'c', 'r', 'n', 'w', 'p', 'm', 'l', 'd', 'i', 'f'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'u', 'e', 'i', 'a', 'o', 'r', 'y', 'l', 'I', 'E', 'R', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'e', 'a', 'o', 'i', 'u', 'A', 'y', 'E', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'t', 'n', 'f', 's', '\'', 'm', 'I', 'N', 'A', 'E', 'L', 'Z', 'r', 'V', 'R', 'C'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'o', 'a', 'y', 'i', 'u', 'e', 'I', 'L', 'D', '\'', 'E', 'Y', '\x00', '\x00', '\x00', '\x00'}, - {'r', 'i', 'y', 'a', 'e', 'o', 'u', 'Y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'h', 'o', 'e', 'E', 'i', 'u', 'r', 'w', 'a', 'H', 'y', 'R', 'Z', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'h', 'i', 'e', 'a', 'o', 'r', 'I', 'y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'n', 't', 's', 'r', 'l', 'd', 'i', 'y', 'v', 'm', 'b', 'c', 'g', 'p', 'k', 'u'}, - {'e', 'l', 'o', 'u', 'y', 'a', 'r', 'i', 's', 'j', 't', 'b', 'v', 'h', 'm', 'd'}, - {'o', 'e', 'h', 'a', 't', 'k', 'i', 'r', 'l', 'u', 'y', 'c', 'q', 's', '-', 'd'}, - {'e', 'i', 'o', 'a', 's', 'y', 'r', 'u', 'd', 'l', '-', 'g', 'n', 'v', 'm', 'f'}, - {'r', 'n', 'd', 's', 'a', 'l', 't', 'e', 'm', 'c', 'v', 'y', 'i', 'x', 'f', 'p'}, - {'o', 'e', 'r', 'a', 'i', 'f', 'u', 't', 'l', '-', 'y', 's', 'n', 'c', '\'', 'k'}, - {'h', 'e', 'o', 'a', 'r', 'i', 'l', 's', 'u', 'n', 'g', 'b', '-', 't', 'y', 'm'}, - {'e', 'a', 'i', 'o', 't', 'r', 'u', 'y', 'm', 's', 'l', 'b', '\'', '-', 'f', 'd'}, - {'n', 's', 't', 'm', 'o', 'l', 'c', 'd', 'r', 'e', 'g', 'a', 'f', 'v', 'z', 'b'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'e', 'n', 'i', 's', 'h', 'l', 'f', 'y', '-', 'a', 'w', '\'', 'g', 'r', 'o', 't'}, - {'e', 'l', 'i', 'y', 'd', 'o', 'a', 'f', 'u', 't', 's', 'k', 'w', 'v', 'm', 'p'}, - {'e', 'a', 'o', 'i', 'u', 'p', 'y', 's', 'b', 'm', 'f', '\'', 'n', '-', 'l', 't'}, - {'d', 'g', 'e', 't', 'o', 'c', 's', 'i', 'a', 'n', 'y', 'l', 'k', '\'', 'f', 'v'}, - {'u', 'n', 'r', 'f', 'm', 't', 'w', 'o', 's', 'l', 'v', 'd', 'p', 'k', 'i', 'c'}, - {'e', 'r', 'a', 'o', 'l', 'p', 'i', 't', 'u', 's', 'h', 'y', 'b', '-', '\'', 'm'}, - {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'e', 'i', 'o', 'a', 's', 'y', 't', 'd', 'r', 'n', 'c', 'm', 'l', 'u', 'g', 'f'}, - {'e', 't', 'h', 'i', 'o', 's', 'a', 'u', 'p', 'c', 'l', 'w', 'm', 'k', 'f', 'y'}, - {'h', 'o', 'e', 'i', 'a', 't', 'r', 'u', 'y', 'l', 's', 'w', 'c', 'f', '\'', '-'}, - {'r', 't', 'l', 's', 'n', 'g', 'c', 'p', 'e', 'i', 'a', 'd', 'm', 'b', 'f', 'o'}, - {'e', 'i', 'a', 'o', 'y', 'u', 'r', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}, - {'a', 'i', 'h', 'e', 'o', 'n', 'r', 's', 'l', 'd', 'k', '-', 'f', '\'', 'c', 'b'}, - {'p', 't', 'c', 'a', 'i', 'e', 'h', 'q', 'u', 'f', '-', 'y', 'o', '\x00', '\x00', '\x00'}, - {'o', 'e', 's', 't', 'i', 'd', '\'', 'l', 'b', '-', 'm', 'a', 'r', 'n', 'p', 'w'}, + 's', 't', 'c', 'l', 'm', 'a', 'd', 'r', 'v', 'T', 'A', 'L', 'e', 'M', 'Y', '-', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '-', 't', 'a', 'b', 's', 'h', 'c', 'r', 'n', 'w', 'p', 'm', 'l', 'd', 'i', 'f', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'u', 'e', 'i', 'a', 'o', 'r', 'y', 'l', 'I', 'E', 'R', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'a', 'o', 'i', 'u', 'A', 'y', 'E', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 't', 'n', 'f', 's', '\'', 'm', 'I', 'N', 'A', 'E', 'L', 'Z', 'r', 'V', 'R', 'C', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'o', 'a', 'y', 'i', 'u', 'e', 'I', 'L', 'D', '\'', 'E', 'Y', '\x00', '\x00', '\x00', '\x00', + 'r', 'i', 'y', 'a', 'e', 'o', 'u', 'Y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'h', 'o', 'e', 'E', 'i', 'u', 'r', 'w', 'a', 'H', 'y', 'R', 'Z', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'h', 'i', 'e', 'a', 'o', 'r', 'I', 'y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'n', 't', 's', 'r', 'l', 'd', 'i', 'y', 'v', 'm', 'b', 'c', 'g', 'p', 'k', 'u', + 'e', 'l', 'o', 'u', 'y', 'a', 'r', 'i', 's', 'j', 't', 'b', 'v', 'h', 'm', 'd', + 'o', 'e', 'h', 'a', 't', 'k', 'i', 'r', 'l', 'u', 'y', 'c', 'q', 's', '-', 'd', + 'e', 'i', 'o', 'a', 's', 'y', 'r', 'u', 'd', 'l', '-', 'g', 'n', 'v', 'm', 'f', + 'r', 'n', 'd', 's', 'a', 'l', 't', 'e', 'm', 'c', 'v', 'y', 'i', 'x', 'f', 'p', + 'o', 'e', 'r', 'a', 'i', 'f', 'u', 't', 'l', '-', 'y', 's', 'n', 'c', '\'', 'k', + 'h', 'e', 'o', 'a', 'r', 'i', 'l', 's', 'u', 'n', 'g', 'b', '-', 't', 'y', 'm', + 'e', 'a', 'i', 'o', 't', 'r', 'u', 'y', 'm', 's', 'l', 'b', '\'', '-', 'f', 'd', + 'n', 's', 't', 'm', 'o', 'l', 'c', 'd', 'r', 'e', 'g', 'a', 'f', 'v', 'z', 'b', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'n', 'i', 's', 'h', 'l', 'f', 'y', '-', 'a', 'w', '\'', 'g', 'r', 'o', 't', + 'e', 'l', 'i', 'y', 'd', 'o', 'a', 'f', 'u', 't', 's', 'k', 'w', 'v', 'm', 'p', + 'e', 'a', 'o', 'i', 'u', 'p', 'y', 's', 'b', 'm', 'f', '\'', 'n', '-', 'l', 't', + 'd', 'g', 'e', 't', 'o', 'c', 's', 'i', 'a', 'n', 'y', 'l', 'k', '\'', 'f', 'v', + 'u', 'n', 'r', 'f', 'm', 't', 'w', 'o', 's', 'l', 'v', 'd', 'p', 'k', 'i', 'c', + 'e', 'r', 'a', 'o', 'l', 'p', 'i', 't', 'u', 's', 'h', 'y', 'b', '-', '\'', 'm', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'i', 'o', 'a', 's', 'y', 't', 'd', 'r', 'n', 'c', 'm', 'l', 'u', 'g', 'f', + 'e', 't', 'h', 'i', 'o', 's', 'a', 'u', 'p', 'c', 'l', 'w', 'm', 'k', 'f', 'y', + 'h', 'o', 'e', 'i', 'a', 't', 'r', 'u', 'y', 'l', 's', 'w', 'c', 'f', '\'', '-', + 'r', 't', 'l', 's', 'n', 'g', 'c', 'p', 'e', 'i', 'a', 'd', 'm', 'b', 'f', 'o', + 'e', 'i', 'a', 'o', 'y', 'u', 'r', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'a', 'i', 'h', 'e', 'o', 'n', 'r', 's', 'l', 'd', 'k', '-', 'f', '\'', 'c', 'b', + 'p', 't', 'c', 'a', 'i', 'e', 'h', 'q', 'u', 'f', '-', 'y', 'o', '\x00', '\x00', '\x00', + 'o', 'e', 's', 't', 'i', 'd', '\'', 'l', 'b', '-', 'm', 'a', 'r', 'n', 'p', 'w', }, character_count = 32, diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index 9c5008f5d..3f5b696ea 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -14,6 +14,8 @@ package shoco import "core:intrinsics" import "core:compress" +import "core:fmt" + Shoco_Pack :: struct { word: u32, bytes_packed: i8, @@ -29,8 +31,8 @@ Shoco_Model :: struct { max_char: u8, characters_by_id: []u8, ids_by_character: [256]i16, - successors_by_bigram: [][]i8, - successors_reversed: [][]u8, + successors_by_bigram: []i8, + successors_reversed: []u8, character_count: u8, successor_count: u8, @@ -74,19 +76,15 @@ find_best_encoding :: proc(indices: []i16, n_consecutive: i8, model := DEFAULT_M } validate_model :: proc(model: Shoco_Model) -> (int, compress.Error) { - if len(model.successors_reversed) != int(model.max_char - model.min_char) { - return 0, .Unknown_Compression_Method - } - if len(model.characters_by_id) != int(model.character_count) { return 0, .Unknown_Compression_Method } - if len(model.successors_by_bigram) != int(model.character_count) || len(model.successors_by_bigram[0]) != int(model.character_count) { + if len(model.successors_by_bigram) != int(model.character_count) * int(model.character_count) { return 0, .Unknown_Compression_Method } - if len(model.successors_reversed[0]) != int(model.successor_count) { + if len(model.successors_reversed) != int(model.successor_count) * int(model.max_char - model.min_char) { return 0, .Unknown_Compression_Method } @@ -155,7 +153,11 @@ decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DE offset = pack.offsets[i] mask = pack.masks[i] - last_chr = model.successors_reversed[last_chr - model.min_char][(code >> offset) & u32(mask)] + index_major := u32(last_chr - model.min_char) * u32(model.successor_count) + index_minor := (code >> offset) & u32(mask) + + last_chr = model.successors_reversed[index_major + index_minor] + output[out + i] = last_chr } @@ -242,7 +244,7 @@ compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_ break } - successor_index := model.successors_by_bigram[last_chr_index][current_index] + successor_index := model.successors_by_bigram[last_chr_index * i16(model.character_count) + current_index] if successor_index < 0 { break } From b022167df12b3d62ddacd51e64f7ab3b4e170852 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 22 Apr 2022 17:56:34 +0200 Subject: [PATCH 068/245] Remove unused fmt. --- core/compress/shoco/shoco.odin | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index 3f5b696ea..f94ce70b7 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -14,8 +14,6 @@ package shoco import "core:intrinsics" import "core:compress" -import "core:fmt" - Shoco_Pack :: struct { word: u32, bytes_packed: i8, From b44b6e7e5099cab83f4a6d0feb5af9f245dea738 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Sat, 23 Apr 2022 03:33:35 +0000 Subject: [PATCH 069/245] [path/filepath] Add file stem and long-extension procedures Adds stem(), short_stem(), and long_ext(); also adds doc-comments to base() and ext(). The 'stem' is usually 'the name' of the file; the basename without the file extension. To this end, this adds stem(), which is such that: stem(path) + ext(path) = base(path) However, 'file extension' has two different meanings to what constitutes it! > What is the extension of: 'name.tar.gz' ? Colloquially, you would likely think of it as 'a tarball' - which you might think is '.tar.gz'. But, if you're writing code to process a file of this type, you would first treat it as a Gzip file, and then treat the result as a TAR file - i.e: '.gz' ... _followed by_ '.tar'. ext() returns '.gz' here, since that is the most-immediate format that you would need to use to decode it; it would be a Gzip stream. Sometimes though, you do actually want to consider these longer file extensions. Perhaps you're extracting a tarball, and what to know what to call the intermediate tar file; perhaps you want to check to see if this file is a tarball, or just a Gzip file; or maybe you just want 'the name' of the file, and not this "strange 'name-and-part-of-the-extension' thing". So, this also adds short_stem() and long_ext(), such that: short_stem(path) + long_ext(path) = base(path) Thus, we can use either, but the most immediately-useful one is the easiest to reach for: stem('name.tar.gz') -> 'name.tar' ext('name.tar.gz') -> '.gz' short_stem('name.tar.gz') -> 'name' long_ext('name.tar.gz') -> '.tar.gz' These procedures are identical to their counterparts when the path only has a simple extension: stem('name.txt') -> 'name' ext('name.txt') -> '.txt' short_stem('name.txt') -> 'name' long_ext('name.txt') -> '.txt' --- core/path/filepath/path.odin | 133 ++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 9 deletions(-) diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index 42714d736..32e4a8a37 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -4,6 +4,8 @@ package filepath import "core:strings" +SEPARATOR_CHARS :: `/\` + // is_separator checks whether the byte is a valid separator character is_separator :: proc(c: byte) -> bool { switch c { @@ -69,6 +71,16 @@ volume_name_len :: proc(path: string) -> int { return 0 } +/* + Gets the file name and extension from a path. + + i.e: + 'path/to/name.tar.gz' -> 'name.tar.gz' + 'path/to/name.txt' -> 'name.txt' + 'path/to/name' -> 'name' + + Returns "." if the path is an empty string. +*/ base :: proc(path: string) -> string { if path == "" { return "." @@ -94,6 +106,118 @@ base :: proc(path: string) -> string { return path } +/* + Gets the name of a file from a path. + + The stem of a file is such that stem(path) + ext(path) = base(path). + + Only the last dot is considered when splitting the file extension. + See `short_stem`. + + i.e: + 'name.tar.gz' -> 'name.tar' + 'name.txt' -> 'name' + + Returns an empty string if there is no stem. e.g: '.gitignore'. + Returns an empty string if there's a trailing path separator. +*/ +stem :: proc(path: string) -> string { + if len(path) > 0 && is_separator(path[len(path) - 1]) { + // NOTE(tetra): Trailing separator + return "" + } + + // NOTE(tetra): Get the basename + path := path + if i := strings.last_index_any(path, SEPARATOR_CHARS); i != -1 { + path = path[i+1:] + } + + if i := strings.last_index_byte(path, '.'); i != -1 { + return path[:i] + } + + return path +} + +/* + Gets the name of a file from a path. + + The short stem is such that short_stem(path) + long_ext(path) = base(path). + + The first dot is used to split off the file extension, unlike `stem` which uses the last dot. + + i.e: + 'name.tar.gz' -> 'name' + 'name.txt' -> 'name' + + Returns an empty string if there is no stem. e.g: '.gitignore'. + Returns an empty string if there's a trailing path separator. +*/ +short_stem :: proc(path: string) -> string { + s := stem(path) + if i := strings.index_byte(s, '.'); i != -1 { + return s[:i] + } + return s +} + +/* + Gets the file extension from a path, including the dot. + + The file extension is such that stem(path) + ext(path) = base(path). + + Only the last dot is considered when splitting the file extension. + See `long_ext`. + + i.e: + 'name.tar.gz' -> '.gz' + 'name.txt' -> '.txt' + + Returns an empty string if there is no dot. + Returns an empty string if there is a trailing path separator. +*/ +ext :: proc(path: string) -> string { + for i := len(path)-1; i >= 0 && !is_separator(path[i]); i -= 1 { + if path[i] == '.' { + return path[i:] + } + } + return "" +} + +/* + Gets the file extension from a path, including the dot. + + The long file extension is such that short_stem(path) + long_ext(path) = base(path). + + The first dot is used to split off the file extension, unlike `ext` which uses the last dot. + + i.e: + 'name.tar.gz' -> '.tar.gz' + 'name.txt' -> '.txt' + + Returns an empty string if there is no dot. + Returns an empty string if there is a trailing path separator. +*/ +long_ext :: proc(path: string) -> string { + if len(path) > 0 && is_separator(path[len(path) - 1]) { + // NOTE(tetra): Trailing separator + return "" + } + + // NOTE(tetra): Get the basename + path := path + if i := strings.last_index_any(path, SEPARATOR_CHARS); i != -1 { + path = path[i+1:] + } + + if i := strings.index_byte(path, '.'); i != -1 { + return path[i:] + } + + return "" +} clean :: proc(path: string, allocator := context.allocator) -> string { context.allocator = allocator @@ -189,15 +313,6 @@ to_slash :: proc(path: string, allocator := context.allocator) -> (new_path: str return strings.replace_all(path, SEPARATOR_STRING, "/", allocator) } -ext :: proc(path: string) -> string { - for i := len(path)-1; i >= 0 && !is_separator(path[i]); i -= 1 { - if path[i] == '.' { - return path[i:] - } - } - return "" -} - Relative_Error :: enum { None, From 3cab2592c3e5a06882ffd711871a08c893b043f1 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 6 Apr 2022 18:26:23 +0200 Subject: [PATCH 070/245] Compiler: Add early error for output path being a directory. - Introduce new `Path` type and an array of build paths on the build context. - Resolve input and output paths/files early (before parsing). - Error early if inputs are missing or outputs are directories. - Plumb new file path generation into linker stage instead of its adhoc method. TODO: - Remove more adhoc file path generation in parser and linker stage. - Make intermediate object file generation use new path system. - Round out and robustify Path helper functions. --- .gitignore | 1 + Makefile | 4 +- build_odin.sh | 4 +- src/build_settings.cpp | 220 +++++++++++++++++++--- src/common.cpp | 257 +------------------------- src/gb/gb.h | 50 +++-- src/llvm_backend.cpp | 14 +- src/llvm_backend_general.cpp | 1 - src/main.cpp | 152 ++++++++-------- src/parser.cpp | 2 +- src/path.cpp | 333 ++++++++++++++++++++++++++++++++++ src/string.cpp | 10 +- tests/core/build.bat | 28 +-- tests/core/math/big/build.bat | 2 +- tests/issues/run.sh | 4 +- 15 files changed, 676 insertions(+), 406 deletions(-) create mode 100644 src/path.cpp diff --git a/.gitignore b/.gitignore index e8b3d3050..d03a86fd7 100644 --- a/.gitignore +++ b/.gitignore @@ -269,6 +269,7 @@ bin/ # - Linux/MacOS odin odin.dSYM +*.bin # shared collection shared/ diff --git a/Makefile b/Makefile index 82150c6a2..1a1c93180 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: debug demo +all: debug demo: - ./odin run examples/demo/demo.odin + ./odin run examples/demo report: ./odin report diff --git a/build_odin.sh b/build_odin.sh index aef3f2836..4810cafd2 100755 --- a/build_odin.sh +++ b/build_odin.sh @@ -102,7 +102,7 @@ build_odin() { } run_demo() { - ./odin run examples/demo/demo.odin -file + ./odin run examples/demo } case $OS in @@ -147,4 +147,4 @@ if [[ $# -eq 1 ]]; then exit 0 else panic "Too many arguments!" -fi +fi \ No newline at end of file diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 2f3eb03a5..0b582eac8 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -3,7 +3,6 @@ #include #endif - // #if defined(GB_SYSTEM_WINDOWS) // #define DEFAULT_TO_THREADED_CHECKER // #endif @@ -198,6 +197,22 @@ enum RelocMode : u8 { RelocMode_DynamicNoPIC, }; +enum BuildPath : u8 { + BuildPath_Main_Package, // Input Path to the package directory (or file) we're building. + BuildPath_RC, // Input Path for .rc file, can be set with `-resource:`. + BuildPath_RES, // Output Path for .res file, generated from previous. + BuildPath_Win_SDK_Root, // windows_sdk_root + BuildPath_Win_SDK_UM_Lib, // windows_sdk_um_library_path + BuildPath_Win_SDK_UCRT_Lib, // windows_sdk_ucrt_library_path + BuildPath_VS_EXE, // vs_exe_path + BuildPath_VS_LIB, // vs_library_path + + BuildPath_Output, // Output Path for .exe, .dll, .so, etc. Can be overridden with `-out:`. + BuildPath_PDB, // Output Path for .pdb file, can be overridden with `-pdb-name:`. + + BuildPathCOUNT, +}; + // This stores the information for the specify architecture of this build struct BuildContext { // Constants @@ -226,9 +241,13 @@ struct BuildContext { bool show_help; + Array build_paths; // Contains `Path` objects to output filename, pdb, resource and intermediate files. + // BuildPath enum contains the indices of paths we know *before* the work starts. + String out_filepath; String resource_filepath; String pdb_filepath; + bool has_resource; String link_flags; String extra_linker_flags; @@ -300,8 +319,6 @@ struct BuildContext { }; - - gb_global BuildContext build_context = {0}; bool global_warnings_as_errors(void) { @@ -605,28 +622,6 @@ bool allow_check_foreign_filepath(void) { // is_abs_path // has_subdir -enum TargetFileValidity : u8 { - TargetFileValidity_Invalid, - - TargetFileValidity_Writable_File, - TargetFileValidity_No_Write_Permission, - TargetFileValidity_Directory, - - TargetTargetFileValidity_COUNT, -}; - -TargetFileValidity set_output_filename(void) { - // Assembles the output filename from build_context information. - // Returns `true` if it doesn't exist or is a file. - // Returns `false` if a directory or write-protected file. - - - - - return TargetFileValidity_Writable_File; -} - - String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1}; String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1}; @@ -973,7 +968,6 @@ char *token_pos_to_string(TokenPos const &pos) { return s; } - void init_build_context(TargetMetrics *cross_target) { BuildContext *bc = &build_context; @@ -1152,8 +1146,178 @@ void init_build_context(TargetMetrics *cross_target) { bc->optimization_level = gb_clamp(bc->optimization_level, 0, 3); - - #undef LINK_FLAG_X64 #undef LINK_FLAG_386 } + +#if defined(GB_SYSTEM_WINDOWS) +// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. +// NOTE(Jeroen): No longer needed in `main.cpp -> linker_stage`. We now resolve those paths in `init_build_paths`. +#include "microsoft_craziness.h" +#endif + +// NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate. +// We've previously called `parse_build_flags`, so `out_filepath` should be set. +bool init_build_paths(String init_filename) { + gbAllocator ha = heap_allocator(); + BuildContext *bc = &build_context; + + // NOTE(Jeroen): We're pre-allocating BuildPathCOUNT slots so that certain paths are always at the same enumerated index. + array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); + + // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. + bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); + + bool produces_output_file = false; + if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { + produces_output_file = true; + } else if (bc->command_kind & Command__does_build) { + produces_output_file = true; + } + + if (!produces_output_file) { + // Command doesn't produce output files. We're done. + return true; + } + + #if defined(GB_SYSTEM_WINDOWS) + if (bc->resource_filepath.len > 0) { + bc->build_paths[BuildPath_RC] = path_from_string(ha, bc->resource_filepath); + bc->build_paths[BuildPath_RES] = path_from_string(ha, bc->resource_filepath); + bc->build_paths[BuildPath_RC].ext = copy_string(ha, STR_LIT("rc")); + bc->build_paths[BuildPath_RES].ext = copy_string(ha, STR_LIT("res")); + } + + if (bc->pdb_filepath.len > 0) { + bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); + } + + if ((bc->command_kind & Command__does_build) && (!bc->ignore_microsoft_magic)) { + // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. + Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); + + if (find_result.windows_sdk_version == 0) { + gb_printf_err("Windows SDK not found.\n"); + return false; + } + + GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); + GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); + + if (find_result.windows_sdk_root.len > 0) { + bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root); + } + + if (find_result.windows_sdk_um_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UM_Lib] = path_from_string(ha, find_result.windows_sdk_um_library_path); + } + + if (find_result.windows_sdk_ucrt_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UCRT_Lib] = path_from_string(ha, find_result.windows_sdk_ucrt_library_path); + } + + if (find_result.vs_exe_path.len > 0) { + bc->build_paths[BuildPath_VS_EXE] = path_from_string(ha, find_result.vs_exe_path); + } + + if (find_result.vs_library_path.len > 0) { + bc->build_paths[BuildPath_VS_LIB] = path_from_string(ha, find_result.vs_library_path); + } + + gb_free(ha, find_result.windows_sdk_root.text); + gb_free(ha, find_result.windows_sdk_um_library_path.text); + gb_free(ha, find_result.windows_sdk_ucrt_library_path.text); + gb_free(ha, find_result.vs_exe_path.text); + gb_free(ha, find_result.vs_library_path.text); + + } + #endif + + // All the build targets and OSes. + String output_extension; + + if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { + output_extension = STR_LIT("odin-doc"); + } else if (is_arch_wasm()) { + output_extension = STR_LIT("wasm"); + } else if (build_context.build_mode == BuildMode_Executable) { + // By default use a .bin executable extension. + output_extension = STR_LIT("bin"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("exe"); + } else if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { + output_extension = make_string(nullptr, 0); + } + } else if (build_context.build_mode == BuildMode_DynamicLibrary) { + // By default use a .so shared library extension. + output_extension = STR_LIT("so"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("dll"); + } else if (build_context.metrics.os == TargetOs_darwin) { + output_extension = STR_LIT("dylib"); + } + } else if (build_context.build_mode == BuildMode_Object) { + // By default use a .o object extension. + output_extension = STR_LIT("o"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("obj"); + } + } else if (build_context.build_mode == BuildMode_Assembly) { + // By default use a .S asm extension. + output_extension = STR_LIT("S"); + } else if (build_context.build_mode == BuildMode_LLVM_IR) { + output_extension = STR_LIT("ll"); + } else { + GB_PANIC("Unhandled build mode/target combination.\n"); + } + + if (bc->out_filepath.len > 0) { + bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath); + } else { + String output_name = remove_directory_from_path(init_filename); + output_name = remove_extension_from_path(output_name); + output_name = copy_string(ha, string_trim_whitespace(output_name)); + + /* + NOTE(Jeroen): This fallback substitution can't be made at this stage. + if (gen->output_name.len == 0) { + gen->output_name = c->info.init_scope->pkg->name; + } + */ + Path output_path = path_from_string(ha, output_name); + + #ifndef GB_SYSTEM_WINDOWS + char cwd[4096]; + getcwd(&cwd[0], 4096); + + const u8 * cwd_str = (const u8 *)&cwd[0]; + output_path.basename = copy_string(ha, make_string(cwd_str, strlen(cwd))); + #endif + + // Replace extension. + if (output_path.ext.len > 0) { + gb_free(ha, output_path.ext.text); + } + output_path.ext = copy_string(ha, output_extension); + + bc->build_paths[BuildPath_Output] = output_path; + } + + // Do we have an extension? We might not if the output filename was supplied. + if (bc->build_paths[BuildPath_Output].ext.len == 0) { + bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension); + } + + // Check if output path is a directory. + if (path_is_directory(bc->build_paths[BuildPath_Output])) { + String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]); + defer (gb_free(ha, output_file.text)); + gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file)); + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/common.cpp b/src/common.cpp index aaacda04b..94248fb62 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -675,262 +675,7 @@ wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) { #endif - -#if defined(GB_SYSTEM_WINDOWS) - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - String16 wstr = string_to_string16(a, path); - defer (gb_free(a, wstr.text)); - - i32 attribs = GetFileAttributesW(wstr.text); - if (attribs < 0) return false; - - return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - -#else - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - char *copy = cast(char *)copy_string(a, path).text; - defer (gb_free(a, copy)); - - struct stat s; - if (stat(copy, &s) == 0) { - return (s.st_mode & S_IFDIR) != 0; - } - return false; - } -#endif - - -String path_to_full_path(gbAllocator a, String path) { - gbAllocator ha = heap_allocator(); - char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); - defer (gb_free(ha, path_c)); - - char *fullpath = gb_path_get_full_name(a, path_c); - String res = string_trim_whitespace(make_string_c(fullpath)); -#if defined(GB_SYSTEM_WINDOWS) - for (isize i = 0; i < res.len; i++) { - if (res.text[i] == '\\') { - res.text[i] = '/'; - } - } -#endif - return res; -} - - - -struct FileInfo { - String name; - String fullpath; - i64 size; - bool is_dir; -}; - -enum ReadDirectoryError { - ReadDirectory_None, - - ReadDirectory_InvalidPath, - ReadDirectory_NotExists, - ReadDirectory_Permission, - ReadDirectory_NotDir, - ReadDirectory_Empty, - ReadDirectory_Unknown, - - ReadDirectory_COUNT, -}; - -i64 get_file_size(String path) { - char *c_str = alloc_cstring(heap_allocator(), path); - defer (gb_free(heap_allocator(), c_str)); - - gbFile f = {}; - gbFileError err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - if (err != gbFileError_None) { - return -1; - } - return gb_file_size(&f); -} - - -#if defined(GB_SYSTEM_WINDOWS) -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - while (path.len > 0) { - Rune end = path[path.len-1]; - if (end == '/') { - path.len -= 1; - } else if (end == '\\') { - path.len -= 1; - } else { - break; - } - } - - if (path.len == 0) { - return ReadDirectory_InvalidPath; - } - { - char *c_str = alloc_cstring(a, path); - defer (gb_free(a, c_str)); - - gbFile f = {}; - gbFileError file_err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - - switch (file_err) { - case gbFileError_Invalid: return ReadDirectory_InvalidPath; - case gbFileError_NotExists: return ReadDirectory_NotExists; - // case gbFileError_Permission: return ReadDirectory_Permission; - } - } - - if (!path_is_directory(path)) { - return ReadDirectory_NotDir; - } - - - char *new_path = gb_alloc_array(a, char, path.len+3); - defer (gb_free(a, new_path)); - - gb_memmove(new_path, path.text, path.len); - gb_memmove(new_path+path.len, "/*", 2); - new_path[path.len+2] = 0; - - String np = make_string(cast(u8 *)new_path, path.len+2); - String16 wstr = string_to_string16(a, np); - defer (gb_free(a, wstr.text)); - - WIN32_FIND_DATAW file_data = {}; - HANDLE find_file = FindFirstFileW(wstr.text, &file_data); - if (find_file == INVALID_HANDLE_VALUE) { - return ReadDirectory_Unknown; - } - defer (FindClose(find_file)); - - array_init(fi, a, 0, 100); - - do { - wchar_t *filename_w = file_data.cFileName; - i64 size = cast(i64)file_data.nFileSizeLow; - size |= (cast(i64)file_data.nFileSizeHigh) << 32; - String name = string16_to_string(a, make_string16_c(filename_w)); - if (name == "." || name == "..") { - gb_free(a, name.text); - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - array_add(fi, info); - } while (FindNextFileW(find_file, &file_data)); - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) - -#include - -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - char *c_path = alloc_cstring(a, path); - defer (gb_free(a, c_path)); - - DIR *dir = opendir(c_path); - if (!dir) { - switch (errno) { - case ENOENT: - return ReadDirectory_NotExists; - case EACCES: - return ReadDirectory_Permission; - case ENOTDIR: - return ReadDirectory_NotDir; - default: - // ENOMEM: out of memory - // EMFILE: per-process limit on open fds reached - // ENFILE: system-wide limit on total open files reached - return ReadDirectory_Unknown; - } - GB_PANIC("unreachable"); - } - - array_init(fi, a, 0, 100); - - for (;;) { - struct dirent *entry = readdir(dir); - if (entry == nullptr) { - break; - } - - String name = make_string_c(entry->d_name); - if (name == "." || name == "..") { - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - filepath.text[filepath.len] = 0; - - - struct stat dir_stat = {}; - - if (stat((char *)filepath.text, &dir_stat)) { - continue; - } - - if (S_ISDIR(dir_stat.st_mode)) { - continue; - } - - i64 size = dir_stat.st_size; - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - array_add(fi, info); - } - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#else -#error Implement read_directory -#endif - - +#include "path.cpp" struct LoadedFile { void *handle; diff --git a/src/gb/gb.h b/src/gb/gb.h index b72a893f7..3b2d6434c 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -6273,20 +6273,44 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) { #else char *p, *result, *fullpath = NULL; isize len; - p = realpath(path, NULL); - fullpath = p; - if (p == NULL) { - // NOTE(bill): File does not exist - fullpath = cast(char *)path; + fullpath = realpath(path, NULL); + + if (fullpath == NULL) { + // NOTE(Jeroen): Path doesn't exist. + if (gb_strlen(path) > 0 && path[0] == '/') { + // But it is an absolute path, so return as-is. + + fullpath = (char *)path; + len = gb_strlen(fullpath) + 1; + result = gb_alloc_array(a, char, len + 1); + + gb_memmove(result, fullpath, len); + result[len] = 0; + + } else { + // Appears to be a relative path, so construct an absolute one relative to . + char cwd[4096]; + getcwd(&cwd[0], 4096); + + isize path_len = gb_strlen(path); + isize cwd_len = gb_strlen(cwd); + len = cwd_len + 1 + path_len + 1; + result = gb_alloc_array(a, char, len); + + gb_memmove(result, (void *)cwd, cwd_len); + result[cwd_len] = '/'; + + gb_memmove(result + cwd_len + 1, (void *)path, gb_strlen(path)); + result[len] = 0; + + } + } else { + len = gb_strlen(fullpath) + 1; + result = gb_alloc_array(a, char, len + 1); + gb_memmove(result, fullpath, len); + result[len] = 0; + free(fullpath); } - - len = gb_strlen(fullpath); - - result = gb_alloc_array(a, char, len + 1); - gb_memmove(result, fullpath, len); - result[len] = 0; - free(p); - return result; #endif } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f5cb84785..7781997f7 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -967,7 +967,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } String lb_filepath_ll_for_module(lbModule *m) { - String path = m->gen->output_base; + String path = concatenate3_strings(permanent_allocator(), + build_context.build_paths[BuildPath_Output].basename, + STR_LIT("/"), + build_context.build_paths[BuildPath_Output].name + ); + if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } else if (USE_SEPARATE_MODULES) { @@ -978,7 +983,12 @@ String lb_filepath_ll_for_module(lbModule *m) { return path; } String lb_filepath_obj_for_module(lbModule *m) { - String path = m->gen->output_base; + String path = concatenate3_strings(permanent_allocator(), + build_context.build_paths[BuildPath_Output].basename, + STR_LIT("/"), + build_context.build_paths[BuildPath_Output].name + ); + if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 330059622..1a431a4ac 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -87,7 +87,6 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) { return false; } - String init_fullpath = c->parser->init_fullpath; if (build_context.out_filepath.len == 0) { diff --git a/src/main.cpp b/src/main.cpp index fc8792ceb..7b0364149 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,7 +46,6 @@ gb_global Timings global_timings = {0}; #include "checker.cpp" #include "docs.cpp" - #include "llvm_backend.cpp" #if defined(GB_SYSTEM_OSX) @@ -57,16 +56,8 @@ gb_global Timings global_timings = {0}; #endif #include "query_data.cpp" - - -#if defined(GB_SYSTEM_WINDOWS) -// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. -#include "microsoft_craziness.h" -#endif - #include "bug_report.cpp" - // NOTE(bill): 'name' is used in debugging and profiling modes i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { isize const cmd_cap = 64<<20; // 64 MiB should be more than enough @@ -130,34 +121,35 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { } - - i32 linker_stage(lbGenerator *gen) { i32 result = 0; Timings *timings = &global_timings; - String output_base = gen->output_base; + String output_filename = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); + debugf("Linking %.*s\n", LIT(output_filename)); + + // TOOD(Jeroen): Make a `build_paths[BuildPath_Object] to avoid `%.*s.o`. if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", + "\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s", LIT(build_context.ODIN_ROOT), - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else result = system_exec_command_line_app("wasm-ld", - "wasm-ld \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + "wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s", + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #endif return result; } if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { -#ifdef GB_SYSTEM_UNIX +#if defined(GB_SYSTEM_UNIX) result = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", LIT(target_os_names[build_context.metrics.os]), @@ -181,28 +173,11 @@ i32 linker_stage(lbGenerator *gen) { gbString lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(lib_str)); - char const *output_ext = "exe"; gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); defer (gb_string_free(link_settings)); - - // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. - Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); - - if (find_result.windows_sdk_version == 0) { - gb_printf_err("Windows SDK not found.\n"); - exit(1); - } - - if (build_context.ignore_microsoft_magic) { - find_result = {}; - } - // Add library search paths. - if (find_result.vs_library_path.len > 0) { - GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); - GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); - + if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { String path = {}; auto add_path = [&](String path) { if (path[path.len-1] == '\\') { @@ -210,9 +185,9 @@ i32 linker_stage(lbGenerator *gen) { } link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); }; - add_path(find_result.windows_sdk_um_library_path); - add_path(find_result.windows_sdk_ucrt_library_path); - add_path(find_result.vs_library_path); + add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); + add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); + add_path(build_context.build_paths[BuildPath_VS_LIB].basename); } @@ -252,14 +227,14 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.build_mode == BuildMode_DynamicLibrary) { - output_ext = "dll"; link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } if (build_context.pdb_filepath != "") { - link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(build_context.pdb_filepath)); + String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); + link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); } if (build_context.no_crt) { @@ -300,13 +275,21 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } + String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); + defer (gb_free(heap_allocator(), vs_exe_path.text)); + char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; if (!build_context.use_lld) { // msvc if (build_context.has_resource) { + String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); + String res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); + defer (gb_free(heap_allocator(), rc_path.text)); + defer (gb_free(heap_allocator(), res_path.text)); + result = system_exec_command_line_app("msvc-link", - "\"rc.exe\" /nologo /fo \"%.*s.res\" \"%.*s.rc\"", - LIT(output_base), - LIT(build_context.resource_filepath) + "\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"", + LIT(res_path), + LIT(rc_path) ); if (result) { @@ -314,13 +297,13 @@ i32 linker_stage(lbGenerator *gen) { } result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s " + "\"%.*slink.exe\" %s \"%.*s\" -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(find_result.vs_exe_path), object_files, LIT(output_base), LIT(output_base), output_ext, + LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), @@ -329,13 +312,13 @@ i32 linker_stage(lbGenerator *gen) { ); } else { result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s " + "\"%.*slink.exe\" %s -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(find_result.vs_exe_path), object_files, LIT(output_base), output_ext, + LIT(vs_exe_path), object_files, LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), @@ -350,13 +333,13 @@ i32 linker_stage(lbGenerator *gen) { } else { // lld result = system_exec_command_line_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " + "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(build_context.ODIN_ROOT), object_files, LIT(output_base),output_ext, + LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), @@ -415,7 +398,7 @@ i32 linker_stage(lbGenerator *gen) { } else if (string_ends_with(lib, str_lit(".so"))) { // dynamic lib, relative path to executable // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible - // at runtimeto the executable + // at runtime to the executable lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); } else { // dynamic or static system lib, just link regularly searching system library paths @@ -431,9 +414,6 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } - // Unlike the Win32 linker code, the output_ext includes the dot, because - // typically executable files on *NIX systems don't have extensions. - String output_ext = {}; gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); if (build_context.no_crt) { @@ -461,26 +441,12 @@ i32 linker_stage(lbGenerator *gen) { // correctly this way since all the other dependencies provided implicitly // by the compiler frontend are still needed and most of the command // line arguments prepared previously are incompatible with ld. - // - // Shared libraries are .dylib on MacOS and .so on Linux. - if (build_context.metrics.os == TargetOs_darwin) { - output_ext = STR_LIT(".dylib"); - } else { - output_ext = STR_LIT(".so"); - } link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); } else if (build_context.metrics.os != TargetOs_openbsd) { // OpenBSD defaults to PIE executable. do not pass -no-pie for it. link_settings = gb_string_appendc(link_settings, "-no-pie "); } - if (build_context.out_filepath.len > 0) { - //NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that - isize pos = string_extension_position(build_context.out_filepath); - if (pos > 0) { - output_ext = substring(build_context.out_filepath, pos, build_context.out_filepath.len); - } - } gbString platform_lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(platform_lib_str)); @@ -507,7 +473,7 @@ i32 linker_stage(lbGenerator *gen) { defer (gb_string_free(link_command_line)); link_command_line = gb_string_appendc(link_command_line, object_files); - link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s%.*s\" ", LIT(output_base), LIT(output_ext)); + link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); @@ -524,9 +490,7 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.ODIN_DEBUG) { // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe // to the symbols in the object file - result = system_exec_command_line_app("dsymutil", - "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) - ); + result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); if (result) { return result; @@ -1526,6 +1490,10 @@ bool parse_build_flags(Array args) { gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path)); bad_flags = true; break; + } else if (!gb_file_exists((const char *)path.text)) { + gb_printf_err("Invalid -resource path %.*s, file does not exist.\n", LIT(path)); + bad_flags = true; + break; } build_context.resource_filepath = substring(path, 0, string_extension_position(path)); build_context.has_resource = true; @@ -1540,6 +1508,11 @@ bool parse_build_flags(Array args) { String path = value.value_string; path = string_trim_whitespace(path); if (is_build_flag_path_valid(path)) { + if (path_is_directory(path)) { + gb_printf_err("Invalid -pdb-name path. %.*s, is a directory.\n", LIT(path)); + bad_flags = true; + break; + } // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); // if (ext != ".pdb") { @@ -2666,6 +2639,8 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + init_filename = copy_string(permanent_allocator(), init_filename); + if (init_filename == "-help" || init_filename == "--help") { build_context.show_help = true; @@ -2688,6 +2663,12 @@ int main(int arg_count, char const **arg_ptr) { gb_printf_err("Did you mean `%.*s %.*s %.*s -file`?\n", LIT(args[0]), LIT(command), LIT(init_filename)); gb_printf_err("The `-file` flag tells it to treat a file as a self-contained package.\n"); return 1; + } else { + String const ext = str_lit(".odin"); + if (!string_ends_with(init_filename, ext)) { + gb_printf_err("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename)); + return 1; + } } } } @@ -2709,13 +2690,24 @@ int main(int arg_count, char const **arg_ptr) { get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); } - init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr); // if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) { // print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0])); // return 1; // } + // Set and check build paths... + if (!init_build_paths(init_filename)) { + return 1; + } + + if (build_context.show_debug_messages) { + for_array(i, build_context.build_paths) { + String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]); + debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path)); + } + } + init_global_thread_pool(); defer (thread_pool_destroy(&global_thread_pool)); @@ -2732,6 +2724,8 @@ int main(int arg_count, char const **arg_ptr) { } defer (destroy_parser(parser)); + // TODO(jeroen): Remove the `init_filename` param. + // Let's put that on `build_context.build_paths[0]` instead. if (parse_packages(parser, init_filename) != ParseFile_None) { return 1; } @@ -2810,16 +2804,14 @@ int main(int arg_count, char const **arg_ptr) { } if (run_output) { + String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); + defer (gb_free(heap_allocator(), exe_name.text)); + #if defined(GB_SYSTEM_WINDOWS) - return system_exec_command_line_app("odin run", "%.*s.exe %.*s", LIT(gen->output_base), LIT(run_args_string)); + return system_exec_command_line_app("odin run", "%.*s %.*s", LIT(exe_name), LIT(run_args_string)); #else - //NOTE(thebirk): This whole thing is a little leaky - String output_ext = {}; - String complete_path = concatenate_strings(permanent_allocator(), gen->output_base, output_ext); - complete_path = path_to_full_path(permanent_allocator(), complete_path); - return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(complete_path), LIT(run_args_string)); + return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string)); #endif } - return 0; } diff --git a/src/parser.cpp b/src/parser.cpp index 767119aa8..df7f908a6 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5751,7 +5751,7 @@ ParseFileError parse_packages(Parser *p, String init_filename) { } } } - + { // Add these packages serially and then process them parallel mutex_lock(&p->wait_mutex); diff --git a/src/path.cpp b/src/path.cpp new file mode 100644 index 000000000..8d8e532b8 --- /dev/null +++ b/src/path.cpp @@ -0,0 +1,333 @@ +/* + Path handling utilities. +*/ + +#if defined(GB_SYSTEM_WINDOWS) + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + String16 wstr = string_to_string16(a, path); + defer (gb_free(a, wstr.text)); + + i32 attribs = GetFileAttributesW(wstr.text); + if (attribs < 0) return false; + + return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; + } + +#else + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + char *copy = cast(char *)copy_string(a, path).text; + defer (gb_free(a, copy)); + + struct stat s; + if (stat(copy, &s) == 0) { + return (s.st_mode & S_IFDIR) != 0; + } + return false; + } +#endif + + +String path_to_full_path(gbAllocator a, String path) { + gbAllocator ha = heap_allocator(); + char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); + defer (gb_free(ha, path_c)); + + char *fullpath = gb_path_get_full_name(a, path_c); + String res = string_trim_whitespace(make_string_c(fullpath)); +#if defined(GB_SYSTEM_WINDOWS) + for (isize i = 0; i < res.len; i++) { + if (res.text[i] == '\\') { + res.text[i] = '/'; + } + } +#endif + return copy_string(a, res); +} + +struct Path { + String basename; + String name; + String ext; +}; + +// NOTE(Jeroen): Naively turns a Path into a string. +String path_to_string(gbAllocator a, Path path) { + if (path.basename.len + path.name.len + path.ext.len == 0) { + return make_string(nullptr, 0); + } + + isize len = path.basename.len + 1 + path.name.len + 1; + if (path.ext.len > 0) { + len += path.ext.len + 1; + } + + u8 *str = gb_alloc_array(a, u8, len); + + isize i = 0; + gb_memmove(str+i, path.basename.text, path.basename.len); i += path.basename.len; + gb_memmove(str+i, "/", 1); i += 1; + gb_memmove(str+i, path.name.text, path.name.len); i += path.name.len; + if (path.ext.len > 0) { + gb_memmove(str+i, ".", 1); i += 1; + gb_memmove(str+i, path.ext.text, path.ext.len); i += path.ext.len; + } + str[i] = 0; + + String res = make_string(str, i); + res = string_trim_whitespace(res); + return res; +} + +// NOTE(Jeroen): Naively turns a Path into a string, then normalizes it using `path_to_full_path`. +String path_to_full_path(gbAllocator a, Path path) { + String temp = path_to_string(heap_allocator(), path); + defer (gb_free(heap_allocator(), temp.text)); + + return path_to_full_path(a, temp); +} + +// NOTE(Jeroen): Takes a path like "odin" or "W:\Odin", turns it into a full path, +// and then breaks it into its components to make a Path. +Path path_from_string(gbAllocator a, String const &path) { + Path res = {}; + + if (path.len == 0) return res; + + String fullpath = path_to_full_path(a, path); + defer (gb_free(heap_allocator(), fullpath.text)); + + res.basename = directory_from_path(fullpath); + res.basename = copy_string(a, res.basename); + + if (string_ends_with(fullpath, '/')) { + // It's a directory. We don't need to tinker with the name and extension. + return res; + } + + isize name_start = (res.basename.len > 0) ? res.basename.len + 1 : res.basename.len; + res.name = substring(fullpath, name_start, fullpath.len); + res.name = remove_extension_from_path(res.name); + res.name = copy_string(a, res.name); + + res.ext = path_extension(fullpath, false); // false says not to include the dot. + res.ext = copy_string(a, res.ext); + return res; +} + +bool path_is_directory(Path path) { + String path_string = path_to_full_path(heap_allocator(), path); + defer (gb_free(heap_allocator(), path_string.text)); + + return path_is_directory(path_string); +} + +struct FileInfo { + String name; + String fullpath; + i64 size; + bool is_dir; +}; + +enum ReadDirectoryError { + ReadDirectory_None, + + ReadDirectory_InvalidPath, + ReadDirectory_NotExists, + ReadDirectory_Permission, + ReadDirectory_NotDir, + ReadDirectory_Empty, + ReadDirectory_Unknown, + + ReadDirectory_COUNT, +}; + +i64 get_file_size(String path) { + char *c_str = alloc_cstring(heap_allocator(), path); + defer (gb_free(heap_allocator(), c_str)); + + gbFile f = {}; + gbFileError err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + if (err != gbFileError_None) { + return -1; + } + return gb_file_size(&f); +} + + +#if defined(GB_SYSTEM_WINDOWS) +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + while (path.len > 0) { + Rune end = path[path.len-1]; + if (end == '/') { + path.len -= 1; + } else if (end == '\\') { + path.len -= 1; + } else { + break; + } + } + + if (path.len == 0) { + return ReadDirectory_InvalidPath; + } + { + char *c_str = alloc_cstring(a, path); + defer (gb_free(a, c_str)); + + gbFile f = {}; + gbFileError file_err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + + switch (file_err) { + case gbFileError_Invalid: return ReadDirectory_InvalidPath; + case gbFileError_NotExists: return ReadDirectory_NotExists; + // case gbFileError_Permission: return ReadDirectory_Permission; + } + } + + if (!path_is_directory(path)) { + return ReadDirectory_NotDir; + } + + + char *new_path = gb_alloc_array(a, char, path.len+3); + defer (gb_free(a, new_path)); + + gb_memmove(new_path, path.text, path.len); + gb_memmove(new_path+path.len, "/*", 2); + new_path[path.len+2] = 0; + + String np = make_string(cast(u8 *)new_path, path.len+2); + String16 wstr = string_to_string16(a, np); + defer (gb_free(a, wstr.text)); + + WIN32_FIND_DATAW file_data = {}; + HANDLE find_file = FindFirstFileW(wstr.text, &file_data); + if (find_file == INVALID_HANDLE_VALUE) { + return ReadDirectory_Unknown; + } + defer (FindClose(find_file)); + + array_init(fi, a, 0, 100); + + do { + wchar_t *filename_w = file_data.cFileName; + i64 size = cast(i64)file_data.nFileSizeLow; + size |= (cast(i64)file_data.nFileSizeHigh) << 32; + String name = string16_to_string(a, make_string16_c(filename_w)); + if (name == "." || name == "..") { + gb_free(a, name.text); + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + array_add(fi, info); + } while (FindNextFileW(find_file, &file_data)); + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) + +#include + +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + char *c_path = alloc_cstring(a, path); + defer (gb_free(a, c_path)); + + DIR *dir = opendir(c_path); + if (!dir) { + switch (errno) { + case ENOENT: + return ReadDirectory_NotExists; + case EACCES: + return ReadDirectory_Permission; + case ENOTDIR: + return ReadDirectory_NotDir; + default: + // ENOMEM: out of memory + // EMFILE: per-process limit on open fds reached + // ENFILE: system-wide limit on total open files reached + return ReadDirectory_Unknown; + } + GB_PANIC("unreachable"); + } + + array_init(fi, a, 0, 100); + + for (;;) { + struct dirent *entry = readdir(dir); + if (entry == nullptr) { + break; + } + + String name = make_string_c(entry->d_name); + if (name == "." || name == "..") { + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + filepath.text[filepath.len] = 0; + + + struct stat dir_stat = {}; + + if (stat((char *)filepath.text, &dir_stat)) { + continue; + } + + if (S_ISDIR(dir_stat.st_mode)) { + continue; + } + + i64 size = dir_stat.st_size; + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + array_add(fi, info); + } + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#else +#error Implement read_directory +#endif + diff --git a/src/string.cpp b/src/string.cpp index d3dbc6904..3515df48e 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -245,15 +245,14 @@ gb_inline isize string_extension_position(String const &str) { return dot_pos; } -String path_extension(String const &str) { +String path_extension(String const &str, bool include_dot = true) { isize pos = string_extension_position(str); if (pos < 0) { return make_string(nullptr, 0); } - return substring(str, pos, str.len); + return substring(str, include_dot ? pos : pos + 1, str.len); } - String string_trim_whitespace(String str) { while (str.len > 0 && rune_is_whitespace(str[str.len-1])) { str.len--; @@ -328,7 +327,10 @@ String directory_from_path(String const &s) { break; } } - return substring(s, 0, i); + if (i >= 0) { + return substring(s, 0, i); + } + return substring(s, 0, 0); } String concatenate_strings(gbAllocator a, String const &x, String const &y) { diff --git a/tests/core/build.bat b/tests/core/build.bat index 2f9ba672e..1973c22aa 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -5,61 +5,61 @@ python3 download_assets.py echo --- echo Running core:image tests echo --- -%PATH_TO_ODIN% run image %COMMON% +%PATH_TO_ODIN% run image %COMMON% -out:test_image echo --- echo Running core:compress tests echo --- -%PATH_TO_ODIN% run compress %COMMON% +%PATH_TO_ODIN% run compress %COMMON% -out:test_compress echo --- echo Running core:strings tests echo --- -%PATH_TO_ODIN% run strings %COMMON% +%PATH_TO_ODIN% run strings %COMMON% -out:test_strings echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size +%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_hash echo --- echo Running core:odin tests echo --- -%PATH_TO_ODIN% run odin %COMMON% -o:size +%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_odin echo --- echo Running core:crypto hash tests echo --- -%PATH_TO_ODIN% run crypto %COMMON% +%PATH_TO_ODIN% run crypto %COMMON% -out:test_crypto echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -%PATH_TO_ODIN% run encoding/json %COMMON% -%PATH_TO_ODIN% run encoding/varint %COMMON% +%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa +%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json +%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint echo --- echo Running core:math/noise tests echo --- -%PATH_TO_ODIN% run math/noise %COMMON% +%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise echo --- echo Running core:math tests echo --- -%PATH_TO_ODIN% run math %COMMON% +%PATH_TO_ODIN% run math %COMMON% -out:test_math echo --- echo Running core:math/linalg/glsl tests echo --- -%PATH_TO_ODIN% run math/linalg/glsl %COMMON% +%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_glsl echo --- echo Running core:path/filepath tests echo --- -%PATH_TO_ODIN% run path/filepath %COMMON% +%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_filepath echo --- echo Running core:reflect tests echo --- -%PATH_TO_ODIN% run reflect %COMMON% +%PATH_TO_ODIN% run reflect %COMMON% -out:test_reflect diff --git a/tests/core/math/big/build.bat b/tests/core/math/big/build.bat index 16bdbc8ca..ad199d775 100644 --- a/tests/core/math/big/build.bat +++ b/tests/core/math/big/build.bat @@ -4,7 +4,7 @@ set PATH_TO_ODIN==..\..\..\..\odin set TEST_ARGS=-fast-tests set TEST_ARGS=-no-random set TEST_ARGS= -set OUT_NAME=math_big_test_library +set OUT_NAME=math_big_test_library.dll set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style echo --- echo Running core:math/big tests diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 117a9a5f1..91ec99e05 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -8,10 +8,10 @@ COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" set -x ./odin build tests/issues/test_issue_829.odin $COMMON -file -tests/issues/build/test_issue +tests/issues/build/test_issue.bin ./odin build tests/issues/test_issue_1592.odin $COMMON -file -tests/issues/build/test_issue +tests/issues/build/test_issue.bin set +x From 76d48b38d394b953ea4bbe1420ecd11e6e7dd028 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 8 Apr 2022 19:02:14 +0200 Subject: [PATCH 071/245] Compiler: Allow -out: to not have an extension on *nix for executables (only). --- src/build_settings.cpp | 4 +++- tests/issues/run.sh | 4 ++-- tests/vendor/Makefile | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0b582eac8..55d129124 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1308,7 +1308,9 @@ bool init_build_paths(String init_filename) { // Do we have an extension? We might not if the output filename was supplied. if (bc->build_paths[BuildPath_Output].ext.len == 0) { - bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension); + if (build_context.metrics.os == TargetOs_windows || build_context.build_mode != BuildMode_Executable) { + bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension); + } } // Check if output path is a directory. diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 91ec99e05..117a9a5f1 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -8,10 +8,10 @@ COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" set -x ./odin build tests/issues/test_issue_829.odin $COMMON -file -tests/issues/build/test_issue.bin +tests/issues/build/test_issue ./odin build tests/issues/test_issue_1592.odin $COMMON -file -tests/issues/build/test_issue.bin +tests/issues/build/test_issue set +x diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index 341067c6e..c508f6c50 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -10,4 +10,4 @@ endif all: botan_test botan_test: - $(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check $(ODINFLAGS) + $(ODIN) run botan -out=test_botan_hash -o:speed -no-bounds-check $(ODINFLAGS) From f4723aea4cb610a8ccc7d3614f8787d638d284d6 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 8 Apr 2022 19:14:59 +0200 Subject: [PATCH 072/245] Remove redundant bit for non-Windows. --- src/build_settings.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 55d129124..212ded5c8 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1281,22 +1281,8 @@ bool init_build_paths(String init_filename) { output_name = remove_extension_from_path(output_name); output_name = copy_string(ha, string_trim_whitespace(output_name)); - /* - NOTE(Jeroen): This fallback substitution can't be made at this stage. - if (gen->output_name.len == 0) { - gen->output_name = c->info.init_scope->pkg->name; - } - */ Path output_path = path_from_string(ha, output_name); - #ifndef GB_SYSTEM_WINDOWS - char cwd[4096]; - getcwd(&cwd[0], 4096); - - const u8 * cwd_str = (const u8 *)&cwd[0]; - output_path.basename = copy_string(ha, make_string(cwd_str, strlen(cwd))); - #endif - // Replace extension. if (output_path.ext.len > 0) { gb_free(ha, output_path.ext.text); From 3d2856db31456e9a117209eccf8e1167b4401205 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 24 Apr 2022 14:19:25 +0200 Subject: [PATCH 073/245] Update tests to use new filename generation code. --- .github/workflows/ci.yml | 11 ++++++++--- core/crypto/util/util.odin | 1 + tests/core/Makefile | 29 +++++++++++++++-------------- tests/core/build.bat | 32 +++++++++++++++++--------------- tests/issues/run.bat | 21 ++++++++------------- tests/issues/run.sh | 19 +++++++++---------- tests/vendor/Makefile | 3 ++- tests/vendor/build.bat | 3 ++- 8 files changed, 62 insertions(+), 57 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cc4283b0..989f56712 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + run: | + cd tests/issues + run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -91,7 +93,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + run: | + cd tests/issues + run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -163,7 +167,8 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - call tests\issues\run.bat + cd tests\issues + call build.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd diff --git a/core/crypto/util/util.odin b/core/crypto/util/util.odin index 6273a232e..83b07e546 100644 --- a/core/crypto/util/util.odin +++ b/core/crypto/util/util.odin @@ -11,6 +11,7 @@ package util */ import "core:mem" +_ :: mem // @note(bp): this can replace the other two cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D { diff --git a/tests/core/Makefile b/tests/core/Makefile index 6a92b4efb..9bb622633 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -1,5 +1,6 @@ ODIN=../../odin PYTHON=$(shell which python3) +OUT_FILE=test_binary.bin all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test @@ -8,39 +9,39 @@ download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin -file + $(ODIN) run image/test_core_image.odin -out=$(OUT_FILE) -file compress_test: - $(ODIN) run compress/test_core_compress.odin -file + $(ODIN) run compress/test_core_compress.odin -out=$(OUT_FILE) -file strings_test: - $(ODIN) run strings/test_core_strings.odin -file + $(ODIN) run strings/test_core_strings.odin -out=$(OUT_FILE) -file hash_test: - $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check + $(ODIN) run hash -out=$(OUT_FILE) -o:speed -no-bounds-check crypto_test: - $(ODIN) run crypto -out=test_crypto_hash -o:speed -no-bounds-check + $(ODIN) run crypto -out=$(OUT_FILE) -o:speed -no-bounds-check noise_test: - $(ODIN) run math/noise -out=test_noise + $(ODIN) run math/noise -out=$(OUT_FILE) encoding_test: - $(ODIN) run encoding/hxa -out=test_hxa -collection:tests=.. - $(ODIN) run encoding/json -out=test_json - $(ODIN) run encoding/varint -out=test_varint + $(ODIN) run encoding/hxa -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run encoding/json -out=$(OUT_FILE) + $(ODIN) run encoding/varint -out=$(OUT_FILE) math_test: - $(ODIN) run math/test_core_math.odin -out=test_core_math -file -collection:tests=.. + $(ODIN) run math/test_core_math.odin -out=$(OUT_FILE) -file -collection:tests=.. linalg_glsl_math_test: - $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=test_linalg_glsl_math -collection:tests=.. + $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=$(OUT_FILE) -collection:tests=.. filepath_test: - $(ODIN) run path/filepath/test_core_filepath.odin -file -out=test_core_filepath -collection:tests=.. + $(ODIN) run path/filepath/test_core_filepath.odin -file -out=$(OUT_FILE) -collection:tests=.. reflect_test: - $(ODIN) run reflect/test_core_reflect.odin -file -out=test_core_reflect -collection:tests=.. + $(ODIN) run reflect/test_core_reflect.odin -file -out=$(OUT_FILE) -collection:tests=.. os_exit_test: - $(ODIN) run os/test_core_os_exit.odin -file -out=test_core_os_exit && exit 1 || exit 0 + $(ODIN) run os/test_core_os_exit.odin -file -out=$(OUT_FILE) && exit 1 || exit 0 diff --git a/tests/core/build.bat b/tests/core/build.bat index 1973c22aa..331a473aa 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -1,65 +1,67 @@ @echo off -set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. +set OUT_FILE=test_binary.exe +set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. -out:%OUT_FILE% set PATH_TO_ODIN==..\..\odin + python3 download_assets.py echo --- echo Running core:image tests echo --- -%PATH_TO_ODIN% run image %COMMON% -out:test_image +%PATH_TO_ODIN% run image %COMMON% echo --- echo Running core:compress tests echo --- -%PATH_TO_ODIN% run compress %COMMON% -out:test_compress +%PATH_TO_ODIN% run compress %COMMON% echo --- echo Running core:strings tests echo --- -%PATH_TO_ODIN% run strings %COMMON% -out:test_strings +%PATH_TO_ODIN% run strings %COMMON% echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_hash +%PATH_TO_ODIN% run hash %COMMON% -o:size echo --- echo Running core:odin tests echo --- -%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_odin +%PATH_TO_ODIN% run odin %COMMON% -o:size echo --- echo Running core:crypto hash tests echo --- -%PATH_TO_ODIN% run crypto %COMMON% -out:test_crypto +%PATH_TO_ODIN% run crypto %COMMON% echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa -%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json -%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint +%PATH_TO_ODIN% run encoding/hxa %COMMON% +%PATH_TO_ODIN% run encoding/json %COMMON% +%PATH_TO_ODIN% run encoding/varint %COMMON% echo --- echo Running core:math/noise tests echo --- -%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise +%PATH_TO_ODIN% run math/noise %COMMON% echo --- echo Running core:math tests echo --- -%PATH_TO_ODIN% run math %COMMON% -out:test_math +%PATH_TO_ODIN% run math %COMMON% echo --- echo Running core:math/linalg/glsl tests echo --- -%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_glsl +%PATH_TO_ODIN% run math/linalg/glsl %COMMON% echo --- echo Running core:path/filepath tests echo --- -%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_filepath +%PATH_TO_ODIN% run path/filepath %COMMON% echo --- echo Running core:reflect tests echo --- -%PATH_TO_ODIN% run reflect %COMMON% -out:test_reflect +%PATH_TO_ODIN% run reflect %COMMON% diff --git a/tests/issues/run.bat b/tests/issues/run.bat index a652d9694..a936bd896 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -1,17 +1,12 @@ @echo off +set PATH_TO_ODIN==..\..\odin +set COMMON=-collection:tests=.. -out:build\test_issue +if not exist "build" mkdir build -if not exist "tests\issues\build\" mkdir tests\issues\build +%PATH_TO_ODIN% build test_issue_829.odin %COMMON% -file +build\test_issue -set COMMON=-collection:tests=tests -out:tests\issues\build\test_issue +%PATH_TO_ODIN% build test_issue_1592.odin %COMMON% -file +build\test_issue -@echo on - -.\odin build tests\issues\test_issue_829.odin %COMMON% -file -tests\issues\build\test_issue - -.\odin build tests\issues\test_issue_1592.odin %COMMON% -file -tests\issues\build\test_issue - -@echo off - -rmdir /S /Q tests\issues\build +rmdir /S /Q build diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 117a9a5f1..ec6d7130d 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -1,18 +1,17 @@ #!/bin/bash +ODIN=../../odin +COMMON="-collection:tests=.. -out:build/test_issue.bin" + set -eu - -mkdir -p tests/issues/build - -COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" - +mkdir -p build set -x -./odin build tests/issues/test_issue_829.odin $COMMON -file -tests/issues/build/test_issue +$ODIN build test_issue_829.odin $COMMON -file +build/test_issue.bin -./odin build tests/issues/test_issue_1592.odin $COMMON -file -tests/issues/build/test_issue +$ODIN build test_issue_1592.odin $COMMON -file +build/test_issue.bin set +x -rm -rf tests/issues/build +rm -rf build diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index c508f6c50..380e64e09 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -1,5 +1,6 @@ ODIN=../../odin ODINFLAGS= +OUT_FILE=test_binary.bin OS=$(shell uname) @@ -10,4 +11,4 @@ endif all: botan_test botan_test: - $(ODIN) run botan -out=test_botan_hash -o:speed -no-bounds-check $(ODINFLAGS) + $(ODIN) run botan -out=$(OUT_FILE) -o:speed -no-bounds-check $(ODINFLAGS) diff --git a/tests/vendor/build.bat b/tests/vendor/build.bat index e70d9f1d5..4bd9a6496 100644 --- a/tests/vendor/build.bat +++ b/tests/vendor/build.bat @@ -1,5 +1,6 @@ @echo off -set COMMON=-show-timings -no-bounds-check -vet -strict-style +set OUT_FILE=test_binary.exe +set COMMON=-show-timings -no-bounds-check -vet -strict-style -out:%OUT_FILE% set PATH_TO_ODIN==..\..\odin echo --- From 9f8d90f466454f4d14e755d44e4ba47ccbf0c92e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 24 Apr 2022 14:28:00 +0200 Subject: [PATCH 074/245] Update CI paths for issue tests. --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 989f56712..d72775636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: - name: Odin issues tests run: | cd tests/issues - run.sh + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -95,7 +95,7 @@ jobs: - name: Odin issues tests run: | cd tests/issues - run.sh + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -168,7 +168,7 @@ jobs: run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat cd tests\issues - call build.bat + call run.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd From 63331ef731209ec8db65d7f26bdbebdf9459107d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 24 Apr 2022 19:53:36 +0200 Subject: [PATCH 075/245] Revert "Merge pull request #1702 from Kelimion/filename_generation" This reverts commit a40a53b10447c9223c24cccf565a95f1773d3922, reversing changes made to 5422a3b17eae821df4adf869960995e922eb0e76. --- .github/workflows/ci.yml | 11 +- .gitignore | 1 - Makefile | 4 +- build_odin.sh | 4 +- core/crypto/util/util.odin | 1 - src/build_settings.cpp | 208 +++------------------ src/common.cpp | 257 +++++++++++++++++++++++++- src/gb/gb.h | 50 ++--- src/llvm_backend.cpp | 14 +- src/llvm_backend_general.cpp | 1 + src/main.cpp | 152 ++++++++-------- src/parser.cpp | 2 +- src/path.cpp | 333 ---------------------------------- src/string.cpp | 10 +- tests/core/Makefile | 29 ++- tests/core/build.bat | 10 +- tests/core/math/big/build.bat | 2 +- tests/issues/run.bat | 21 ++- tests/issues/run.sh | 19 +- tests/vendor/Makefile | 3 +- tests/vendor/build.bat | 3 +- 21 files changed, 436 insertions(+), 699 deletions(-) delete mode 100644 src/path.cpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d72775636..3cc4283b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,9 +39,7 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: | - cd tests/issues - ./run.sh + run: tests/issues/run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -93,9 +91,7 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: | - cd tests/issues - ./run.sh + run: tests/issues/run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -167,8 +163,7 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - cd tests\issues - call run.bat + call tests\issues\run.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd diff --git a/.gitignore b/.gitignore index d03a86fd7..e8b3d3050 100644 --- a/.gitignore +++ b/.gitignore @@ -269,7 +269,6 @@ bin/ # - Linux/MacOS odin odin.dSYM -*.bin # shared collection shared/ diff --git a/Makefile b/Makefile index 1a1c93180..82150c6a2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: debug +all: debug demo demo: - ./odin run examples/demo + ./odin run examples/demo/demo.odin report: ./odin report diff --git a/build_odin.sh b/build_odin.sh index 4810cafd2..aef3f2836 100755 --- a/build_odin.sh +++ b/build_odin.sh @@ -102,7 +102,7 @@ build_odin() { } run_demo() { - ./odin run examples/demo + ./odin run examples/demo/demo.odin -file } case $OS in @@ -147,4 +147,4 @@ if [[ $# -eq 1 ]]; then exit 0 else panic "Too many arguments!" -fi \ No newline at end of file +fi diff --git a/core/crypto/util/util.odin b/core/crypto/util/util.odin index 83b07e546..6273a232e 100644 --- a/core/crypto/util/util.odin +++ b/core/crypto/util/util.odin @@ -11,7 +11,6 @@ package util */ import "core:mem" -_ :: mem // @note(bp): this can replace the other two cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 212ded5c8..2f3eb03a5 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -3,6 +3,7 @@ #include #endif + // #if defined(GB_SYSTEM_WINDOWS) // #define DEFAULT_TO_THREADED_CHECKER // #endif @@ -197,22 +198,6 @@ enum RelocMode : u8 { RelocMode_DynamicNoPIC, }; -enum BuildPath : u8 { - BuildPath_Main_Package, // Input Path to the package directory (or file) we're building. - BuildPath_RC, // Input Path for .rc file, can be set with `-resource:`. - BuildPath_RES, // Output Path for .res file, generated from previous. - BuildPath_Win_SDK_Root, // windows_sdk_root - BuildPath_Win_SDK_UM_Lib, // windows_sdk_um_library_path - BuildPath_Win_SDK_UCRT_Lib, // windows_sdk_ucrt_library_path - BuildPath_VS_EXE, // vs_exe_path - BuildPath_VS_LIB, // vs_library_path - - BuildPath_Output, // Output Path for .exe, .dll, .so, etc. Can be overridden with `-out:`. - BuildPath_PDB, // Output Path for .pdb file, can be overridden with `-pdb-name:`. - - BuildPathCOUNT, -}; - // This stores the information for the specify architecture of this build struct BuildContext { // Constants @@ -241,13 +226,9 @@ struct BuildContext { bool show_help; - Array build_paths; // Contains `Path` objects to output filename, pdb, resource and intermediate files. - // BuildPath enum contains the indices of paths we know *before* the work starts. - String out_filepath; String resource_filepath; String pdb_filepath; - bool has_resource; String link_flags; String extra_linker_flags; @@ -319,6 +300,8 @@ struct BuildContext { }; + + gb_global BuildContext build_context = {0}; bool global_warnings_as_errors(void) { @@ -622,6 +605,28 @@ bool allow_check_foreign_filepath(void) { // is_abs_path // has_subdir +enum TargetFileValidity : u8 { + TargetFileValidity_Invalid, + + TargetFileValidity_Writable_File, + TargetFileValidity_No_Write_Permission, + TargetFileValidity_Directory, + + TargetTargetFileValidity_COUNT, +}; + +TargetFileValidity set_output_filename(void) { + // Assembles the output filename from build_context information. + // Returns `true` if it doesn't exist or is a file. + // Returns `false` if a directory or write-protected file. + + + + + return TargetFileValidity_Writable_File; +} + + String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1}; String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1}; @@ -968,6 +973,7 @@ char *token_pos_to_string(TokenPos const &pos) { return s; } + void init_build_context(TargetMetrics *cross_target) { BuildContext *bc = &build_context; @@ -1146,166 +1152,8 @@ void init_build_context(TargetMetrics *cross_target) { bc->optimization_level = gb_clamp(bc->optimization_level, 0, 3); + + #undef LINK_FLAG_X64 #undef LINK_FLAG_386 } - -#if defined(GB_SYSTEM_WINDOWS) -// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. -// NOTE(Jeroen): No longer needed in `main.cpp -> linker_stage`. We now resolve those paths in `init_build_paths`. -#include "microsoft_craziness.h" -#endif - -// NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate. -// We've previously called `parse_build_flags`, so `out_filepath` should be set. -bool init_build_paths(String init_filename) { - gbAllocator ha = heap_allocator(); - BuildContext *bc = &build_context; - - // NOTE(Jeroen): We're pre-allocating BuildPathCOUNT slots so that certain paths are always at the same enumerated index. - array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); - - // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. - bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); - - bool produces_output_file = false; - if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { - produces_output_file = true; - } else if (bc->command_kind & Command__does_build) { - produces_output_file = true; - } - - if (!produces_output_file) { - // Command doesn't produce output files. We're done. - return true; - } - - #if defined(GB_SYSTEM_WINDOWS) - if (bc->resource_filepath.len > 0) { - bc->build_paths[BuildPath_RC] = path_from_string(ha, bc->resource_filepath); - bc->build_paths[BuildPath_RES] = path_from_string(ha, bc->resource_filepath); - bc->build_paths[BuildPath_RC].ext = copy_string(ha, STR_LIT("rc")); - bc->build_paths[BuildPath_RES].ext = copy_string(ha, STR_LIT("res")); - } - - if (bc->pdb_filepath.len > 0) { - bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); - } - - if ((bc->command_kind & Command__does_build) && (!bc->ignore_microsoft_magic)) { - // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. - Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); - - if (find_result.windows_sdk_version == 0) { - gb_printf_err("Windows SDK not found.\n"); - return false; - } - - GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); - GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); - - if (find_result.windows_sdk_root.len > 0) { - bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root); - } - - if (find_result.windows_sdk_um_library_path.len > 0) { - bc->build_paths[BuildPath_Win_SDK_UM_Lib] = path_from_string(ha, find_result.windows_sdk_um_library_path); - } - - if (find_result.windows_sdk_ucrt_library_path.len > 0) { - bc->build_paths[BuildPath_Win_SDK_UCRT_Lib] = path_from_string(ha, find_result.windows_sdk_ucrt_library_path); - } - - if (find_result.vs_exe_path.len > 0) { - bc->build_paths[BuildPath_VS_EXE] = path_from_string(ha, find_result.vs_exe_path); - } - - if (find_result.vs_library_path.len > 0) { - bc->build_paths[BuildPath_VS_LIB] = path_from_string(ha, find_result.vs_library_path); - } - - gb_free(ha, find_result.windows_sdk_root.text); - gb_free(ha, find_result.windows_sdk_um_library_path.text); - gb_free(ha, find_result.windows_sdk_ucrt_library_path.text); - gb_free(ha, find_result.vs_exe_path.text); - gb_free(ha, find_result.vs_library_path.text); - - } - #endif - - // All the build targets and OSes. - String output_extension; - - if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { - output_extension = STR_LIT("odin-doc"); - } else if (is_arch_wasm()) { - output_extension = STR_LIT("wasm"); - } else if (build_context.build_mode == BuildMode_Executable) { - // By default use a .bin executable extension. - output_extension = STR_LIT("bin"); - - if (build_context.metrics.os == TargetOs_windows) { - output_extension = STR_LIT("exe"); - } else if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { - output_extension = make_string(nullptr, 0); - } - } else if (build_context.build_mode == BuildMode_DynamicLibrary) { - // By default use a .so shared library extension. - output_extension = STR_LIT("so"); - - if (build_context.metrics.os == TargetOs_windows) { - output_extension = STR_LIT("dll"); - } else if (build_context.metrics.os == TargetOs_darwin) { - output_extension = STR_LIT("dylib"); - } - } else if (build_context.build_mode == BuildMode_Object) { - // By default use a .o object extension. - output_extension = STR_LIT("o"); - - if (build_context.metrics.os == TargetOs_windows) { - output_extension = STR_LIT("obj"); - } - } else if (build_context.build_mode == BuildMode_Assembly) { - // By default use a .S asm extension. - output_extension = STR_LIT("S"); - } else if (build_context.build_mode == BuildMode_LLVM_IR) { - output_extension = STR_LIT("ll"); - } else { - GB_PANIC("Unhandled build mode/target combination.\n"); - } - - if (bc->out_filepath.len > 0) { - bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath); - } else { - String output_name = remove_directory_from_path(init_filename); - output_name = remove_extension_from_path(output_name); - output_name = copy_string(ha, string_trim_whitespace(output_name)); - - Path output_path = path_from_string(ha, output_name); - - // Replace extension. - if (output_path.ext.len > 0) { - gb_free(ha, output_path.ext.text); - } - output_path.ext = copy_string(ha, output_extension); - - bc->build_paths[BuildPath_Output] = output_path; - } - - // Do we have an extension? We might not if the output filename was supplied. - if (bc->build_paths[BuildPath_Output].ext.len == 0) { - if (build_context.metrics.os == TargetOs_windows || build_context.build_mode != BuildMode_Executable) { - bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension); - } - } - - // Check if output path is a directory. - if (path_is_directory(bc->build_paths[BuildPath_Output])) { - String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]); - defer (gb_free(ha, output_file.text)); - gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file)); - return false; - } - - return true; -} \ No newline at end of file diff --git a/src/common.cpp b/src/common.cpp index 94248fb62..aaacda04b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -675,7 +675,262 @@ wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) { #endif -#include "path.cpp" + +#if defined(GB_SYSTEM_WINDOWS) + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + String16 wstr = string_to_string16(a, path); + defer (gb_free(a, wstr.text)); + + i32 attribs = GetFileAttributesW(wstr.text); + if (attribs < 0) return false; + + return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; + } + +#else + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + char *copy = cast(char *)copy_string(a, path).text; + defer (gb_free(a, copy)); + + struct stat s; + if (stat(copy, &s) == 0) { + return (s.st_mode & S_IFDIR) != 0; + } + return false; + } +#endif + + +String path_to_full_path(gbAllocator a, String path) { + gbAllocator ha = heap_allocator(); + char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); + defer (gb_free(ha, path_c)); + + char *fullpath = gb_path_get_full_name(a, path_c); + String res = string_trim_whitespace(make_string_c(fullpath)); +#if defined(GB_SYSTEM_WINDOWS) + for (isize i = 0; i < res.len; i++) { + if (res.text[i] == '\\') { + res.text[i] = '/'; + } + } +#endif + return res; +} + + + +struct FileInfo { + String name; + String fullpath; + i64 size; + bool is_dir; +}; + +enum ReadDirectoryError { + ReadDirectory_None, + + ReadDirectory_InvalidPath, + ReadDirectory_NotExists, + ReadDirectory_Permission, + ReadDirectory_NotDir, + ReadDirectory_Empty, + ReadDirectory_Unknown, + + ReadDirectory_COUNT, +}; + +i64 get_file_size(String path) { + char *c_str = alloc_cstring(heap_allocator(), path); + defer (gb_free(heap_allocator(), c_str)); + + gbFile f = {}; + gbFileError err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + if (err != gbFileError_None) { + return -1; + } + return gb_file_size(&f); +} + + +#if defined(GB_SYSTEM_WINDOWS) +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + while (path.len > 0) { + Rune end = path[path.len-1]; + if (end == '/') { + path.len -= 1; + } else if (end == '\\') { + path.len -= 1; + } else { + break; + } + } + + if (path.len == 0) { + return ReadDirectory_InvalidPath; + } + { + char *c_str = alloc_cstring(a, path); + defer (gb_free(a, c_str)); + + gbFile f = {}; + gbFileError file_err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + + switch (file_err) { + case gbFileError_Invalid: return ReadDirectory_InvalidPath; + case gbFileError_NotExists: return ReadDirectory_NotExists; + // case gbFileError_Permission: return ReadDirectory_Permission; + } + } + + if (!path_is_directory(path)) { + return ReadDirectory_NotDir; + } + + + char *new_path = gb_alloc_array(a, char, path.len+3); + defer (gb_free(a, new_path)); + + gb_memmove(new_path, path.text, path.len); + gb_memmove(new_path+path.len, "/*", 2); + new_path[path.len+2] = 0; + + String np = make_string(cast(u8 *)new_path, path.len+2); + String16 wstr = string_to_string16(a, np); + defer (gb_free(a, wstr.text)); + + WIN32_FIND_DATAW file_data = {}; + HANDLE find_file = FindFirstFileW(wstr.text, &file_data); + if (find_file == INVALID_HANDLE_VALUE) { + return ReadDirectory_Unknown; + } + defer (FindClose(find_file)); + + array_init(fi, a, 0, 100); + + do { + wchar_t *filename_w = file_data.cFileName; + i64 size = cast(i64)file_data.nFileSizeLow; + size |= (cast(i64)file_data.nFileSizeHigh) << 32; + String name = string16_to_string(a, make_string16_c(filename_w)); + if (name == "." || name == "..") { + gb_free(a, name.text); + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + array_add(fi, info); + } while (FindNextFileW(find_file, &file_data)); + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) + +#include + +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + char *c_path = alloc_cstring(a, path); + defer (gb_free(a, c_path)); + + DIR *dir = opendir(c_path); + if (!dir) { + switch (errno) { + case ENOENT: + return ReadDirectory_NotExists; + case EACCES: + return ReadDirectory_Permission; + case ENOTDIR: + return ReadDirectory_NotDir; + default: + // ENOMEM: out of memory + // EMFILE: per-process limit on open fds reached + // ENFILE: system-wide limit on total open files reached + return ReadDirectory_Unknown; + } + GB_PANIC("unreachable"); + } + + array_init(fi, a, 0, 100); + + for (;;) { + struct dirent *entry = readdir(dir); + if (entry == nullptr) { + break; + } + + String name = make_string_c(entry->d_name); + if (name == "." || name == "..") { + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + filepath.text[filepath.len] = 0; + + + struct stat dir_stat = {}; + + if (stat((char *)filepath.text, &dir_stat)) { + continue; + } + + if (S_ISDIR(dir_stat.st_mode)) { + continue; + } + + i64 size = dir_stat.st_size; + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + array_add(fi, info); + } + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#else +#error Implement read_directory +#endif + + struct LoadedFile { void *handle; diff --git a/src/gb/gb.h b/src/gb/gb.h index 3b2d6434c..b72a893f7 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -6273,44 +6273,20 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) { #else char *p, *result, *fullpath = NULL; isize len; - fullpath = realpath(path, NULL); - - if (fullpath == NULL) { - // NOTE(Jeroen): Path doesn't exist. - if (gb_strlen(path) > 0 && path[0] == '/') { - // But it is an absolute path, so return as-is. - - fullpath = (char *)path; - len = gb_strlen(fullpath) + 1; - result = gb_alloc_array(a, char, len + 1); - - gb_memmove(result, fullpath, len); - result[len] = 0; - - } else { - // Appears to be a relative path, so construct an absolute one relative to . - char cwd[4096]; - getcwd(&cwd[0], 4096); - - isize path_len = gb_strlen(path); - isize cwd_len = gb_strlen(cwd); - len = cwd_len + 1 + path_len + 1; - result = gb_alloc_array(a, char, len); - - gb_memmove(result, (void *)cwd, cwd_len); - result[cwd_len] = '/'; - - gb_memmove(result + cwd_len + 1, (void *)path, gb_strlen(path)); - result[len] = 0; - - } - } else { - len = gb_strlen(fullpath) + 1; - result = gb_alloc_array(a, char, len + 1); - gb_memmove(result, fullpath, len); - result[len] = 0; - free(fullpath); + p = realpath(path, NULL); + fullpath = p; + if (p == NULL) { + // NOTE(bill): File does not exist + fullpath = cast(char *)path; } + + len = gb_strlen(fullpath); + + result = gb_alloc_array(a, char, len + 1); + gb_memmove(result, fullpath, len); + result[len] = 0; + free(p); + return result; #endif } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 7781997f7..f5cb84785 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -967,12 +967,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } String lb_filepath_ll_for_module(lbModule *m) { - String path = concatenate3_strings(permanent_allocator(), - build_context.build_paths[BuildPath_Output].basename, - STR_LIT("/"), - build_context.build_paths[BuildPath_Output].name - ); - + String path = m->gen->output_base; if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } else if (USE_SEPARATE_MODULES) { @@ -983,12 +978,7 @@ String lb_filepath_ll_for_module(lbModule *m) { return path; } String lb_filepath_obj_for_module(lbModule *m) { - String path = concatenate3_strings(permanent_allocator(), - build_context.build_paths[BuildPath_Output].basename, - STR_LIT("/"), - build_context.build_paths[BuildPath_Output].name - ); - + String path = m->gen->output_base; if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 1a431a4ac..330059622 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -87,6 +87,7 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) { return false; } + String init_fullpath = c->parser->init_fullpath; if (build_context.out_filepath.len == 0) { diff --git a/src/main.cpp b/src/main.cpp index 7b0364149..fc8792ceb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ gb_global Timings global_timings = {0}; #include "checker.cpp" #include "docs.cpp" + #include "llvm_backend.cpp" #if defined(GB_SYSTEM_OSX) @@ -56,8 +57,16 @@ gb_global Timings global_timings = {0}; #endif #include "query_data.cpp" + + +#if defined(GB_SYSTEM_WINDOWS) +// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. +#include "microsoft_craziness.h" +#endif + #include "bug_report.cpp" + // NOTE(bill): 'name' is used in debugging and profiling modes i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { isize const cmd_cap = 64<<20; // 64 MiB should be more than enough @@ -121,35 +130,34 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { } + + i32 linker_stage(lbGenerator *gen) { i32 result = 0; Timings *timings = &global_timings; - String output_filename = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); - debugf("Linking %.*s\n", LIT(output_filename)); - - // TOOD(Jeroen): Make a `build_paths[BuildPath_Object] to avoid `%.*s.o`. + String output_base = gen->output_base; if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s", + "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", LIT(build_context.ODIN_ROOT), - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else result = system_exec_command_line_app("wasm-ld", - "wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + "wasm-ld \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", + LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #endif return result; } if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { -#if defined(GB_SYSTEM_UNIX) +#ifdef GB_SYSTEM_UNIX result = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", LIT(target_os_names[build_context.metrics.os]), @@ -173,11 +181,28 @@ i32 linker_stage(lbGenerator *gen) { gbString lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(lib_str)); + char const *output_ext = "exe"; gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); defer (gb_string_free(link_settings)); + + // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. + Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); + + if (find_result.windows_sdk_version == 0) { + gb_printf_err("Windows SDK not found.\n"); + exit(1); + } + + if (build_context.ignore_microsoft_magic) { + find_result = {}; + } + // Add library search paths. - if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { + if (find_result.vs_library_path.len > 0) { + GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); + GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); + String path = {}; auto add_path = [&](String path) { if (path[path.len-1] == '\\') { @@ -185,9 +210,9 @@ i32 linker_stage(lbGenerator *gen) { } link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); }; - add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); - add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); - add_path(build_context.build_paths[BuildPath_VS_LIB].basename); + add_path(find_result.windows_sdk_um_library_path); + add_path(find_result.windows_sdk_ucrt_library_path); + add_path(find_result.vs_library_path); } @@ -227,14 +252,14 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.build_mode == BuildMode_DynamicLibrary) { + output_ext = "dll"; link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } if (build_context.pdb_filepath != "") { - String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); - link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); + link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(build_context.pdb_filepath)); } if (build_context.no_crt) { @@ -275,21 +300,13 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } - String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); - defer (gb_free(heap_allocator(), vs_exe_path.text)); - char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; if (!build_context.use_lld) { // msvc if (build_context.has_resource) { - String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); - String res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); - defer (gb_free(heap_allocator(), rc_path.text)); - defer (gb_free(heap_allocator(), res_path.text)); - result = system_exec_command_line_app("msvc-link", - "\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"", - LIT(res_path), - LIT(rc_path) + "\"rc.exe\" /nologo /fo \"%.*s.res\" \"%.*s.rc\"", + LIT(output_base), + LIT(build_context.resource_filepath) ); if (result) { @@ -297,13 +314,13 @@ i32 linker_stage(lbGenerator *gen) { } result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s \"%.*s\" -OUT:\"%.*s\" %s " + "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), + LIT(find_result.vs_exe_path), object_files, LIT(output_base), LIT(output_base), output_ext, link_settings, subsystem_str, LIT(build_context.link_flags), @@ -312,13 +329,13 @@ i32 linker_stage(lbGenerator *gen) { ); } else { result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s -OUT:\"%.*s\" %s " + "\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(vs_exe_path), object_files, LIT(output_filename), + LIT(find_result.vs_exe_path), object_files, LIT(output_base), output_ext, link_settings, subsystem_str, LIT(build_context.link_flags), @@ -333,13 +350,13 @@ i32 linker_stage(lbGenerator *gen) { } else { // lld result = system_exec_command_line_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " + "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), + LIT(build_context.ODIN_ROOT), object_files, LIT(output_base),output_ext, link_settings, subsystem_str, LIT(build_context.link_flags), @@ -398,7 +415,7 @@ i32 linker_stage(lbGenerator *gen) { } else if (string_ends_with(lib, str_lit(".so"))) { // dynamic lib, relative path to executable // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible - // at runtime to the executable + // at runtimeto the executable lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); } else { // dynamic or static system lib, just link regularly searching system library paths @@ -414,6 +431,9 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } + // Unlike the Win32 linker code, the output_ext includes the dot, because + // typically executable files on *NIX systems don't have extensions. + String output_ext = {}; gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); if (build_context.no_crt) { @@ -441,12 +461,26 @@ i32 linker_stage(lbGenerator *gen) { // correctly this way since all the other dependencies provided implicitly // by the compiler frontend are still needed and most of the command // line arguments prepared previously are incompatible with ld. + // + // Shared libraries are .dylib on MacOS and .so on Linux. + if (build_context.metrics.os == TargetOs_darwin) { + output_ext = STR_LIT(".dylib"); + } else { + output_ext = STR_LIT(".so"); + } link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); } else if (build_context.metrics.os != TargetOs_openbsd) { // OpenBSD defaults to PIE executable. do not pass -no-pie for it. link_settings = gb_string_appendc(link_settings, "-no-pie "); } + if (build_context.out_filepath.len > 0) { + //NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that + isize pos = string_extension_position(build_context.out_filepath); + if (pos > 0) { + output_ext = substring(build_context.out_filepath, pos, build_context.out_filepath.len); + } + } gbString platform_lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(platform_lib_str)); @@ -473,7 +507,7 @@ i32 linker_stage(lbGenerator *gen) { defer (gb_string_free(link_command_line)); link_command_line = gb_string_appendc(link_command_line, object_files); - link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); + link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s%.*s\" ", LIT(output_base), LIT(output_ext)); link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); @@ -490,7 +524,9 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.ODIN_DEBUG) { // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe // to the symbols in the object file - result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); + result = system_exec_command_line_app("dsymutil", + "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) + ); if (result) { return result; @@ -1490,10 +1526,6 @@ bool parse_build_flags(Array args) { gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path)); bad_flags = true; break; - } else if (!gb_file_exists((const char *)path.text)) { - gb_printf_err("Invalid -resource path %.*s, file does not exist.\n", LIT(path)); - bad_flags = true; - break; } build_context.resource_filepath = substring(path, 0, string_extension_position(path)); build_context.has_resource = true; @@ -1508,11 +1540,6 @@ bool parse_build_flags(Array args) { String path = value.value_string; path = string_trim_whitespace(path); if (is_build_flag_path_valid(path)) { - if (path_is_directory(path)) { - gb_printf_err("Invalid -pdb-name path. %.*s, is a directory.\n", LIT(path)); - bad_flags = true; - break; - } // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); // if (ext != ".pdb") { @@ -2639,8 +2666,6 @@ int main(int arg_count, char const **arg_ptr) { return 1; } - init_filename = copy_string(permanent_allocator(), init_filename); - if (init_filename == "-help" || init_filename == "--help") { build_context.show_help = true; @@ -2663,12 +2688,6 @@ int main(int arg_count, char const **arg_ptr) { gb_printf_err("Did you mean `%.*s %.*s %.*s -file`?\n", LIT(args[0]), LIT(command), LIT(init_filename)); gb_printf_err("The `-file` flag tells it to treat a file as a self-contained package.\n"); return 1; - } else { - String const ext = str_lit(".odin"); - if (!string_ends_with(init_filename, ext)) { - gb_printf_err("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename)); - return 1; - } } } } @@ -2690,24 +2709,13 @@ int main(int arg_count, char const **arg_ptr) { get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); } + init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr); // if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) { // print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0])); // return 1; // } - // Set and check build paths... - if (!init_build_paths(init_filename)) { - return 1; - } - - if (build_context.show_debug_messages) { - for_array(i, build_context.build_paths) { - String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]); - debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path)); - } - } - init_global_thread_pool(); defer (thread_pool_destroy(&global_thread_pool)); @@ -2724,8 +2732,6 @@ int main(int arg_count, char const **arg_ptr) { } defer (destroy_parser(parser)); - // TODO(jeroen): Remove the `init_filename` param. - // Let's put that on `build_context.build_paths[0]` instead. if (parse_packages(parser, init_filename) != ParseFile_None) { return 1; } @@ -2804,14 +2810,16 @@ int main(int arg_count, char const **arg_ptr) { } if (run_output) { - String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); - defer (gb_free(heap_allocator(), exe_name.text)); - #if defined(GB_SYSTEM_WINDOWS) - return system_exec_command_line_app("odin run", "%.*s %.*s", LIT(exe_name), LIT(run_args_string)); + return system_exec_command_line_app("odin run", "%.*s.exe %.*s", LIT(gen->output_base), LIT(run_args_string)); #else - return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string)); + //NOTE(thebirk): This whole thing is a little leaky + String output_ext = {}; + String complete_path = concatenate_strings(permanent_allocator(), gen->output_base, output_ext); + complete_path = path_to_full_path(permanent_allocator(), complete_path); + return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(complete_path), LIT(run_args_string)); #endif } + return 0; } diff --git a/src/parser.cpp b/src/parser.cpp index df7f908a6..767119aa8 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -5751,7 +5751,7 @@ ParseFileError parse_packages(Parser *p, String init_filename) { } } } - + { // Add these packages serially and then process them parallel mutex_lock(&p->wait_mutex); diff --git a/src/path.cpp b/src/path.cpp deleted file mode 100644 index 8d8e532b8..000000000 --- a/src/path.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - Path handling utilities. -*/ - -#if defined(GB_SYSTEM_WINDOWS) - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - String16 wstr = string_to_string16(a, path); - defer (gb_free(a, wstr.text)); - - i32 attribs = GetFileAttributesW(wstr.text); - if (attribs < 0) return false; - - return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - -#else - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - char *copy = cast(char *)copy_string(a, path).text; - defer (gb_free(a, copy)); - - struct stat s; - if (stat(copy, &s) == 0) { - return (s.st_mode & S_IFDIR) != 0; - } - return false; - } -#endif - - -String path_to_full_path(gbAllocator a, String path) { - gbAllocator ha = heap_allocator(); - char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); - defer (gb_free(ha, path_c)); - - char *fullpath = gb_path_get_full_name(a, path_c); - String res = string_trim_whitespace(make_string_c(fullpath)); -#if defined(GB_SYSTEM_WINDOWS) - for (isize i = 0; i < res.len; i++) { - if (res.text[i] == '\\') { - res.text[i] = '/'; - } - } -#endif - return copy_string(a, res); -} - -struct Path { - String basename; - String name; - String ext; -}; - -// NOTE(Jeroen): Naively turns a Path into a string. -String path_to_string(gbAllocator a, Path path) { - if (path.basename.len + path.name.len + path.ext.len == 0) { - return make_string(nullptr, 0); - } - - isize len = path.basename.len + 1 + path.name.len + 1; - if (path.ext.len > 0) { - len += path.ext.len + 1; - } - - u8 *str = gb_alloc_array(a, u8, len); - - isize i = 0; - gb_memmove(str+i, path.basename.text, path.basename.len); i += path.basename.len; - gb_memmove(str+i, "/", 1); i += 1; - gb_memmove(str+i, path.name.text, path.name.len); i += path.name.len; - if (path.ext.len > 0) { - gb_memmove(str+i, ".", 1); i += 1; - gb_memmove(str+i, path.ext.text, path.ext.len); i += path.ext.len; - } - str[i] = 0; - - String res = make_string(str, i); - res = string_trim_whitespace(res); - return res; -} - -// NOTE(Jeroen): Naively turns a Path into a string, then normalizes it using `path_to_full_path`. -String path_to_full_path(gbAllocator a, Path path) { - String temp = path_to_string(heap_allocator(), path); - defer (gb_free(heap_allocator(), temp.text)); - - return path_to_full_path(a, temp); -} - -// NOTE(Jeroen): Takes a path like "odin" or "W:\Odin", turns it into a full path, -// and then breaks it into its components to make a Path. -Path path_from_string(gbAllocator a, String const &path) { - Path res = {}; - - if (path.len == 0) return res; - - String fullpath = path_to_full_path(a, path); - defer (gb_free(heap_allocator(), fullpath.text)); - - res.basename = directory_from_path(fullpath); - res.basename = copy_string(a, res.basename); - - if (string_ends_with(fullpath, '/')) { - // It's a directory. We don't need to tinker with the name and extension. - return res; - } - - isize name_start = (res.basename.len > 0) ? res.basename.len + 1 : res.basename.len; - res.name = substring(fullpath, name_start, fullpath.len); - res.name = remove_extension_from_path(res.name); - res.name = copy_string(a, res.name); - - res.ext = path_extension(fullpath, false); // false says not to include the dot. - res.ext = copy_string(a, res.ext); - return res; -} - -bool path_is_directory(Path path) { - String path_string = path_to_full_path(heap_allocator(), path); - defer (gb_free(heap_allocator(), path_string.text)); - - return path_is_directory(path_string); -} - -struct FileInfo { - String name; - String fullpath; - i64 size; - bool is_dir; -}; - -enum ReadDirectoryError { - ReadDirectory_None, - - ReadDirectory_InvalidPath, - ReadDirectory_NotExists, - ReadDirectory_Permission, - ReadDirectory_NotDir, - ReadDirectory_Empty, - ReadDirectory_Unknown, - - ReadDirectory_COUNT, -}; - -i64 get_file_size(String path) { - char *c_str = alloc_cstring(heap_allocator(), path); - defer (gb_free(heap_allocator(), c_str)); - - gbFile f = {}; - gbFileError err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - if (err != gbFileError_None) { - return -1; - } - return gb_file_size(&f); -} - - -#if defined(GB_SYSTEM_WINDOWS) -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - while (path.len > 0) { - Rune end = path[path.len-1]; - if (end == '/') { - path.len -= 1; - } else if (end == '\\') { - path.len -= 1; - } else { - break; - } - } - - if (path.len == 0) { - return ReadDirectory_InvalidPath; - } - { - char *c_str = alloc_cstring(a, path); - defer (gb_free(a, c_str)); - - gbFile f = {}; - gbFileError file_err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - - switch (file_err) { - case gbFileError_Invalid: return ReadDirectory_InvalidPath; - case gbFileError_NotExists: return ReadDirectory_NotExists; - // case gbFileError_Permission: return ReadDirectory_Permission; - } - } - - if (!path_is_directory(path)) { - return ReadDirectory_NotDir; - } - - - char *new_path = gb_alloc_array(a, char, path.len+3); - defer (gb_free(a, new_path)); - - gb_memmove(new_path, path.text, path.len); - gb_memmove(new_path+path.len, "/*", 2); - new_path[path.len+2] = 0; - - String np = make_string(cast(u8 *)new_path, path.len+2); - String16 wstr = string_to_string16(a, np); - defer (gb_free(a, wstr.text)); - - WIN32_FIND_DATAW file_data = {}; - HANDLE find_file = FindFirstFileW(wstr.text, &file_data); - if (find_file == INVALID_HANDLE_VALUE) { - return ReadDirectory_Unknown; - } - defer (FindClose(find_file)); - - array_init(fi, a, 0, 100); - - do { - wchar_t *filename_w = file_data.cFileName; - i64 size = cast(i64)file_data.nFileSizeLow; - size |= (cast(i64)file_data.nFileSizeHigh) << 32; - String name = string16_to_string(a, make_string16_c(filename_w)); - if (name == "." || name == "..") { - gb_free(a, name.text); - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - array_add(fi, info); - } while (FindNextFileW(find_file, &file_data)); - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) - -#include - -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - char *c_path = alloc_cstring(a, path); - defer (gb_free(a, c_path)); - - DIR *dir = opendir(c_path); - if (!dir) { - switch (errno) { - case ENOENT: - return ReadDirectory_NotExists; - case EACCES: - return ReadDirectory_Permission; - case ENOTDIR: - return ReadDirectory_NotDir; - default: - // ENOMEM: out of memory - // EMFILE: per-process limit on open fds reached - // ENFILE: system-wide limit on total open files reached - return ReadDirectory_Unknown; - } - GB_PANIC("unreachable"); - } - - array_init(fi, a, 0, 100); - - for (;;) { - struct dirent *entry = readdir(dir); - if (entry == nullptr) { - break; - } - - String name = make_string_c(entry->d_name); - if (name == "." || name == "..") { - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - filepath.text[filepath.len] = 0; - - - struct stat dir_stat = {}; - - if (stat((char *)filepath.text, &dir_stat)) { - continue; - } - - if (S_ISDIR(dir_stat.st_mode)) { - continue; - } - - i64 size = dir_stat.st_size; - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - array_add(fi, info); - } - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#else -#error Implement read_directory -#endif - diff --git a/src/string.cpp b/src/string.cpp index 3515df48e..d3dbc6904 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -245,14 +245,15 @@ gb_inline isize string_extension_position(String const &str) { return dot_pos; } -String path_extension(String const &str, bool include_dot = true) { +String path_extension(String const &str) { isize pos = string_extension_position(str); if (pos < 0) { return make_string(nullptr, 0); } - return substring(str, include_dot ? pos : pos + 1, str.len); + return substring(str, pos, str.len); } + String string_trim_whitespace(String str) { while (str.len > 0 && rune_is_whitespace(str[str.len-1])) { str.len--; @@ -327,10 +328,7 @@ String directory_from_path(String const &s) { break; } } - if (i >= 0) { - return substring(s, 0, i); - } - return substring(s, 0, 0); + return substring(s, 0, i); } String concatenate_strings(gbAllocator a, String const &x, String const &y) { diff --git a/tests/core/Makefile b/tests/core/Makefile index 9bb622633..6a92b4efb 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -1,6 +1,5 @@ ODIN=../../odin PYTHON=$(shell which python3) -OUT_FILE=test_binary.bin all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test @@ -9,39 +8,39 @@ download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin -out=$(OUT_FILE) -file + $(ODIN) run image/test_core_image.odin -file compress_test: - $(ODIN) run compress/test_core_compress.odin -out=$(OUT_FILE) -file + $(ODIN) run compress/test_core_compress.odin -file strings_test: - $(ODIN) run strings/test_core_strings.odin -out=$(OUT_FILE) -file + $(ODIN) run strings/test_core_strings.odin -file hash_test: - $(ODIN) run hash -out=$(OUT_FILE) -o:speed -no-bounds-check + $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check crypto_test: - $(ODIN) run crypto -out=$(OUT_FILE) -o:speed -no-bounds-check + $(ODIN) run crypto -out=test_crypto_hash -o:speed -no-bounds-check noise_test: - $(ODIN) run math/noise -out=$(OUT_FILE) + $(ODIN) run math/noise -out=test_noise encoding_test: - $(ODIN) run encoding/hxa -out=$(OUT_FILE) -collection:tests=.. - $(ODIN) run encoding/json -out=$(OUT_FILE) - $(ODIN) run encoding/varint -out=$(OUT_FILE) + $(ODIN) run encoding/hxa -out=test_hxa -collection:tests=.. + $(ODIN) run encoding/json -out=test_json + $(ODIN) run encoding/varint -out=test_varint math_test: - $(ODIN) run math/test_core_math.odin -out=$(OUT_FILE) -file -collection:tests=.. + $(ODIN) run math/test_core_math.odin -out=test_core_math -file -collection:tests=.. linalg_glsl_math_test: - $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=test_linalg_glsl_math -collection:tests=.. filepath_test: - $(ODIN) run path/filepath/test_core_filepath.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run path/filepath/test_core_filepath.odin -file -out=test_core_filepath -collection:tests=.. reflect_test: - $(ODIN) run reflect/test_core_reflect.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run reflect/test_core_reflect.odin -file -out=test_core_reflect -collection:tests=.. os_exit_test: - $(ODIN) run os/test_core_os_exit.odin -file -out=$(OUT_FILE) && exit 1 || exit 0 + $(ODIN) run os/test_core_os_exit.odin -file -out=test_core_os_exit && exit 1 || exit 0 diff --git a/tests/core/build.bat b/tests/core/build.bat index 331a473aa..2f9ba672e 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -1,8 +1,6 @@ @echo off -set OUT_FILE=test_binary.exe -set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. -out:%OUT_FILE% +set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. set PATH_TO_ODIN==..\..\odin - python3 download_assets.py echo --- echo Running core:image tests @@ -37,14 +35,14 @@ echo --- echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -%PATH_TO_ODIN% run encoding/json %COMMON% +%PATH_TO_ODIN% run encoding/hxa %COMMON% +%PATH_TO_ODIN% run encoding/json %COMMON% %PATH_TO_ODIN% run encoding/varint %COMMON% echo --- echo Running core:math/noise tests echo --- -%PATH_TO_ODIN% run math/noise %COMMON% +%PATH_TO_ODIN% run math/noise %COMMON% echo --- echo Running core:math tests diff --git a/tests/core/math/big/build.bat b/tests/core/math/big/build.bat index ad199d775..16bdbc8ca 100644 --- a/tests/core/math/big/build.bat +++ b/tests/core/math/big/build.bat @@ -4,7 +4,7 @@ set PATH_TO_ODIN==..\..\..\..\odin set TEST_ARGS=-fast-tests set TEST_ARGS=-no-random set TEST_ARGS= -set OUT_NAME=math_big_test_library.dll +set OUT_NAME=math_big_test_library set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style echo --- echo Running core:math/big tests diff --git a/tests/issues/run.bat b/tests/issues/run.bat index a936bd896..a652d9694 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -1,12 +1,17 @@ @echo off -set PATH_TO_ODIN==..\..\odin -set COMMON=-collection:tests=.. -out:build\test_issue -if not exist "build" mkdir build -%PATH_TO_ODIN% build test_issue_829.odin %COMMON% -file -build\test_issue +if not exist "tests\issues\build\" mkdir tests\issues\build -%PATH_TO_ODIN% build test_issue_1592.odin %COMMON% -file -build\test_issue +set COMMON=-collection:tests=tests -out:tests\issues\build\test_issue -rmdir /S /Q build +@echo on + +.\odin build tests\issues\test_issue_829.odin %COMMON% -file +tests\issues\build\test_issue + +.\odin build tests\issues\test_issue_1592.odin %COMMON% -file +tests\issues\build\test_issue + +@echo off + +rmdir /S /Q tests\issues\build diff --git a/tests/issues/run.sh b/tests/issues/run.sh index ec6d7130d..117a9a5f1 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -1,17 +1,18 @@ #!/bin/bash -ODIN=../../odin -COMMON="-collection:tests=.. -out:build/test_issue.bin" - set -eu -mkdir -p build + +mkdir -p tests/issues/build + +COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" + set -x -$ODIN build test_issue_829.odin $COMMON -file -build/test_issue.bin +./odin build tests/issues/test_issue_829.odin $COMMON -file +tests/issues/build/test_issue -$ODIN build test_issue_1592.odin $COMMON -file -build/test_issue.bin +./odin build tests/issues/test_issue_1592.odin $COMMON -file +tests/issues/build/test_issue set +x -rm -rf build +rm -rf tests/issues/build diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index 380e64e09..341067c6e 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -1,6 +1,5 @@ ODIN=../../odin ODINFLAGS= -OUT_FILE=test_binary.bin OS=$(shell uname) @@ -11,4 +10,4 @@ endif all: botan_test botan_test: - $(ODIN) run botan -out=$(OUT_FILE) -o:speed -no-bounds-check $(ODINFLAGS) + $(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check $(ODINFLAGS) diff --git a/tests/vendor/build.bat b/tests/vendor/build.bat index 4bd9a6496..e70d9f1d5 100644 --- a/tests/vendor/build.bat +++ b/tests/vendor/build.bat @@ -1,6 +1,5 @@ @echo off -set OUT_FILE=test_binary.exe -set COMMON=-show-timings -no-bounds-check -vet -strict-style -out:%OUT_FILE% +set COMMON=-show-timings -no-bounds-check -vet -strict-style set PATH_TO_ODIN==..\..\odin echo --- From e01662c13959469c9c0bc4974a3b7c03d577d7a4 Mon Sep 17 00:00:00 2001 From: Florian Behr Date: Mon, 25 Apr 2022 13:23:05 +0200 Subject: [PATCH 076/245] Make allocator in pool_add_task() explicit --- core/thread/thread_pool.odin | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 3f782cf73..fe289d8aa 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -113,9 +113,8 @@ pool_join :: proc(pool: ^Pool) { // the thread pool. You can even add tasks from inside other tasks. // // Each task also needs an allocator which it either owns, or which is thread -// safe. By default, allocations in the task are disabled by use of the -// nil_allocator. -pool_add_task :: proc(pool: ^Pool, procedure: Task_Proc, data: rawptr, user_index: int = 0, allocator := context.allocator) { +// safe. +pool_add_task :: proc(pool: ^Pool, procedure: Task_Proc, data: rawptr, user_index: int = 0, allocator: mem.Allocator) { sync.guard(&pool.mutex) append(&pool.tasks, Task{ From 1fb76ad7687bc9efe538b79ac05dc0fafad06950 Mon Sep 17 00:00:00 2001 From: Florian Behr Date: Mon, 25 Apr 2022 13:41:19 +0200 Subject: [PATCH 077/245] change usage in demo.odin --- examples/demo/demo.odin | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index b03345849..a36acdf18 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1166,7 +1166,8 @@ threading_example :: proc() { for i in 0..<30 { - thread.pool_add_task(pool=&pool, procedure=task_proc, data=nil, user_index=i) + // be mindful of the allocator used for tasks. The allocator needs to be thread safe, or be owned by the task for exclusive use + thread.pool_add_task(pool=&pool, procedure=task_proc, data=nil, user_index=i, allocator=context.allocator) } thread.pool_start(&pool) From ca6a1db7576dd72f5a5b4b73fec8cbad34e5bced Mon Sep 17 00:00:00 2001 From: Florian Behr Date: Mon, 25 Apr 2022 13:41:39 +0200 Subject: [PATCH 078/245] fix doc comment for pool_init --- core/thread/thread_pool.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index fe289d8aa..4fc02309e 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -44,7 +44,7 @@ Pool :: struct { } // Once initialized, the pool's memory address is not allowed to change until -// it is destroyed. If thread_count < 1, thread count 1 will be used. +// it is destroyed. // // The thread pool requires an allocator which it either owns, or which is thread safe. pool_init :: proc(pool: ^Pool, thread_count: int, allocator: mem.Allocator) { From ee67a0b9a1d83acad3e8ade9314bdad3bb0d2197 Mon Sep 17 00:00:00 2001 From: Florian Behr Date: Mon, 25 Apr 2022 14:08:09 +0200 Subject: [PATCH 079/245] reorder procedure parameters to make sure the optional argument in pool_add_task() is last, and the argument order is consistent with pool_init() --- core/thread/thread_pool.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 4fc02309e..af80da9aa 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -47,7 +47,7 @@ Pool :: struct { // it is destroyed. // // The thread pool requires an allocator which it either owns, or which is thread safe. -pool_init :: proc(pool: ^Pool, thread_count: int, allocator: mem.Allocator) { +pool_init :: proc(pool: ^Pool, allocator: mem.Allocator, thread_count: int) { context.allocator = allocator pool.allocator = allocator pool.tasks = make([dynamic]Task) @@ -114,7 +114,7 @@ pool_join :: proc(pool: ^Pool) { // // Each task also needs an allocator which it either owns, or which is thread // safe. -pool_add_task :: proc(pool: ^Pool, procedure: Task_Proc, data: rawptr, user_index: int = 0, allocator: mem.Allocator) { +pool_add_task :: proc(pool: ^Pool, allocator: mem.Allocator, procedure: Task_Proc, data: rawptr, user_index: int = 0) { sync.guard(&pool.mutex) append(&pool.tasks, Task{ From a412d34574649cceacea6a171ccd4af6119c7a0f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 11:35:34 +0100 Subject: [PATCH 080/245] Fix #1740 --- core/mem/virtual/virtual.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 2035171a7..21ab5ef21 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -120,7 +120,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) do_commit_if_necessary :: proc(block: ^Memory_Block, size: uint) -> (err: Allocator_Error) { if block.committed - block.used < size { pmblock := (^Platform_Memory_Block)(block) - base_offset := uint(uintptr(block) - uintptr(pmblock)) + base_offset := uint(uintptr(pmblock.block.base) - uintptr(pmblock)) platform_total_commit := base_offset + block.used + size assert(pmblock.committed <= pmblock.reserved) From 530401e5ee84bd3346b6a3213814a904696019df Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 11:38:32 +0100 Subject: [PATCH 081/245] Fix #1729 --- src/check_type.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/check_type.cpp b/src/check_type.cpp index 51f472961..c0ae64baa 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1338,14 +1338,14 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type * } } } - } else if (allow_caller_location && o.mode == Addressing_Context) { + } else if (allow_caller_location && (o.mode == Addressing_Context || are_types_identical(o.type, t_source_code_location))) { param_value.kind = ParameterValue_Value; param_value.ast_value = expr; } else if (o.value.kind != ExactValue_Invalid) { param_value.kind = ParameterValue_Constant; param_value.value = o.value; } else { - error(expr, "Default parameter must be a constant, %d", o.mode); + error(expr, "Default parameter must be a constant"); } } } else { From 3bd71229596427d43551ff6612d71505bb79c796 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 11:42:01 +0100 Subject: [PATCH 082/245] Fix #1720 --- vendor/vulkan/_gen/create_vulkan_odin_wrapper.py | 3 +++ vendor/vulkan/core.odin | 3 +++ 2 files changed, 6 insertions(+) diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index ae1bc8d64..9a32f5796 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -626,6 +626,9 @@ with open("../core.odin", 'w', encoding='utf-8') as f: f.write(BASE) f.write(""" API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) +API_VERSION_1_1 :: (1<<22) | (1<<12) | (0) +API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) +API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { return (major<<22) | (minor<<12) | (patch) diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index 94c667910..b90bfad17 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -3,6 +3,9 @@ // package vulkan API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) +API_VERSION_1_1 :: (1<<22) | (1<<12) | (0) +API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) +API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { return (major<<22) | (minor<<12) | (patch) From c81fd2e5dd82fba0d5a1eb6771b1816cdb4ba574 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 11:45:46 +0100 Subject: [PATCH 083/245] Fix #1644 --- core/math/linalg/specific.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin index cb007bd91..a4aaeb012 100644 --- a/core/math/linalg/specific.odin +++ b/core/math/linalg/specific.odin @@ -479,21 +479,21 @@ angle_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 { if abs(q.w) > math.SQRT_THREE*0.5 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 { if abs(q.w) > math.SQRT_THREE*0.5 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion :: proc{ angle_from_quaternion_f16, From a5342a01267f55dec5a5b9f775cec8c8379139b1 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 13:14:09 +0200 Subject: [PATCH 084/245] Address edge cases. --- .github/workflows/ci.yml | 11 ++---- .gitignore | 1 - Makefile | 4 +-- build_odin.sh | 4 +-- core/crypto/util/util.odin | 1 - src/build_settings.cpp | 42 ++++++++++++++++++---- src/path.cpp | 67 +++++++++++++++++++++++++++++++++-- src/string.cpp | 35 ------------------ tests/core/Makefile | 29 ++++++++------- tests/core/build.bat | 10 +++--- tests/core/math/big/build.bat | 2 +- tests/issues/run.bat | 21 ++++++----- tests/issues/run.sh | 19 +++++----- tests/vendor/Makefile | 3 +- tests/vendor/build.bat | 3 +- 15 files changed, 150 insertions(+), 102 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d72775636..3cc4283b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,9 +39,7 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: | - cd tests/issues - ./run.sh + run: tests/issues/run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -93,9 +91,7 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: | - cd tests/issues - ./run.sh + run: tests/issues/run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -167,8 +163,7 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - cd tests\issues - call run.bat + call tests\issues\run.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd diff --git a/.gitignore b/.gitignore index d03a86fd7..e8b3d3050 100644 --- a/.gitignore +++ b/.gitignore @@ -269,7 +269,6 @@ bin/ # - Linux/MacOS odin odin.dSYM -*.bin # shared collection shared/ diff --git a/Makefile b/Makefile index 1a1c93180..82150c6a2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: debug +all: debug demo demo: - ./odin run examples/demo + ./odin run examples/demo/demo.odin report: ./odin report diff --git a/build_odin.sh b/build_odin.sh index 4810cafd2..aef3f2836 100755 --- a/build_odin.sh +++ b/build_odin.sh @@ -102,7 +102,7 @@ build_odin() { } run_demo() { - ./odin run examples/demo + ./odin run examples/demo/demo.odin -file } case $OS in @@ -147,4 +147,4 @@ if [[ $# -eq 1 ]]; then exit 0 else panic "Too many arguments!" -fi \ No newline at end of file +fi diff --git a/core/crypto/util/util.odin b/core/crypto/util/util.odin index 83b07e546..6273a232e 100644 --- a/core/crypto/util/util.odin +++ b/core/crypto/util/util.odin @@ -11,7 +11,6 @@ package util */ import "core:mem" -_ :: mem // @note(bp): this can replace the other two cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D { diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 212ded5c8..89d370144 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1276,16 +1276,44 @@ bool init_build_paths(String init_filename) { if (bc->out_filepath.len > 0) { bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath); + if (build_context.metrics.os == TargetOs_windows) { + String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]); + defer (gb_free(ha, output_file.text)); + if (path_is_directory(bc->build_paths[BuildPath_Output])) { + gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file)); + return false; + } else if (bc->build_paths[BuildPath_Output].ext.len == 0) { + gb_printf_err("Output path %.*s must have an appropriate extension.\n", LIT(output_file)); + return false; + } + } } else { - String output_name = remove_directory_from_path(init_filename); - output_name = remove_extension_from_path(output_name); - output_name = copy_string(ha, string_trim_whitespace(output_name)); + Path output_path; - Path output_path = path_from_string(ha, output_name); + if (str_eq(init_filename, str_lit("."))) { + // We must name the output file after the current directory. + debugf("Output name will be created from current base name %.*s.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename)); + String last_element = last_path_element(bc->build_paths[BuildPath_Main_Package].basename); - // Replace extension. - if (output_path.ext.len > 0) { - gb_free(ha, output_path.ext.text); + if (last_element.len == 0) { + gb_printf_err("The output name is created from the last path element. `%.*s` has none. Use `-out:output_name.ext` to set it.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename)); + return false; + } + output_path.basename = copy_string(ha, bc->build_paths[BuildPath_Main_Package].basename); + output_path.name = copy_string(ha, last_element); + + } else { + // Init filename was not 'current path'. + // Contruct the output name from the path elements as usual. + String output_name = remove_directory_from_path(init_filename); + output_name = remove_extension_from_path(output_name); + output_name = copy_string(ha, string_trim_whitespace(output_name)); + output_path = path_from_string(ha, output_name); + + // Replace extension. + if (output_path.ext.len > 0) { + gb_free(ha, output_path.ext.text); + } } output_path.ext = copy_string(ha, output_extension); diff --git a/src/path.cpp b/src/path.cpp index 8d8e532b8..6f83c39ea 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -1,6 +1,46 @@ /* Path handling utilities. */ +String remove_extension_from_path(String const &s) { + for (isize i = s.len-1; i >= 0; i--) { + if (s[i] == '.') { + return substring(s, 0, i); + } + } + return s; +} + +String remove_directory_from_path(String const &s) { + isize len = 0; + for (isize i = s.len-1; i >= 0; i--) { + if (s[i] == '/' || + s[i] == '\\') { + break; + } + len += 1; + } + return substring(s, s.len-len, s.len); +} + +bool path_is_directory(String path); + +String directory_from_path(String const &s) { + if (path_is_directory(s)) { + return s; + } + + isize i = s.len-1; + for (; i >= 0; i--) { + if (s[i] == '/' || + s[i] == '\\') { + break; + } + } + if (i >= 0) { + return substring(s, 0, i); + } + return substring(s, 0, 0); +} #if defined(GB_SYSTEM_WINDOWS) bool path_is_directory(String path) { @@ -98,11 +138,15 @@ Path path_from_string(gbAllocator a, String const &path) { String fullpath = path_to_full_path(a, path); defer (gb_free(heap_allocator(), fullpath.text)); - res.basename = directory_from_path(fullpath); - res.basename = copy_string(a, res.basename); + res.basename = directory_from_path(fullpath); + res.basename = copy_string(a, res.basename); - if (string_ends_with(fullpath, '/')) { + if (path_is_directory(fullpath)) { // It's a directory. We don't need to tinker with the name and extension. + // It could have a superfluous trailing `/`. Remove it if so. + if (res.basename.len > 0 && res.basename.text[res.basename.len - 1] == '/') { + res.basename.len--; + } return res; } @@ -116,6 +160,23 @@ Path path_from_string(gbAllocator a, String const &path) { return res; } +// NOTE(Jeroen): Takes a path String and returns the last path element. +String last_path_element(String const &path) { + isize count = 0; + u8 * start = (u8 *)(&path.text[path.len - 1]); + for (isize length = path.len; length > 0 && path.text[length - 1] != '/'; length--) { + count++; + start--; + } + if (count > 0) { + start++; // Advance past the `/` and return the substring. + String res = make_string(start, count); + return res; + } + // Must be a root path like `/` or `C:/`, return empty String. + return STR_LIT(""); +} + bool path_is_directory(Path path) { String path_string = path_to_full_path(heap_allocator(), path); defer (gb_free(heap_allocator(), path_string.text)); diff --git a/src/string.cpp b/src/string.cpp index 3515df48e..616761265 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -298,41 +298,6 @@ String filename_from_path(String s) { return make_string(nullptr, 0); } -String remove_extension_from_path(String const &s) { - for (isize i = s.len-1; i >= 0; i--) { - if (s[i] == '.') { - return substring(s, 0, i); - } - } - return s; -} - -String remove_directory_from_path(String const &s) { - isize len = 0; - for (isize i = s.len-1; i >= 0; i--) { - if (s[i] == '/' || - s[i] == '\\') { - break; - } - len += 1; - } - return substring(s, s.len-len, s.len); -} - -String directory_from_path(String const &s) { - isize i = s.len-1; - for (; i >= 0; i--) { - if (s[i] == '/' || - s[i] == '\\') { - break; - } - } - if (i >= 0) { - return substring(s, 0, i); - } - return substring(s, 0, 0); -} - String concatenate_strings(gbAllocator a, String const &x, String const &y) { isize len = x.len+y.len; u8 *data = gb_alloc_array(a, u8, len+1); diff --git a/tests/core/Makefile b/tests/core/Makefile index 9bb622633..6a92b4efb 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -1,6 +1,5 @@ ODIN=../../odin PYTHON=$(shell which python3) -OUT_FILE=test_binary.bin all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test @@ -9,39 +8,39 @@ download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin -out=$(OUT_FILE) -file + $(ODIN) run image/test_core_image.odin -file compress_test: - $(ODIN) run compress/test_core_compress.odin -out=$(OUT_FILE) -file + $(ODIN) run compress/test_core_compress.odin -file strings_test: - $(ODIN) run strings/test_core_strings.odin -out=$(OUT_FILE) -file + $(ODIN) run strings/test_core_strings.odin -file hash_test: - $(ODIN) run hash -out=$(OUT_FILE) -o:speed -no-bounds-check + $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check crypto_test: - $(ODIN) run crypto -out=$(OUT_FILE) -o:speed -no-bounds-check + $(ODIN) run crypto -out=test_crypto_hash -o:speed -no-bounds-check noise_test: - $(ODIN) run math/noise -out=$(OUT_FILE) + $(ODIN) run math/noise -out=test_noise encoding_test: - $(ODIN) run encoding/hxa -out=$(OUT_FILE) -collection:tests=.. - $(ODIN) run encoding/json -out=$(OUT_FILE) - $(ODIN) run encoding/varint -out=$(OUT_FILE) + $(ODIN) run encoding/hxa -out=test_hxa -collection:tests=.. + $(ODIN) run encoding/json -out=test_json + $(ODIN) run encoding/varint -out=test_varint math_test: - $(ODIN) run math/test_core_math.odin -out=$(OUT_FILE) -file -collection:tests=.. + $(ODIN) run math/test_core_math.odin -out=test_core_math -file -collection:tests=.. linalg_glsl_math_test: - $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=test_linalg_glsl_math -collection:tests=.. filepath_test: - $(ODIN) run path/filepath/test_core_filepath.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run path/filepath/test_core_filepath.odin -file -out=test_core_filepath -collection:tests=.. reflect_test: - $(ODIN) run reflect/test_core_reflect.odin -file -out=$(OUT_FILE) -collection:tests=.. + $(ODIN) run reflect/test_core_reflect.odin -file -out=test_core_reflect -collection:tests=.. os_exit_test: - $(ODIN) run os/test_core_os_exit.odin -file -out=$(OUT_FILE) && exit 1 || exit 0 + $(ODIN) run os/test_core_os_exit.odin -file -out=test_core_os_exit && exit 1 || exit 0 diff --git a/tests/core/build.bat b/tests/core/build.bat index 331a473aa..2f9ba672e 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -1,8 +1,6 @@ @echo off -set OUT_FILE=test_binary.exe -set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. -out:%OUT_FILE% +set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. set PATH_TO_ODIN==..\..\odin - python3 download_assets.py echo --- echo Running core:image tests @@ -37,14 +35,14 @@ echo --- echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -%PATH_TO_ODIN% run encoding/json %COMMON% +%PATH_TO_ODIN% run encoding/hxa %COMMON% +%PATH_TO_ODIN% run encoding/json %COMMON% %PATH_TO_ODIN% run encoding/varint %COMMON% echo --- echo Running core:math/noise tests echo --- -%PATH_TO_ODIN% run math/noise %COMMON% +%PATH_TO_ODIN% run math/noise %COMMON% echo --- echo Running core:math tests diff --git a/tests/core/math/big/build.bat b/tests/core/math/big/build.bat index ad199d775..16bdbc8ca 100644 --- a/tests/core/math/big/build.bat +++ b/tests/core/math/big/build.bat @@ -4,7 +4,7 @@ set PATH_TO_ODIN==..\..\..\..\odin set TEST_ARGS=-fast-tests set TEST_ARGS=-no-random set TEST_ARGS= -set OUT_NAME=math_big_test_library.dll +set OUT_NAME=math_big_test_library set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style echo --- echo Running core:math/big tests diff --git a/tests/issues/run.bat b/tests/issues/run.bat index a936bd896..a652d9694 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -1,12 +1,17 @@ @echo off -set PATH_TO_ODIN==..\..\odin -set COMMON=-collection:tests=.. -out:build\test_issue -if not exist "build" mkdir build -%PATH_TO_ODIN% build test_issue_829.odin %COMMON% -file -build\test_issue +if not exist "tests\issues\build\" mkdir tests\issues\build -%PATH_TO_ODIN% build test_issue_1592.odin %COMMON% -file -build\test_issue +set COMMON=-collection:tests=tests -out:tests\issues\build\test_issue -rmdir /S /Q build +@echo on + +.\odin build tests\issues\test_issue_829.odin %COMMON% -file +tests\issues\build\test_issue + +.\odin build tests\issues\test_issue_1592.odin %COMMON% -file +tests\issues\build\test_issue + +@echo off + +rmdir /S /Q tests\issues\build diff --git a/tests/issues/run.sh b/tests/issues/run.sh index ec6d7130d..117a9a5f1 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -1,17 +1,18 @@ #!/bin/bash -ODIN=../../odin -COMMON="-collection:tests=.. -out:build/test_issue.bin" - set -eu -mkdir -p build + +mkdir -p tests/issues/build + +COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" + set -x -$ODIN build test_issue_829.odin $COMMON -file -build/test_issue.bin +./odin build tests/issues/test_issue_829.odin $COMMON -file +tests/issues/build/test_issue -$ODIN build test_issue_1592.odin $COMMON -file -build/test_issue.bin +./odin build tests/issues/test_issue_1592.odin $COMMON -file +tests/issues/build/test_issue set +x -rm -rf build +rm -rf tests/issues/build diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index 380e64e09..341067c6e 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -1,6 +1,5 @@ ODIN=../../odin ODINFLAGS= -OUT_FILE=test_binary.bin OS=$(shell uname) @@ -11,4 +10,4 @@ endif all: botan_test botan_test: - $(ODIN) run botan -out=$(OUT_FILE) -o:speed -no-bounds-check $(ODINFLAGS) + $(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check $(ODINFLAGS) diff --git a/tests/vendor/build.bat b/tests/vendor/build.bat index 4bd9a6496..e70d9f1d5 100644 --- a/tests/vendor/build.bat +++ b/tests/vendor/build.bat @@ -1,6 +1,5 @@ @echo off -set OUT_FILE=test_binary.exe -set COMMON=-show-timings -no-bounds-check -vet -strict-style -out:%OUT_FILE% +set COMMON=-show-timings -no-bounds-check -vet -strict-style set PATH_TO_ODIN==..\..\odin echo --- From ec8221cb5def171deb5bea0cf4d6a935e74e33d2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 13:04:50 +0100 Subject: [PATCH 085/245] Simplify Atomic_Cond implementation --- core/sync/atomic.odin | 4 +- core/sync/primitives_atomic.odin | 109 +++++-------------------------- 2 files changed, 19 insertions(+), 94 deletions(-) diff --git a/core/sync/atomic.odin b/core/sync/atomic.odin index f537764c4..0900a6544 100644 --- a/core/sync/atomic.odin +++ b/core/sync/atomic.odin @@ -6,8 +6,8 @@ cpu_relax :: intrinsics.cpu_relax /* Atomic_Memory_Order :: enum { - Relaxed = 0, - Consume = 1, + Relaxed = 0, // Unordered + Consume = 1, // Monotonic Acquire = 2, Release = 3, Acq_Rel = 4, diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 11fff4e60..bd32eb192 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -281,118 +281,43 @@ atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool { - -@(private="file") -Queue_Item :: struct { - next: ^Queue_Item, - futex: Futex, -} - -@(private="file") -queue_item_wait :: proc(item: ^Queue_Item) { - for atomic_load_explicit(&item.futex, .Acquire) == 0 { - futex_wait(&item.futex, 0) - cpu_relax() - } -} -@(private="file") -queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) -> bool { - start := time.tick_now() - for atomic_load_explicit(&item.futex, .Acquire) == 0 { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false - } - if !futex_wait_with_timeout(&item.futex, 0, remaining) { - return false - } - cpu_relax() - } - return true -} -@(private="file") -queue_item_signal :: proc(item: ^Queue_Item) { - atomic_store_explicit(&item.futex, 1, .Release) - futex_signal(&item.futex) -} - - // Atomic_Cond implements a condition variable, a rendezvous point for threads // waiting for signalling the occurence of an event // // An Atomic_Cond must not be copied after first use Atomic_Cond :: struct { - queue_mutex: Atomic_Mutex, - queue_head: ^Queue_Item, - pending: bool, + state: Futex, + prev: u32, } atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) { - waiter := &Queue_Item{} + state := u32(atomic_load(&c.state)) + atomic_store(&c.prev, state) + unlock(m) + futex_wait(&c.state, state) + lock(m) - atomic_mutex_lock(&c.queue_mutex) - waiter.next = c.queue_head - c.queue_head = waiter - - atomic_store(&c.pending, true) - atomic_mutex_unlock(&c.queue_mutex) - - atomic_mutex_unlock(m) - queue_item_wait(waiter) - atomic_mutex_lock(m) } atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) { - waiter := &Queue_Item{} - - atomic_mutex_lock(&c.queue_mutex) - waiter.next = c.queue_head - c.queue_head = waiter - - atomic_store(&c.pending, true) - atomic_mutex_unlock(&c.queue_mutex) - - atomic_mutex_unlock(m) - ok = queue_item_wait_with_timeout(waiter, duration) - atomic_mutex_lock(m) + state := u32(atomic_load(&c.state)) + unlock(m) + ok = futex_wait_with_timeout(&c.state, state, duration) + lock(m) return } atomic_cond_signal :: proc(c: ^Atomic_Cond) { - if !atomic_load(&c.pending) { - return - } - - atomic_mutex_lock(&c.queue_mutex) - waiter := c.queue_head - if c.queue_head != nil { - c.queue_head = c.queue_head.next - } - atomic_store(&c.pending, c.queue_head != nil) - atomic_mutex_unlock(&c.queue_mutex) - - if waiter != nil { - queue_item_signal(waiter) - } + state := 1 + atomic_load(&c.prev) + atomic_store(&c.state, Futex(state)) + futex_signal(&c.state) } atomic_cond_broadcast :: proc(c: ^Atomic_Cond) { - if !atomic_load(&c.pending) { - return - } - - atomic_store(&c.pending, false) - - atomic_mutex_lock(&c.queue_mutex) - waiters := c.queue_head - c.queue_head = nil - atomic_mutex_unlock(&c.queue_mutex) - - for waiters != nil { - queue_item_signal(waiters) - waiters = waiters.next - } + state := 1 + atomic_load(&c.prev) + atomic_store(&c.state, Futex(state)) + futex_broadcast(&c.state) } // When waited upon, blocks until the internal count is greater than zero, then subtracts one. From 07d1a42768cd7082622fafc2bd01216e27bed54e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 13:11:34 +0100 Subject: [PATCH 086/245] Simplify `Atomic_Sema` implementation --- core/sync/primitives_atomic.odin | 65 +++++++++++++++----------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index bd32eb192..812e5ae97 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -325,30 +325,28 @@ atomic_cond_broadcast :: proc(c: ^Atomic_Cond) { // // An Atomic_Sema must not be copied after first use Atomic_Sema :: struct { - mutex: Atomic_Mutex, - cond: Atomic_Cond, - count: int, + count: Futex, } atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) { - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - s.count += count - atomic_cond_signal(&s.cond) + atomic_add_explicit(&s.count, Futex(count), .Release) + if count == 1 { + futex_signal(&s.count) + } else { + futex_broadcast(&s.count) + } } atomic_sema_wait :: proc(s: ^Atomic_Sema) { - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - for s.count == 0 { - atomic_cond_wait(&s.cond, &s.mutex) - } - - s.count -= 1 - if s.count > 0 { - atomic_cond_signal(&s.cond) + for { + original_count := atomic_load_explicit(&s.count, .Relaxed) + for original_count == 0 { + futex_wait(&s.count, u32(original_count)) + original_count = s.count + } + if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) { + return + } } } @@ -356,25 +354,22 @@ atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration) if duration <= 0 { return false } - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - start := time.tick_now() + for { - for s.count == 0 { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false + original_count := atomic_load_explicit(&s.count, .Relaxed) + for start := time.tick_now(); original_count == 0; /**/ { + remaining := duration - time.tick_since(start) + if remaining < 0 { + return false + } + + if !futex_wait_with_timeout(&s.count, u32(original_count), remaining) { + return false + } + original_count = s.count } - - if !atomic_cond_wait_with_timeout(&s.cond, &s.mutex, remaining) { - return false + if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) { + return true } } - - s.count -= 1 - if s.count > 0 { - atomic_cond_signal(&s.cond) - } - return true } From 5e11ad2e1e6d0e335f47197c63a5ffdd8f405dd7 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 14:23:23 +0200 Subject: [PATCH 087/245] Update test paths. --- .github/workflows/ci.yml | 11 ++++++++--- core/crypto/util/util.odin | 1 + tests/core/Makefile | 28 ++++++++++++++-------------- tests/core/build.bat | 28 ++++++++++++++-------------- tests/issues/run.bat | 14 +++++++------- tests/issues/run.sh | 16 ++++++++-------- tests/vendor/Makefile | 2 +- tests/vendor/build.bat | 4 ++-- 8 files changed, 55 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cc4283b0..d72775636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + run: | + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -91,7 +93,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + run: | + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -163,7 +167,8 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - call tests\issues\run.bat + cd tests\issues + call run.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd diff --git a/core/crypto/util/util.odin b/core/crypto/util/util.odin index 6273a232e..83b07e546 100644 --- a/core/crypto/util/util.odin +++ b/core/crypto/util/util.odin @@ -11,6 +11,7 @@ package util */ import "core:mem" +_ :: mem // @note(bp): this can replace the other two cast_slice :: #force_inline proc "contextless" ($D: typeid/[]$DE, src: $S/[]$SE) -> D { diff --git a/tests/core/Makefile b/tests/core/Makefile index 6a92b4efb..2c24fef75 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -8,39 +8,39 @@ download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin -file + $(ODIN) run image/test_core_image.odin -file -out:test_core_image compress_test: - $(ODIN) run compress/test_core_compress.odin -file + $(ODIN) run compress/test_core_compress.odin -file -out:test_core_compress strings_test: - $(ODIN) run strings/test_core_strings.odin -file + $(ODIN) run strings/test_core_strings.odin -file -out:test_core_strings hash_test: - $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check + $(ODIN) run hash -o:speed -no-bounds-check -out:test_hash crypto_test: - $(ODIN) run crypto -out=test_crypto_hash -o:speed -no-bounds-check + $(ODIN) run crypto -o:speed -no-bounds-check -out:test_crypto_hash noise_test: - $(ODIN) run math/noise -out=test_noise + $(ODIN) run math/noise -out:test_noise encoding_test: - $(ODIN) run encoding/hxa -out=test_hxa -collection:tests=.. - $(ODIN) run encoding/json -out=test_json - $(ODIN) run encoding/varint -out=test_varint + $(ODIN) run encoding/hxa -collection:tests=.. -out:test_hxa + $(ODIN) run encoding/json -out:test_json + $(ODIN) run encoding/varint -out:test_varint math_test: - $(ODIN) run math/test_core_math.odin -out=test_core_math -file -collection:tests=.. + $(ODIN) run math/test_core_math.odin -file -collection:tests=.. -out:test_core_math linalg_glsl_math_test: - $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -out=test_linalg_glsl_math -collection:tests=.. + $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -collection:tests=.. -out:test_linalg_glsl_math filepath_test: - $(ODIN) run path/filepath/test_core_filepath.odin -file -out=test_core_filepath -collection:tests=.. + $(ODIN) run path/filepath/test_core_filepath.odin -file -collection:tests=.. -out:test_core_filepath reflect_test: - $(ODIN) run reflect/test_core_reflect.odin -file -out=test_core_reflect -collection:tests=.. + $(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect os_exit_test: - $(ODIN) run os/test_core_os_exit.odin -file -out=test_core_os_exit && exit 1 || exit 0 + $(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0 \ No newline at end of file diff --git a/tests/core/build.bat b/tests/core/build.bat index 2f9ba672e..b03fef4bb 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -5,61 +5,61 @@ python3 download_assets.py echo --- echo Running core:image tests echo --- -%PATH_TO_ODIN% run image %COMMON% +%PATH_TO_ODIN% run image %COMMON% -out:test_core_image.exe echo --- echo Running core:compress tests echo --- -%PATH_TO_ODIN% run compress %COMMON% +%PATH_TO_ODIN% run compress %COMMON% -out:test_core_compress.exe echo --- echo Running core:strings tests echo --- -%PATH_TO_ODIN% run strings %COMMON% +%PATH_TO_ODIN% run strings %COMMON% -out:test_core_strings.exe echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size +%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe echo --- echo Running core:odin tests echo --- -%PATH_TO_ODIN% run odin %COMMON% -o:size +%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_core_odin.exe echo --- echo Running core:crypto hash tests echo --- -%PATH_TO_ODIN% run crypto %COMMON% +%PATH_TO_ODIN% run crypto %COMMON% -out:test_crypto_hash.exe echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -%PATH_TO_ODIN% run encoding/json %COMMON% -%PATH_TO_ODIN% run encoding/varint %COMMON% +%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa.exe +%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe +%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe echo --- echo Running core:math/noise tests echo --- -%PATH_TO_ODIN% run math/noise %COMMON% +%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise.exe echo --- echo Running core:math tests echo --- -%PATH_TO_ODIN% run math %COMMON% +%PATH_TO_ODIN% run math %COMMON% -out:test_core_math.exe echo --- echo Running core:math/linalg/glsl tests echo --- -%PATH_TO_ODIN% run math/linalg/glsl %COMMON% +%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_linalg_glsl.exe echo --- echo Running core:path/filepath tests echo --- -%PATH_TO_ODIN% run path/filepath %COMMON% +%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_core_filepath.exe echo --- echo Running core:reflect tests echo --- -%PATH_TO_ODIN% run reflect %COMMON% +%PATH_TO_ODIN% run reflect %COMMON% -out:test_core_reflect.exe \ No newline at end of file diff --git a/tests/issues/run.bat b/tests/issues/run.bat index a652d9694..a7078ae0f 100644 --- a/tests/issues/run.bat +++ b/tests/issues/run.bat @@ -1,17 +1,17 @@ @echo off -if not exist "tests\issues\build\" mkdir tests\issues\build +if not exist "build\" mkdir build -set COMMON=-collection:tests=tests -out:tests\issues\build\test_issue +set COMMON=-collection:tests=.. -out:build\test_issue.exe @echo on -.\odin build tests\issues\test_issue_829.odin %COMMON% -file -tests\issues\build\test_issue +..\..\odin build test_issue_829.odin %COMMON% -file +build\test_issue -.\odin build tests\issues\test_issue_1592.odin %COMMON% -file -tests\issues\build\test_issue +..\..\odin build test_issue_1592.odin %COMMON% -file +build\test_issue @echo off -rmdir /S /Q tests\issues\build +rmdir /S /Q build diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 117a9a5f1..ec0804bac 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -1,18 +1,18 @@ #!/bin/bash set -eu -mkdir -p tests/issues/build - -COMMON="-collection:tests=tests -out:tests/issues/build/test_issue" +mkdir -p build +ODIN=../../odin +COMMON="-collection:tests=.. -out:build/test_issue" set -x -./odin build tests/issues/test_issue_829.odin $COMMON -file -tests/issues/build/test_issue +$ODIN build test_issue_829.odin $COMMON -file +./build/test_issue -./odin build tests/issues/test_issue_1592.odin $COMMON -file -tests/issues/build/test_issue +$ODIN build test_issue_1592.odin $COMMON -file +./build/test_issue set +x -rm -rf tests/issues/build +rm -rf build diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index 341067c6e..6c68d7908 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -10,4 +10,4 @@ endif all: botan_test botan_test: - $(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check $(ODINFLAGS) + $(ODIN) run botan -o:speed -no-bounds-check $(ODINFLAGS) -out=vendor_botan diff --git a/tests/vendor/build.bat b/tests/vendor/build.bat index e70d9f1d5..d92a5eaea 100644 --- a/tests/vendor/build.bat +++ b/tests/vendor/build.bat @@ -5,9 +5,9 @@ set PATH_TO_ODIN==..\..\odin echo --- echo Running vendor:botan tests echo --- -%PATH_TO_ODIN% run botan %COMMON% +%PATH_TO_ODIN% run botan %COMMON% -out:vendor_botan.exe echo --- echo Running vendor:glfw tests echo --- -%PATH_TO_ODIN% run glfw %COMMON% \ No newline at end of file +%PATH_TO_ODIN% run glfw %COMMON% -out:vendor_glfw.exe \ No newline at end of file From 9cf7a31068bb8f9bf63c6e7e8f350125334ea406 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 13:44:32 +0100 Subject: [PATCH 088/245] Implement `_Sema` with `Atomic_Sema` --- core/sync/sema_internal.odin | 42 ++++-------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/core/sync/sema_internal.odin b/core/sync/sema_internal.odin index e4a3c0bfc..8188abe28 100644 --- a/core/sync/sema_internal.odin +++ b/core/sync/sema_internal.odin @@ -6,53 +6,19 @@ import "core:time" when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { _Sema :: struct { - count: Futex, + sema: Atomic_Sema, } _sema_post :: proc(s: ^Sema, count := 1) { - atomic_add_explicit(&s.impl.count, Futex(count), .Release) - if count == 1 { - futex_signal(&s.impl.count) - } else { - futex_broadcast(&s.impl.count) - } + atomic_sema_post(&s.impl.sema, count) } _sema_wait :: proc(s: ^Sema) { - for { - original_count := atomic_load_explicit(&s.impl.count, .Relaxed) - for original_count == 0 { - futex_wait(&s.impl.count, u32(original_count)) - original_count = s.impl.count - } - if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { - return - } - } + atomic_sema_wait(&s.impl.sema) } _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { - if duration <= 0 { - return false - } - for { - - original_count := atomic_load_explicit(&s.impl.count, .Relaxed) - for start := time.tick_now(); original_count == 0; /**/ { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false - } - - if !futex_wait_with_timeout(&s.impl.count, u32(original_count), remaining) { - return false - } - original_count = s.impl.count - } - if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { - return true - } - } + return atomic_sema_wait_with_timeout(&s.impl.sema, duration) } } else { _Sema :: struct { From ba5e33bc3518c327057102f56ac2c1cce55dc76f Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 14:51:16 +0200 Subject: [PATCH 089/245] Update CI workflow. --- .github/workflows/ci.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cc4283b0..a5a6eddb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + run: | + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -91,7 +93,8 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - run: tests/issues/run.sh + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 @@ -163,7 +166,8 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - call tests\issues\run.bat + cd tests\issues + call run.bat timeout-minutes: 10 - name: Odin check examples/all for Windows 32bits shell: cmd From 1c03e6805775c58044d417eea2504312b4e916ab Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 14:56:28 +0200 Subject: [PATCH 090/245] Update CI. --- .github/workflows/ci.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5a6eddb1..d72775636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,8 +40,8 @@ jobs: timeout-minutes: 10 - name: Odin issues tests run: | - cd tests/issues - ./run.sh + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Linux i386 run: ./odin check examples/all -vet -strict-style -target:linux_i386 @@ -93,8 +93,9 @@ jobs: make timeout-minutes: 10 - name: Odin issues tests - cd tests/issues - ./run.sh + run: | + cd tests/issues + ./run.sh timeout-minutes: 10 - name: Odin check examples/all for Darwin arm64 run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 From 40f0f5ad8dd56691ae42e9dd4b9a2f5e5395f3ee Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 15:01:09 +0200 Subject: [PATCH 091/245] Update CI for math library. --- tests/core/math/big/build.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/math/big/build.bat b/tests/core/math/big/build.bat index 16bdbc8ca..ad199d775 100644 --- a/tests/core/math/big/build.bat +++ b/tests/core/math/big/build.bat @@ -4,7 +4,7 @@ set PATH_TO_ODIN==..\..\..\..\odin set TEST_ARGS=-fast-tests set TEST_ARGS=-no-random set TEST_ARGS= -set OUT_NAME=math_big_test_library +set OUT_NAME=math_big_test_library.dll set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style echo --- echo Running core:math/big tests From d262eda91c527880a95f70a3d6fa20346c1d20d6 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 26 Apr 2022 15:10:31 +0200 Subject: [PATCH 092/245] Update Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 82150c6a2..91010a620 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -all: debug demo +all: debug demo: - ./odin run examples/demo/demo.odin + ./odin run examples/demo/demo.odin -file report: ./odin report From a6cef2e50ea4867f02bac5442debfa1de0743681 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Apr 2022 21:47:45 +0100 Subject: [PATCH 093/245] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 9ca94bcdf..9a87ab8da 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2021 Ginger Bill. All rights reserved. +Copyright (c) 2016-2022 Ginger Bill. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: From 96924969895d78d93e8f39158a0409a6a2c214ab Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 12:27:53 +0100 Subject: [PATCH 094/245] Add `intrinsics.type_field_type` --- core/intrinsics/intrinsics.odin | 1 + src/check_builtin.cpp | 31 +++++++++++++++++++++++++++++++ src/checker_builtin_procs.hpp | 2 ++ 3 files changed, 34 insertions(+) diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index a25e9783d..c132d4095 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -153,6 +153,7 @@ type_is_specialization_of :: proc($T, $S: typeid) -> bool --- type_is_variant_of :: proc($U, $V: typeid) -> bool where type_is_union(U) --- type_has_field :: proc($T: typeid, $name: string) -> bool --- +type_field_type :: proc($T: typeid, $name: string) -> typeid --- type_proc_parameter_count :: proc($T: typeid) -> int where type_is_proc(T) --- type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) --- diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index e055539c5..6c7972d45 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -3926,6 +3926,37 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } break; + case BuiltinProc_type_field_type: + { + Operand op = {}; + Type *bt = check_type(c, ce->args[0]); + Type *type = base_type(bt); + if (type == nullptr || type == t_invalid) { + error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr(c, &x, ce->args[1]); + + if (!is_type_string(x.type) || x.mode != Addressing_Constant || x.value.kind != ExactValue_String) { + error(ce->args[1], "Expected a const string for field argument"); + return false; + } + + String field_name = x.value.value_string; + + Selection sel = lookup_field(type, field_name, false); + if (sel.index.count == 0) { + gbString t = type_to_string(type); + error(ce->args[1], "'%.*s' is not a field of type %s", LIT(field_name), t); + gb_string_free(t); + return false; + } + operand->mode = Addressing_Type; + operand->type = sel.entity->type; + break; + } + break; case BuiltinProc_type_is_specialization_of: { diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index fe14ae372..0f72f01f7 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -179,6 +179,7 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc__type_simple_boolean_end, BuiltinProc_type_has_field, + BuiltinProc_type_field_type, BuiltinProc_type_is_specialization_of, @@ -395,6 +396,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("type_has_field"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_field_type"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_specialization_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, From 9349dfba8fec53f52f77a0c8928e115ec93ff447 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 12:39:45 +0100 Subject: [PATCH 095/245] Add new builtin `container_of` --- core/runtime/core_builtin.odin | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 67b1bd37b..13e464a76 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -5,6 +5,16 @@ import "core:intrinsics" @builtin Maybe :: union($T: typeid) #maybe {T} + +@builtin +container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T + where intrinsics.type_has_field(T, field_name), + intrinsics.type_field_type(T, field_name) == Field_Type { + offset :: offset_of_by_string(T, field_name) + return (^T)(uintptr(ptr) - offset) if ptr != nil else nil +} + + @thread_local global_default_temp_allocator_data: Default_Temp_Allocator @builtin From 3a9b0a22e728d1158efccb7f90e2c8aa05c486ef Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 14:27:33 +0100 Subject: [PATCH 096/245] Add `core:container/intrusive/list` --- .../intrusive/list/intrusive_list.odin | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 core/container/intrusive/list/intrusive_list.odin diff --git a/core/container/intrusive/list/intrusive_list.odin b/core/container/intrusive/list/intrusive_list.odin new file mode 100644 index 000000000..88e21edc5 --- /dev/null +++ b/core/container/intrusive/list/intrusive_list.odin @@ -0,0 +1,173 @@ +package container_intrusive_list + +import "core:intrinsics" + +// An intrusive doubly-linked list +// +// As this is an intrusive container, a `Node` must be embedded in your own +// structure which is conventionally called a "link". The use of `push_front` +// and `push_back` take the address of this node. Retrieving the data +// associated with the node requires finding the relative offset of the node +// of the parent structure. The parent type and field name are given to +// `iterator_*` procedures, or to the built-in `container_of` procedure. +// +// This data structure is two-pointers in size: +// 8 bytes on 32-bit platforms and 16 bytes on 64-bit platforms +List :: struct { + head: ^Node, + tail: ^Node, +} + + +Node :: struct { + next, prev: ^Node, +} + +push_front :: proc(list: ^List, node: ^Node) { + if list.head != nil { + list.head.prev = node + node.prev, node.next = nil, list.head + list.head = node + } else { + list.head, list.tail = node, node + node.prev, node.next = nil, nil + } +} + +push_back :: proc(list: ^List, node: ^Node) { + if list.tail != nil { + list.tail.next = node + node.prev, node.next = list.tail, nil + list.tail = node + } else { + list.head, list.tail = node, node + node.prev, node.next = nil, nil + } +} + +remove :: proc(list: ^List, node: ^Node) { + if node != nil { + if node.next != nil { + node.next.prev = node.prev + } + if node.prev != nil { + node.prev.next = node.next + } + if list.head == node { + list.head = node.next + } + if list.tail == node { + list.tail = node.prev + } + } +} + +remove_by_proc :: proc(list: ^List, to_erase: proc(^Node) -> bool) { + for node := list.head; node != nil; { + next := node.next + if to_erase(node) { + if node.next != nil { + node.next.prev = node.prev + } + if node.prev != nil { + node.prev.next = node.next + } + if list.head == node { + list.head = node.next + } + if list.tail == node { + list.tail = node.prev + } + } + node = next + } +} + + +is_empty :: proc(list: ^List) -> bool { + return list.head == nil +} + +pop_front :: proc(list: ^List) -> ^Node { + link := list.head + if link == nil { + return nil + } + if link.next != nil { + link.next.prev = link.prev + } + if link.prev != nil { + link.prev.next = link.next + } + if link == list.head { + list.head = link.next + } + if link == list.tail { + list.tail = link.prev + } + return link + +} +pop_back :: proc(list: ^List) -> ^Node { + link := list.tail + if link == nil { + return nil + } + if link.next != nil { + link.next.prev = link.prev + } + if link.prev != nil { + link.prev.next = link.next + } + if link == list.head { + list.head = link.next + } + if link == list.tail { + list.tail = link.prev + } + return link +} + + +Iterator :: struct($T: typeid) { + curr: ^Node, + offset: uintptr, +} + +iterator_head :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T) + where intrinsics.type_has_field(T, field_name), + intrinsics.type_field_type(T, field_name) == Node { + return {list.head, offset_of_by_string(T, field_name)} +} + +iterator_tail :: proc(list: List, $T: typeid, $field_name: string) -> Iterator(T) + where intrinsics.type_has_field(T, field_name), + intrinsics.type_field_type(T, field_name) == Node { + return {list.tail, offset_of_by_string(T, field_name)} +} + +iterator_from_node :: proc(node: ^Node, $T: typeid, $field_name: string) -> Iterator(T) + where intrinsics.type_has_field(T, field_name), + intrinsics.type_field_type(T, field_name) == Node { + return {node, offset_of_by_string(T, field_name)} +} + +iterate_next :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { + node := it.curr + if node == nil { + return nil, false + } + it.curr = node.next + + return (^T)(uintptr(node) - it.offset), true +} + +iterate_prev :: proc(it: ^Iterator($T)) -> (ptr: ^T, ok: bool) { + node := it.curr + if node == nil { + return nil, false + } + it.curr = node.prev + + return (^T)(uintptr(node) - it.offset), true +} \ No newline at end of file From fbbb0d7610d2ace168df2aec65d76f51f35ec6a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 14:51:04 +0100 Subject: [PATCH 097/245] Update intrinsics.odin for documentation --- core/intrinsics/intrinsics.odin | 54 +++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index c132d4095..beb6f3f31 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -41,6 +41,10 @@ mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) --- mem_zero :: proc(ptr: rawptr, len: int) --- mem_zero_volatile :: proc(ptr: rawptr, len: int) --- +// prefer [^]T operations if possible +ptr_offset :: proc(ptr: ^$T, offset: int) -> ^T --- +ptr_sub :: proc(a, b: ^$T) -> int --- + unaligned_load :: proc(src: ^$T) -> T --- unaligned_store :: proc(dst: ^$T, val: T) -> T --- @@ -82,6 +86,7 @@ atomic_store_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) --- atomic_load :: proc(dst: ^$T) -> T --- atomic_load_explicit :: proc(dst: ^$T, order: Atomic_Memory_Order) -> T --- +// fetch then operator atomic_add :: proc(dst; ^$T, val: T) -> T --- atomic_add_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- atomic_sub :: proc(dst; ^$T, val: T) -> T --- @@ -119,19 +124,20 @@ type_is_string :: proc($T: typeid) -> bool --- type_is_typeid :: proc($T: typeid) -> bool --- type_is_any :: proc($T: typeid) -> bool --- -type_is_endian_platform :: proc($T: typeid) -> bool --- -type_is_endian_little :: proc($T: typeid) -> bool --- -type_is_endian_big :: proc($T: typeid) -> bool --- -type_is_unsigned :: proc($T: typeid) -> bool --- -type_is_numeric :: proc($T: typeid) -> bool --- -type_is_ordered :: proc($T: typeid) -> bool --- -type_is_ordered_numeric :: proc($T: typeid) -> bool --- -type_is_indexable :: proc($T: typeid) -> bool --- -type_is_sliceable :: proc($T: typeid) -> bool --- -type_is_comparable :: proc($T: typeid) -> bool --- -type_is_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=) -type_is_dereferenceable :: proc($T: typeid) -> bool --- -type_is_valid_map_key :: proc($T: typeid) -> bool --- +type_is_endian_platform :: proc($T: typeid) -> bool --- +type_is_endian_little :: proc($T: typeid) -> bool --- +type_is_endian_big :: proc($T: typeid) -> bool --- +type_is_unsigned :: proc($T: typeid) -> bool --- +type_is_numeric :: proc($T: typeid) -> bool --- +type_is_ordered :: proc($T: typeid) -> bool --- +type_is_ordered_numeric :: proc($T: typeid) -> bool --- +type_is_indexable :: proc($T: typeid) -> bool --- +type_is_sliceable :: proc($T: typeid) -> bool --- +type_is_comparable :: proc($T: typeid) -> bool --- +type_is_simple_compare :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=) +type_is_dereferenceable :: proc($T: typeid) -> bool --- +type_is_valid_map_key :: proc($T: typeid) -> bool --- +type_is_valid_matrix_elements :: proc($T: typeid) -> bool --- type_is_named :: proc($T: typeid) -> bool --- type_is_pointer :: proc($T: typeid) -> bool --- @@ -146,6 +152,7 @@ type_is_enum :: proc($T: typeid) -> bool --- type_is_proc :: proc($T: typeid) -> bool --- type_is_bit_set :: proc($T: typeid) -> bool --- type_is_simd_vector :: proc($T: typeid) -> bool --- +type_is_matrix :: proc($T: typeid) -> bool --- type_has_nil :: proc($T: typeid) -> bool --- @@ -161,20 +168,41 @@ type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) --- type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- type_proc_return_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- +type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) --- + type_polymorphic_record_parameter_count :: proc($T: typeid) -> typeid --- type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V --- +type_is_specialized_polymorphic_record :: proc($T: typeid) -> bool --- +type_is_unspecialized_polymorphic_record :: proc($T: typeid) -> bool --- + +type_is_subtype_of :: proc($T, $U: typeid) -> bool --- type_field_index_of :: proc($T: typeid, $name: string) -> uintptr --- type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) --- type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- +constant_utf16_cstring :: proc($literal: string) -> [^]u16 --- // WASM targets only wasm_memory_grow :: proc(index, delta: uintptr) -> int --- wasm_memory_size :: proc(index: uintptr) -> int --- + +// Darwin targets only +objc_object :: struct{} +objc_selector :: struct{} +objc_class :: struct{} +objc_id :: ^objc_object +objc_SEL :: ^objc_selector +objc_Class :: ^objc_class + +objc_find_selector :: proc($name: string) -> objc_SEL --- +objc_register_selector :: proc($name: string) -> objc_SEL --- +objc_find_class :: proc($name: string) -> objc_Class --- +objc_register_class :: proc($name: string) -> objc_Class --- + // Internal compiler use only __entry_point :: proc() --- \ No newline at end of file From 904f0407f8e19a419dfe313181c2b47216121e11 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 14:53:26 +0100 Subject: [PATCH 098/245] Add `intrinsics.type_is_multi_pointer` --- src/check_builtin.cpp | 2 ++ src/checker_builtin_procs.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 6c7972d45..9a5d1c554 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -29,6 +29,7 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end - is_type_named, is_type_pointer, + is_type_multi_pointer, is_type_array, is_type_enumerated_array, is_type_slice, @@ -3866,6 +3867,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_type_is_valid_matrix_elements: case BuiltinProc_type_is_named: case BuiltinProc_type_is_pointer: + case BuiltinProc_type_is_multi_pointer: case BuiltinProc_type_is_array: case BuiltinProc_type_is_enumerated_array: case BuiltinProc_type_is_slice: diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 0f72f01f7..d301cae0c 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -158,6 +158,7 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc_type_is_named, BuiltinProc_type_is_pointer, + BuiltinProc_type_is_multi_pointer, BuiltinProc_type_is_array, BuiltinProc_type_is_enumerated_array, BuiltinProc_type_is_slice, @@ -376,6 +377,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_named"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_pointer"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_multi_pointer"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_array"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_enumerated_array"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_slice"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, From da0f722aad98afc94de09903a74802f43e6f5961 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 27 Apr 2022 15:56:45 +0200 Subject: [PATCH 099/245] Move Odin CI test assets over to its own repository. --- tests/core/download_assets.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/core/download_assets.py b/tests/core/download_assets.py index d86f7f1e7..50137f563 100644 --- a/tests/core/download_assets.py +++ b/tests/core/download_assets.py @@ -5,8 +5,9 @@ import sys import os import zipfile +TEST_SUITES = ['PNG', 'XML'] DOWNLOAD_BASE_PATH = "assets/{}" -ASSETS_BASE_URL = "https://raw.githubusercontent.com/Kelimion/compress-odin/master/tests/assets/{}/{}" +ASSETS_BASE_URL = "https://raw.githubusercontent.com/odin-lang/test-assets/master/{}/{}" PNG_IMAGES = [ "basi0g01.png", "basi0g02.png", "basi0g04.png", "basi0g08.png", "basi0g16.png", "basi2c08.png", "basi2c16.png", "basi3p01.png", "basi3p02.png", "basi3p04.png", "basi3p08.png", "basi4a08.png", @@ -73,25 +74,27 @@ def try_download_and_unpack_zip(suite): print("Could not extract ZIP file") return 2 - def main(): - print("Downloading PNG assets") + for suite in TEST_SUITES: + print("Downloading {} assets".format(suite)) - # Make PNG assets path - try: - path = DOWNLOAD_BASE_PATH.format("PNG") - os.makedirs(path) - except FileExistsError: - pass + # Make assets path + try: + path = DOWNLOAD_BASE_PATH.format(suite) + os.makedirs(path) + except FileExistsError: + pass + + # Try downloading and unpacking the assets + r = try_download_and_unpack_zip(suite) + if r is not None: + return r + + # We could fall back on downloading the PNG files individually, but it's slow + print("Done downloading {} assets.".format(suite)) - # Try downloading and unpacking the PNG assets - r = try_download_and_unpack_zip("PNG") - if r is not None: - return r - # We could fall back on downloading the PNG files individually, but it's slow - print("Done downloading PNG assets") return 0 if __name__ == '__main__': From bd73b2845b2e7cadf38c441babeeb9765896b2be Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 15:03:48 +0100 Subject: [PATCH 100/245] Unify default `Sema` and `Atomic_Sema` behaviour --- core/sync/primitives_atomic.odin | 65 +++++++++++++++----------------- core/sync/sema_internal.odin | 42 ++------------------- 2 files changed, 34 insertions(+), 73 deletions(-) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 11fff4e60..22771443d 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -400,30 +400,28 @@ atomic_cond_broadcast :: proc(c: ^Atomic_Cond) { // // An Atomic_Sema must not be copied after first use Atomic_Sema :: struct { - mutex: Atomic_Mutex, - cond: Atomic_Cond, - count: int, + count: Futex, } atomic_sema_post :: proc(s: ^Atomic_Sema, count := 1) { - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - s.count += count - atomic_cond_signal(&s.cond) + atomic_add_explicit(&s.count, Futex(count), .Release) + if count == 1 { + futex_signal(&s.count) + } else { + futex_broadcast(&s.count) + } } atomic_sema_wait :: proc(s: ^Atomic_Sema) { - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - for s.count == 0 { - atomic_cond_wait(&s.cond, &s.mutex) - } - - s.count -= 1 - if s.count > 0 { - atomic_cond_signal(&s.cond) + for { + original_count := atomic_load_explicit(&s.count, .Relaxed) + for original_count == 0 { + futex_wait(&s.count, u32(original_count)) + original_count = s.count + } + if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) { + return + } } } @@ -431,25 +429,22 @@ atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration) if duration <= 0 { return false } - atomic_mutex_lock(&s.mutex) - defer atomic_mutex_unlock(&s.mutex) - - start := time.tick_now() + for { - for s.count == 0 { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false + original_count := atomic_load_explicit(&s.count, .Relaxed) + for start := time.tick_now(); original_count == 0; /**/ { + remaining := duration - time.tick_since(start) + if remaining < 0 { + return false + } + + if !futex_wait_with_timeout(&s.count, u32(original_count), remaining) { + return false + } + original_count = s.count } - - if !atomic_cond_wait_with_timeout(&s.cond, &s.mutex, remaining) { - return false + if original_count == atomic_compare_exchange_strong_explicit(&s.count, original_count, original_count-1, .Acquire, .Acquire) { + return true } } - - s.count -= 1 - if s.count > 0 { - atomic_cond_signal(&s.cond) - } - return true } diff --git a/core/sync/sema_internal.odin b/core/sync/sema_internal.odin index e4a3c0bfc..5e2203c34 100644 --- a/core/sync/sema_internal.odin +++ b/core/sync/sema_internal.odin @@ -6,53 +6,19 @@ import "core:time" when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { _Sema :: struct { - count: Futex, + atomic: Atomic_Sema, } _sema_post :: proc(s: ^Sema, count := 1) { - atomic_add_explicit(&s.impl.count, Futex(count), .Release) - if count == 1 { - futex_signal(&s.impl.count) - } else { - futex_broadcast(&s.impl.count) - } + atomic_sema_post(&s.impl.atomic, count) } _sema_wait :: proc(s: ^Sema) { - for { - original_count := atomic_load_explicit(&s.impl.count, .Relaxed) - for original_count == 0 { - futex_wait(&s.impl.count, u32(original_count)) - original_count = s.impl.count - } - if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { - return - } - } + atomic_sema_wait(&s.impl.atomic) } _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { - if duration <= 0 { - return false - } - for { - - original_count := atomic_load_explicit(&s.impl.count, .Relaxed) - for start := time.tick_now(); original_count == 0; /**/ { - remaining := duration - time.tick_since(start) - if remaining < 0 { - return false - } - - if !futex_wait_with_timeout(&s.impl.count, u32(original_count), remaining) { - return false - } - original_count = s.impl.count - } - if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { - return true - } - } + return atomic_sema_wait_with_timeout(&s.impl.atomic, duration) } } else { _Sema :: struct { From 305510bea0cd8493ffab32a50516d8fde8611e4c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 15:25:56 +0100 Subject: [PATCH 101/245] Update intrinsics.odin --- core/intrinsics/intrinsics.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index beb6f3f31..7e75aecc4 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -141,6 +141,7 @@ type_is_valid_matrix_elements :: proc($T: typeid) -> bool --- type_is_named :: proc($T: typeid) -> bool --- type_is_pointer :: proc($T: typeid) -> bool --- +type_is_multi_pointer :: proc($T: typeid) -> bool --- type_is_array :: proc($T: typeid) -> bool --- type_is_enumerated_array :: proc($T: typeid) -> bool --- type_is_slice :: proc($T: typeid) -> bool --- From d6cfb6050613872c3ae70cbbe446276cec4ded12 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 15:29:21 +0100 Subject: [PATCH 102/245] Remove `prev` from `Atomic_Cond` --- core/sync/primitives_atomic.odin | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 812e5ae97..665b515ba 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -287,12 +287,10 @@ atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool { // An Atomic_Cond must not be copied after first use Atomic_Cond :: struct { state: Futex, - prev: u32, } atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) { - state := u32(atomic_load(&c.state)) - atomic_store(&c.prev, state) + state := u32(atomic_load_explicit(&c.state, .Relaxed)) unlock(m) futex_wait(&c.state, state) lock(m) @@ -309,14 +307,12 @@ atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duratio atomic_cond_signal :: proc(c: ^Atomic_Cond) { - state := 1 + atomic_load(&c.prev) - atomic_store(&c.state, Futex(state)) + atomic_add_explicit(&c.state, 1, .Relaxed) futex_signal(&c.state) } atomic_cond_broadcast :: proc(c: ^Atomic_Cond) { - state := 1 + atomic_load(&c.prev) - atomic_store(&c.state, Futex(state)) + atomic_add_explicit(&c.state, 1, .Relaxed) futex_broadcast(&c.state) } From 10cd294cf2b64ae6d5c7e8a470d074e2c48eb4cb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 27 Apr 2022 15:57:47 +0100 Subject: [PATCH 103/245] Use Acquire semantics for the `futex_wait` load shortcut --- core/sync/primitives.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sync/primitives.odin b/core/sync/primitives.odin index 483f85343..bfbdc6f9b 100644 --- a/core/sync/primitives.odin +++ b/core/sync/primitives.odin @@ -195,7 +195,7 @@ sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { Futex :: distinct u32 futex_wait :: proc(f: ^Futex, expected: u32) { - if u32(atomic_load(f)) != expected { + if u32(atomic_load_explicit(f, .Acquire)) != expected { return } @@ -204,7 +204,7 @@ futex_wait :: proc(f: ^Futex, expected: u32) { // returns true if the wait happened within the duration, false if it exceeded the time duration futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool { - if u32(atomic_load(f)) != expected { + if u32(atomic_load_explicit(f, .Acquire)) != expected { return true } if duration <= 0 { From cd13dedb36799d1b6e2f674d95fd820babff5e16 Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Wed, 27 Apr 2022 20:06:43 +0200 Subject: [PATCH 104/245] D3D12 binding fixes: Added dxgi.IID versions of all the UUIDs in d3d12.odin so that the IIDs can be used to fetch interfaces properly. Also fixed an issue where GetDesc, GetCPUDescriptorHandleForHeapStart and GetGPUDescriptorHandleForHeapStart had the wrong signature due to an old D3D12 header bug, more info: https://stackoverflow.com/questions/34118929/getcpudescriptorhandleforheapstart-stack-corruption --- vendor/directx/d3d12/d3d12.odin | 184 +++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 64 deletions(-) diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index f3885ed63..739606249 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -189,7 +189,8 @@ SRV_DIMENSION :: enum i32 { PFN_DESTRUCTION_CALLBACK :: #type proc "c" (a0: rawptr) -ID3DDestructionNotifier_UUID :: "a06eb39a-50da-425b-8c31-4eecd6c270f3" +ID3DDestructionNotifier_UUID_STRING :: "a06eb39a-50da-425b-8c31-4eecd6c270f3" +ID3DDestructionNotifier_UUID := &IID{0xa06eb39a, 0x50da, 0x425b, {0x8c, 0x31, 0x4e, 0xec, 0xd6, 0xc2, 0x70, 0xf3}} ID3DDestructionNotifier :: struct #raw_union { #subtype iunknown: IUnknown, using id3ddestructionnotifier_vtable: ^ID3DDestructionNotifier_VTable, @@ -658,7 +659,8 @@ RASTERIZER_DESC :: struct { } -IObject_UUID :: "c4fec28f-7966-4e95-9f94-f431cb56c3b8" +IObject_UUID_STRING :: "c4fec28f-7966-4e95-9f94-f431cb56c3b8" +IObject_UUID := &IID{0xc4fec28f, 0x7966, 0x4e95, {0x9f, 0x94, 0xf4, 0x31, 0xcb, 0x56, 0xc3, 0xb8}} IObject :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12object_vtable: ^IObject_VTable, @@ -672,7 +674,8 @@ IObject_VTable :: struct { } -IDeviceChild_UUID :: "905db94b-a00c-4140-9df5-2b64ca9ea357" +IDeviceChild_UUID_STRING :: "905db94b-a00c-4140-9df5-2b64ca9ea357" +IDeviceChild_UUID := &IID{0x905db94b, 0xa00c, 0x4140, {0x9d, 0xf5, 0x2b, 0x64, 0xca, 0x9e, 0xa3, 0x57}} IDeviceChild :: struct #raw_union { #subtype id3d12object: IObject, using id3d12devicechild_vtable: ^IDeviceChild_VTable, @@ -683,7 +686,8 @@ IDeviceChild_VTable :: struct { } -IRootSignature_UUID :: "c54a6b66-72df-4ee8-8be5-a946a1429214" +IRootSignature_UUID_STRING :: "c54a6b66-72df-4ee8-8be5-a946a1429214" +IRootSignature_UUID := &IID{0xc54a6b66, 0x72df, 0x4ee8, {0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14}} IRootSignature :: struct { using id3d12devicechild: IDeviceChild, } @@ -2058,7 +2062,8 @@ VERSIONED_ROOT_SIGNATURE_DESC :: struct { } -IRootSignatureDeserializer_UUID :: "34AB647B-3CC8-46AC-841B-C0965645C046" +IRootSignatureDeserializer_UUID_STRING :: "34AB647B-3CC8-46AC-841B-C0965645C046" +IRootSignatureDeserializer_UUID := &IID{0x34AB647B, 0x3CC8, 0x46AC, {0x84, 0x1B, 0xC0, 0x96, 0x56, 0x45, 0xC0, 0x46}} IRootSignatureDeserializer :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12rootsignaturedeserializer_vtable: ^IRootSignatureDeserializer_VTable, @@ -2069,7 +2074,8 @@ IRootSignatureDeserializer_VTable :: struct { } -IVersionedRootSignatureDeserializer_UUID :: "7F91CE67-090C-4BB7-B78E-ED8FF2E31DA0" +IVersionedRootSignatureDeserializer_UUID_STRING :: "7F91CE67-090C-4BB7-B78E-ED8FF2E31DA0" +IVersionedRootSignatureDeserializer_UUID := &IID{0x7F91CE67, 0x090C, 0x4BB7, {0xB7, 0x8E, 0xED, 0x8F, 0xF2, 0xE3, 0x1D, 0xA0}} IVersionedRootSignatureDeserializer :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12versionedrootsignaturedeserializer_vtable: ^IVersionedRootSignatureDeserializer_VTable, @@ -2236,13 +2242,15 @@ COMMAND_SIGNATURE_DESC :: struct { } -IPageable_UUID :: "63ee58fb-1268-4835-86da-f008ce62f0d6" +IPageable_UUID_STRING :: "63ee58fb-1268-4835-86da-f008ce62f0d6" +IPageable_UUID := &IID{0x63ee58fb, 0x1268, 0x4835, {0x86, 0xda, 0xf0, 0x08, 0xce, 0x62, 0xf0, 0xd6}} IPageable :: struct { using id3d12devicechild: IDeviceChild, } -IHeap_UUID :: "6b3b2502-6e51-45b3-90ee-9884265e8df3" +IHeap_UUID_STRING :: "6b3b2502-6e51-45b3-90ee-9884265e8df3" +IHeap_UUID := &IID{0x6b3b2502, 0x6e51, 0x45b3, {0x90, 0xee, 0x98, 0x84, 0x26, 0x5e, 0x8d, 0xf3}} IHeap :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12heap_vtable: ^IHeap_VTable, @@ -2253,7 +2261,8 @@ IHeap_VTable :: struct { } -IResource_UUID :: "696442be-a72e-4059-bc79-5b5c98040fad" +IResource_UUID_STRING :: "696442be-a72e-4059-bc79-5b5c98040fad" +IResource_UUID := &IID{0x696442be, 0xa72e, 0x4059, {0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad}} IResource :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12resource_vtable: ^IResource_VTable, @@ -2270,7 +2279,8 @@ IResource_VTable :: struct { } -ICommandAllocator_UUID :: "6102dee4-af59-4b09-b999-b44d73f09b24" +ICommandAllocator_UUID_STRING :: "6102dee4-af59-4b09-b999-b44d73f09b24" +ICommandAllocator_UUID := &IID{0x6102dee4, 0xaf59, 0x4b09, {0xb9, 0x99, 0xb4, 0x4d, 0x73, 0xf0, 0x9b, 0x24}} ICommandAllocator :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12commandallocator_vtable: ^ICommandAllocator_VTable, @@ -2281,7 +2291,8 @@ ICommandAllocator_VTable :: struct { } -IFence_UUID :: "0a753dcf-c4d8-4b91-adf6-be5a60d95a76" +IFence_UUID_STRING :: "0a753dcf-c4d8-4b91-adf6-be5a60d95a76" +IFence_UUID := &IID {0x0a753dcf, 0xc4d8, 0x4b91, {0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76}} IFence :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12fence_vtable: ^IFence_VTable, @@ -2294,7 +2305,8 @@ IFence_VTable :: struct { } -IFence1_UUID :: "433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a" +IFence1_UUID_STRING :: "433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a" +IFence1_UUID := &IID{0x433685fe, 0xe22b, 0x4ca0, {0xa8, 0xdb, 0xb5, 0xb4, 0xf4, 0xdd, 0x0e, 0x4a}} IFence1 :: struct #raw_union { #subtype id3d12fence: IFence, using id3d12fence1_vtable: ^IFence1_VTable, @@ -2305,7 +2317,8 @@ IFence1_VTable :: struct { } -IPipelineState_UUID :: "765a30f3-f624-4c6f-a828-ace948622445" +IPipelineState_UUID_STRING :: "765a30f3-f624-4c6f-a828-ace948622445" +IPipelineState_UUID := &IID{0x765a30f3, 0xf624, 0x4c6f, {0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45}} IPipelineState :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12pipelinestate_vtable: ^IPipelineState_VTable, @@ -2316,32 +2329,35 @@ IPipelineState_VTable :: struct { } -IDescriptorHeap_UUID :: "8efb471d-616c-4f49-90f7-127bb763fa51" +IDescriptorHeap_UUID_STRING :: "8efb471d-616c-4f49-90f7-127bb763fa51" +IDescriptorHeap_UUID := &IID{0x8efb471d, 0x616c, 0x4f49, { 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51}} IDescriptorHeap :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12descriptorheap_vtable: ^IDescriptorHeap_VTable, } IDescriptorHeap_VTable :: struct { using id3d12devicechild_vtable: IDeviceChild_VTable, - GetDesc: proc "stdcall" (this: ^IDescriptorHeap) -> DESCRIPTOR_HEAP_DESC, - GetCPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap) -> CPU_DESCRIPTOR_HANDLE, - GetGPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap) -> GPU_DESCRIPTOR_HANDLE, -} + GetDesc: proc "stdcall" (this: ^IDescriptorHeap, desc: ^DESCRIPTOR_HEAP_DESC), + GetCPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap, handle: ^CPU_DESCRIPTOR_HANDLE), + GetGPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap, handle: ^GPU_DESCRIPTOR_HANDLE), +} - -IQueryHeap_UUID :: "0d9658ae-ed45-469e-a61d-970ec583cab4" +IQueryHeap_UUID_STRING :: "0d9658ae-ed45-469e-a61d-970ec583cab4" +IQueryHeap_UUID := &IID{0x0d9658ae, 0xed45, 0x469e, {0xa6, 0x1d, 0x97, 0x0e, 0xc5, 0x83, 0xca, 0xb4}} IQueryHeap :: struct { #subtype id3d12pageable: IPageable, } -ICommandSignature_UUID :: "c36a797c-ec80-4f0a-8985-a7b2475082d1" +ICommandSignature_UUID_STRING :: "c36a797c-ec80-4f0a-8985-a7b2475082d1" +ICommandSignature_UUID := &IID{0xc36a797c, 0xec80, 0x4f0a, {0x89, 0x85, 0xa7, 0xb2, 0x47, 0x50, 0x82, 0xd1}} ICommandSignature :: struct { #subtype id3d12pageable: IPageable, } -ICommandList_UUID :: "7116d91c-e7e4-47ce-b8c6-ec8168f437e5" +ICommandList_UUID_STRING :: "7116d91c-e7e4-47ce-b8c6-ec8168f437e5" +ICommandList_UUID := &IID {0x7116d91c, 0xe7e4, 0x47ce, {0xb8, 0xc6, 0xec, 0x81, 0x68, 0xf4, 0x37, 0xe5}} ICommandList :: struct #raw_union { #subtype id3d12devicechild: IDeviceChild, using id3d12commandlist_vtable: ^ICommandList_VTable, @@ -2352,7 +2368,8 @@ ICommandList_VTable :: struct { } -IGraphicsCommandList_UUID :: "5b160d0f-ac1b-4185-8ba8-b3ae42a5a455" +IGraphicsCommandList_UUID_STRING :: "5b160d0f-ac1b-4185-8ba8-b3ae42a5a455" +IGraphicsCommandList_UUID := &IID{0x5b160d0f, 0xac1b, 0x4185, {0x8b, 0xa8, 0xb3, 0xae, 0x42, 0xa5, 0xa4, 0x55}} IGraphicsCommandList :: struct #raw_union { #subtype id3d12commandlist: ICommandList, using id3d12graphicscommandlist_vtable: ^IGraphicsCommandList_VTable, @@ -2413,7 +2430,8 @@ IGraphicsCommandList_VTable :: struct { } -IGraphicsCommandList1_UUID :: "553103fb-1fe7-4557-bb38-946d7d0e7ca7" +IGraphicsCommandList1_UUID_STRING :: "553103fb-1fe7-4557-bb38-946d7d0e7ca7" +IGraphicsCommandList1_UUID := &IID{0x553103fb, 0x1fe7, 0x4557, {0xbb, 0x38, 0x94, 0x6d, 0x7d, 0x0e, 0x7c, 0xa7}} IGraphicsCommandList1 :: struct #raw_union { #subtype id3d12graphicscommandlist: IGraphicsCommandList, using id3d12graphicscommandlist1_vtable: ^IGraphicsCommandList1_VTable, @@ -2440,7 +2458,8 @@ WRITEBUFFERIMMEDIATE_MODE :: enum i32 { } -IGraphicsCommandList2_UUID :: "38C3E585-FF17-412C-9150-4FC6F9D72A28" +IGraphicsCommandList2_UUID_STRING :: "38C3E585-FF17-412C-9150-4FC6F9D72A28" +IGraphicsCommandList2_UUID := &IID{0x38C3E585, 0xFF17, 0x412C, {0x91, 0x50, 0x4F, 0xC6, 0xF9, 0xD7, 0x2A, 0x28}} IGraphicsCommandList2 :: struct #raw_union { #subtype id3d12graphicscommandlist1: IGraphicsCommandList1, using id3d12graphicscommandlist2_vtable: ^IGraphicsCommandList2_VTable, @@ -2451,7 +2470,8 @@ IGraphicsCommandList2_VTable :: struct { } -ICommandQueue_UUID :: "0ec870a6-5d7e-4c22-8cfc-5baae07616ed" +ICommandQueue_UUID_STRING :: "0ec870a6-5d7e-4c22-8cfc-5baae07616ed" +ICommandQueue_UUID := &IID{0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed}} ICommandQueue :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12commandqueue_vtable: ^ICommandQueue_VTable, @@ -2472,7 +2492,8 @@ ICommandQueue_VTable :: struct { } -IDevice_UUID :: "189819f1-1db6-4b57-be54-1821339b85f7" +IDevice_UUID_STRING :: "189819f1-1db6-4b57-be54-1821339b85f7" +IDevice_UUID := &IID{0x189819f1, 0x1db6, 0x4b57, { 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7}} IDevice :: struct #raw_union { #subtype id3d12object: IObject, using id3d12device_vtable: ^IDevice_VTable, @@ -2519,7 +2540,8 @@ IDevice_VTable :: struct { } -IPipelineLibrary_UUID :: "c64226a8-9201-46af-b4cc-53fb9ff7414f" +IPipelineLibrary_UUID_STRING :: "c64226a8-9201-46af-b4cc-53fb9ff7414f" +IPipelineLibrary_UUID := &IID{0xc64226a8, 0x9201, 0x46af, {0xb4, 0xcc, 0x53, 0xfb, 0x9f, 0xf7, 0x41, 0x4f}} IPipelineLibrary :: struct #raw_union { #subtype id3d12devicechild: IDeviceChild, using id3d12pipelinelibrary_vtable: ^IPipelineLibrary_VTable, @@ -2534,7 +2556,8 @@ IPipelineLibrary_VTable :: struct { } -IPipelineLibrary1_UUID :: "80eabf42-2568-4e5e-bd82-c37f86961dc3" +IPipelineLibrary1_UUID_STRING :: "80eabf42-2568-4e5e-bd82-c37f86961dc3" +IPipelineLibrary1_UUID := &IID{0x80eabf42, 0x2568, 0x4e5e, {0xbd, 0x82, 0xc3, 0x7f, 0x86, 0x96, 0x1d, 0xc3}} IPipelineLibrary1 :: struct #raw_union { #subtype id3d12pipelinelibrary: IPipelineLibrary, using id3d12pipelinelibrary1_vtable: ^IPipelineLibrary1_VTable, @@ -2559,7 +2582,8 @@ RESIDENCY_PRIORITY :: enum i32 { } -IDevice1_UUID :: "77acce80-638e-4e65-8895-c1f23386863e" +IDevice1_UUID_STRING :: "77acce80-638e-4e65-8895-c1f23386863e" +IDevice1_UUID := &IID{0x77acce80, 0x638e, 0x4e65, {0x88, 0x95, 0xc1, 0xf2, 0x33, 0x86, 0x86, 0x3e}} IDevice1 :: struct #raw_union { #subtype id3d12device: IDevice, using id3d12device1_vtable: ^IDevice1_VTable, @@ -2572,7 +2596,8 @@ IDevice1_VTable :: struct { } -IDevice2_UUID :: "30baa41e-b15b-475c-a0bb-1af5c5b64328" +IDevice2_UUID_STRING :: "30baa41e-b15b-475c-a0bb-1af5c5b64328" +IDevice2_UUID := &IID{0x30baa41e, 0xb15b, 0x475c, {0xa0, 0xbb, 0x1a, 0xf5, 0xc5, 0xb6, 0x43, 0x28}} IDevice2 :: struct #raw_union { #subtype id3d12device1: IDevice1, using id3d12device2_vtable: ^IDevice2_VTable, @@ -2588,7 +2613,8 @@ RESIDENCY_FLAGS :: enum u32 { // TODO: make bit_set } -IDevice3_UUID :: "81dadc15-2bad-4392-93c5-101345c4aa98" +IDevice3_UUID_STRING :: "81dadc15-2bad-4392-93c5-101345c4aa98" +IDevice3_UUID := &IID{0x81dadc15, 0x2bad, 0x4392, {0x93, 0xc5, 0x10, 0x13, 0x45, 0xc4, 0xaa, 0x98}} IDevice3 :: struct #raw_union { #subtype id3d12device2: IDevice2, using id3d12device3_vtable: ^IDevice3_VTable, @@ -2618,7 +2644,8 @@ PROTECTED_SESSION_STATUS :: enum i32 { } -IProtectedSession_UUID :: "A1533D18-0AC1-4084-85B9-89A96116806B" +IProtectedSession_UUID_STRING :: "A1533D18-0AC1-4084-85B9-89A96116806B" +IProtectedSession_UUID := &IID{0xA1533D18, 0x0AC1, 0x4084, {0x85, 0xB9, 0x89, 0xA9, 0x61, 0x16, 0x80, 0x6B}} IProtectedSession :: struct #raw_union { #subtype id3d12devicechild: IDeviceChild, using id3d12protectedsession_vtable: ^IProtectedSession_VTable, @@ -2649,7 +2676,8 @@ PROTECTED_RESOURCE_SESSION_DESC :: struct { } -IProtectedResourceSession_UUID :: "6CD696F4-F289-40CC-8091-5A6C0A099C3D" +IProtectedResourceSession_UUID_STRING :: "6CD696F4-F289-40CC-8091-5A6C0A099C3D" +IProtectedResourceSession_UUID := &IID{0x6CD696F4, 0xF289, 0x40CC, {0x80, 0x91, 0x5A, 0x6C, 0x0A, 0x09, 0x9C, 0x3D}} IProtectedResourceSession :: struct #raw_union { #subtype id3d12protectedsession: IProtectedSession, using id3d12protectedresourcesession_vtable: ^IProtectedResourceSession_VTable, @@ -2660,7 +2688,8 @@ IProtectedResourceSession_VTable :: struct { } -IDevice4_UUID :: "e865df17-a9ee-46f9-a463-3098315aa2e5" +IDevice4_UUID_STRING :: "e865df17-a9ee-46f9-a463-3098315aa2e5" +IDevice4_UUID := &IID{0xe865df17, 0xa9ee, 0x46f9, {0xa4, 0x63, 0x30, 0x98, 0x31, 0x5a, 0xa2, 0xe5}} IDevice4 :: struct #raw_union { #subtype id3d12device3: IDevice3, using id3d12device4_vtable: ^IDevice4_VTable, @@ -2681,7 +2710,8 @@ LIFETIME_STATE :: enum i32 { } -ILifetimeOwner_UUID :: "e667af9f-cd56-4f46-83ce-032e595d70a8" +ILifetimeOwner_UUID_STRING :: "e667af9f-cd56-4f46-83ce-032e595d70a8" +ILifetimeOwner_UUID := &IID{0xe667af9f, 0xcd56, 0x4f46, {0x83, 0xce, 0x03, 0x2e, 0x59, 0x5d, 0x70, 0xa8}} ILifetimeOwner :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12lifetimeowner_vtable: ^ILifetimeOwner_VTable, @@ -2692,7 +2722,8 @@ ILifetimeOwner_VTable :: struct { } -ISwapChainAssistant_UUID :: "f1df64b6-57fd-49cd-8807-c0eb88b45c8f" +ISwapChainAssistant_UUID_STRING :: "f1df64b6-57fd-49cd-8807-c0eb88b45c8f" +ISwapChainAssistant_UUID := &IID{0xf1df64b6, 0x57fd, 0x49cd, {0x88, 0x07, 0xc0, 0xeb, 0x88, 0xb4, 0x5c, 0x8f}} ISwapChainAssistant :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12swapchainassistant_vtable: ^ISwapChainAssistant_VTable, @@ -2706,7 +2737,8 @@ ISwapChainAssistant_VTable :: struct { } -ILifetimeTracker_UUID :: "3fd03d36-4eb1-424a-a582-494ecb8ba813" +ILifetimeTracker_UUID_STRING :: "3fd03d36-4eb1-424a-a582-494ecb8ba813" +ILifetimeTracker_UUID := &IID{0x3fd03d36, 0x4eb1, 0x424a, {0xa5, 0x82, 0x49, 0x4e, 0xcb, 0x8b, 0xa8, 0x13}} ILifetimeTracker :: struct #raw_union { #subtype id3d12devicechild: IDeviceChild, using id3d12lifetimetracker_vtable: ^ILifetimeTracker_VTable, @@ -2772,13 +2804,15 @@ META_COMMAND_DESC :: struct { } -IStateObject_UUID :: "47016943-fca8-4594-93ea-af258b55346d" +IStateObject_UUID_STRING :: "47016943-fca8-4594-93ea-af258b55346d" +IStateObject_UUID := &IID{0x47016943, 0xfca8, 0x4594, {0x93, 0xea, 0xaf, 0x25, 0x8b, 0x55, 0x34, 0x6d}} IStateObject :: struct #raw_union { #subtype id3d12pageable: IPageable, } -IStateObjectProperties_UUID :: "de5fa827-9bf9-4f26-89ff-d7f56fde3860" +IStateObjectProperties_UUID_STRING :: "de5fa827-9bf9-4f26-89ff-d7f56fde3860" +IStateObjectProperties_IID := &IID{0xde5fa827, 0x9bf9, 0x4f26, {0x89, 0xff, 0xd7, 0xf5, 0x6f, 0xde, 0x38, 0x60}} IStateObjectProperties :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12stateobjectproperties_vtable: ^IStateObjectProperties_VTable, @@ -3119,7 +3153,8 @@ HIT_KIND :: enum i32 { } -IDevice5_UUID :: "8b4f173b-2fea-4b80-8f58-4307191ab95d" +IDevice5_UUID_STRING :: "8b4f173b-2fea-4b80-8f58-4307191ab95d" +IDevice5_UUID := &IID{0x8b4f173b, 0x2fea, 0x4b80, {0x8f, 0x58, 0x43, 0x07, 0x19, 0x1a, 0xb9, 0x5d}} IDevice5 :: struct #raw_union { #subtype id3d12device4: IDevice4, using id3d12device5_vtable: ^IDevice5_VTable, @@ -3325,7 +3360,8 @@ VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct { } -IDeviceRemovedExtendedDataSettings_UUID :: "82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63" +IDeviceRemovedExtendedDataSettings_UUID_SRING :: "82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63" +IDeviceRemovedExtendedDataSettings_UUID := &IID{0x82BC481C, 0x6B9B, 0x4030, {0xAE, 0xDB, 0x7E, 0xE3, 0xD1, 0xDF, 0x1E, 0x63}} IDeviceRemovedExtendedDataSettings :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12deviceremovedextendeddatasettings_vtable: ^IDeviceRemovedExtendedDataSettings_VTable, @@ -3338,7 +3374,8 @@ IDeviceRemovedExtendedDataSettings_VTable :: struct { } -IDeviceRemovedExtendedDataSettings1_UUID :: "DBD5AE51-3317-4F0A-ADF9-1D7CEDCAAE0B" +IDeviceRemovedExtendedDataSettings1_UUID_STRING :: "DBD5AE51-3317-4F0A-ADF9-1D7CEDCAAE0B" +IDeviceRemovedExtendedDataSettings1_UUID := &IID{0xDBD5AE51, 0x3317, 0x4F0A, {0xAD, 0xF9, 0x1D, 0x7C, 0xED, 0xCA, 0xAE, 0x0B}} IDeviceRemovedExtendedDataSettings1 :: struct #raw_union { #subtype id3d12deviceremovedextendeddatasettings: IDeviceRemovedExtendedDataSettings, using id3d12deviceremovedextendeddatasettings1_vtable: ^IDeviceRemovedExtendedDataSettings1_VTable, @@ -3349,7 +3386,8 @@ IDeviceRemovedExtendedDataSettings1_VTable :: struct { } -IDeviceRemovedExtendedData_UUID :: "98931D33-5AE8-4791-AA3C-1A73A2934E71" +IDeviceRemovedExtendedData_UUID_STRING :: "98931D33-5AE8-4791-AA3C-1A73A2934E71" +IDeviceRemovedExtendedData_UUID := &IID{0x98931D33, 0x5AE8, 0x4791, {0xAA, 0x3C, 0x1A, 0x73, 0xA2, 0x93, 0x4E, 0x71}} IDeviceRemovedExtendedData :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12deviceremovedextendeddata_vtable: ^IDeviceRemovedExtendedData_VTable, @@ -3361,7 +3399,8 @@ IDeviceRemovedExtendedData_VTable :: struct { } -IDeviceRemovedExtendedData1_UUID :: "9727A022-CF1D-4DDA-9EBA-EFFA653FC506" +IDeviceRemovedExtendedData1_UUID_STRING :: "9727A022-CF1D-4DDA-9EBA-EFFA653FC506" +IDeviceRemovedExtendedData1_UUID := &IID{0x9727A022, 0xCF1D, 0x4DDA, {0x9E, 0xBA, 0xEF, 0xFA, 0x65, 0x3F, 0xC5, 0x06}} IDeviceRemovedExtendedData1 :: struct #raw_union { #subtype id3d12deviceremovedextendeddata: IDeviceRemovedExtendedData, using id3d12deviceremovedextendeddata1_vtable: ^IDeviceRemovedExtendedData1_VTable, @@ -3387,7 +3426,8 @@ MEASUREMENTS_ACTION :: enum i32 { } -IDevice6_UUID :: "c70b221b-40e4-4a17-89af-025a0727a6dc" +IDevice6_UUID_STRING :: "c70b221b-40e4-4a17-89af-025a0727a6dc" +IDevice6_UUID := &IID{0xc70b221b, 0x40e4, 0x4a17, {0x89, 0xaf, 0x02, 0x5a, 0x07, 0x27, 0xa6, 0xdc}} IDevice6 :: struct #raw_union { #subtype id3d12device5: IDevice5, using id3d12device6_vtable: ^IDevice6_VTable, @@ -3415,7 +3455,8 @@ PROTECTED_RESOURCE_SESSION_DESC1 :: struct { } -IProtectedResourceSession1_UUID :: "D6F12DD6-76FB-406E-8961-4296EEFC0409" +IProtectedResourceSession1_UUID_STRING :: "D6F12DD6-76FB-406E-8961-4296EEFC0409" +IProtectedResourceSession1_UUID := &IID{0xD6F12DD6, 0x76FB, 0x406E, {0x89, 0x61, 0x42, 0x96, 0xEE, 0xFC, 0x04, 0x09}} IProtectedResourceSession1 :: struct #raw_union { #subtype id3d12protectedresourcesession: IProtectedResourceSession, using id3d12protectedresourcesession1_vtable: ^IProtectedResourceSession1_VTable, @@ -3426,7 +3467,8 @@ IProtectedResourceSession1_VTable :: struct { } -IDevice7_UUID :: "5c014b53-68a1-4b9b-8bd1-dd6046b9358b" +IDevice7_UUID_STRING :: "5c014b53-68a1-4b9b-8bd1-dd6046b9358b" +IDevice7_UUID := &IID{0x5c014b53, 0x68a1, 0x4b9b, {0x8b, 0xd1, 0xdd, 0x60, 0x46, 0xb9, 0x35, 0x8b}} IDevice7 :: struct #raw_union { #subtype id3d12device6: IDevice6, using id3d12device7_vtable: ^IDevice7_VTable, @@ -3438,7 +3480,8 @@ IDevice7_VTable :: struct { } -IDevice8_UUID :: "9218E6BB-F944-4F7E-A75C-B1B2C7B701F3" +IDevice8_UUID_STRING :: "9218E6BB-F944-4F7E-A75C-B1B2C7B701F3" +IDevice8_UUID := &IID{0x9218E6BB, 0xF944, 0x4F7E, {0xA7, 0x5C, 0xB1, 0xB2, 0xC7, 0xB7, 0x01, 0xF3}} IDevice8 :: struct #raw_union { #subtype id3d12device7: IDevice7, using id3d12device8_vtable: ^IDevice8_VTable, @@ -3453,7 +3496,8 @@ IDevice8_VTable :: struct { } -IResource1_UUID :: "9D5E227A-4430-4161-88B3-3ECA6BB16E19" +IResource1_UUID_STRING :: "9D5E227A-4430-4161-88B3-3ECA6BB16E19" +IResource1_UUID := &IID{0x9D5E227A, 0x4430, 0x4161, {0x88, 0xB3, 0x3E, 0xCA, 0x6B, 0xB1, 0x6E, 0x19}} IResource1 :: struct #raw_union { #subtype id3d12resource: IResource, using id3d12resource1_vtable: ^IResource1_VTable, @@ -3464,7 +3508,8 @@ IResource1_VTable :: struct { } -IResource2_UUID :: "BE36EC3B-EA85-4AEB-A45A-E9D76404A495" +IResource2_UUID_STRING :: "BE36EC3B-EA85-4AEB-A45A-E9D76404A495" +IResource2_UUID := &IID{0xBE36EC3B, 0xEA85, 0x4AEB, {0xA4, 0x5A, 0xE9, 0xD7, 0x64, 0x04, 0xA4, 0x95}} IResource2 :: struct #raw_union { #subtype id3d12resource1: IResource1, using id3d12resource2_vtable: ^IResource2_VTable, @@ -3475,7 +3520,8 @@ IResource2_VTable :: struct { } -IHeap1_UUID :: "572F7389-2168-49E3-9693-D6DF5871BF6D" +IHeap1_UUID_STRING :: "572F7389-2168-49E3-9693-D6DF5871BF6D" +IHeap1_UUID := &IID{0x572F7389, 0x2168, 0x49E3, {0x96, 0x93, 0xD6, 0xDF, 0x58, 0x71, 0xBF, 0x6D}} IHeap1 :: struct #raw_union { #subtype id3d12heap: IHeap, using id3d12heap1_vtable: ^IHeap1_VTable, @@ -3486,7 +3532,8 @@ IHeap1_VTable :: struct { } -IGraphicsCommandList3_UUID :: "6FDA83A7-B84C-4E38-9AC8-C7BD22016B3D" +IGraphicsCommandList3_UUID_STRING :: "6FDA83A7-B84C-4E38-9AC8-C7BD22016B3D" +IGraphicsCommandList3_UUID := &IID{0x6FDA83A7, 0xB84C, 0x4E38, {0x9A, 0xC8, 0xC7, 0xBD, 0x22, 0x01, 0x6B, 0x3D}} IGraphicsCommandList3 :: struct #raw_union { #subtype id3d12graphicscommandlist2: IGraphicsCommandList2, using id3d12graphicscommandlist3_vtable: ^IGraphicsCommandList3_VTable, @@ -3568,7 +3615,8 @@ RENDER_PASS_FLAGS :: enum u32 { // TODO: make bit_set } -IMetaCommand_UUID :: "DBB84C27-36CE-4FC9-B801-F048C46AC570" +IMetaCommand_UUID_STRING :: "DBB84C27-36CE-4FC9-B801-F048C46AC570" +IMetaCommand_UUID := &IID{0xDBB84C27, 0x36CE, 0x4FC9, {0xB8, 0x01, 0xF0, 0x48, 0xC4, 0x6A, 0xC5, 0x70}} IMetaCommand :: struct #raw_union { #subtype id3d12pageable: IPageable, using id3d12metacommand_vtable: ^IMetaCommand_VTable, @@ -3589,7 +3637,8 @@ DISPATCH_RAYS_DESC :: struct { } -IGraphicsCommandList4_UUID :: "8754318e-d3a9-4541-98cf-645b50dc4874" +IGraphicsCommandList4_UUID_STRING :: "8754318e-d3a9-4541-98cf-645b50dc4874" +IGraphicsCommandList4_UUID := &IID{0x8754318e, 0xd3a9, 0x4541, {0x98, 0xcf, 0x64, 0x5b, 0x50, 0xdc, 0x48, 0x74}} IGraphicsCommandList4 :: struct #raw_union { #subtype id3d12graphicscommandlist3: IGraphicsCommandList3, using id3d12graphicscommandlist4_vtable: ^IGraphicsCommandList4_VTable, @@ -3608,7 +3657,8 @@ IGraphicsCommandList4_VTable :: struct { } -ITools_UUID :: "7071e1f0-e84b-4b33-974f-12fa49de65c5" +ITools_UUID_STRING :: "7071e1f0-e84b-4b33-974f-12fa49de65c5" +ITools_UUID := &IID{0x7071e1f0, 0xe84b, 0x4b33, {0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5}} ITools :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12tools_vtable: ^ITools_VTable, @@ -3632,7 +3682,8 @@ MEMCPY_DEST :: struct { } -IDebug_UUID :: "344488b7-6846-474b-b989-f027448245e0" +IDebug_UUID_STRING :: "344488b7-6846-474b-b989-f027448245e0" +IDebug_UUID := &IID{0x344488b7, 0x6846, 0x474b, {0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0}} IDebug :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debug_vtable: ^IDebug_VTable, @@ -3648,7 +3699,8 @@ GPU_BASED_VALIDATION_FLAGS :: enum u32 { // TODO: make bit_set } -IDebug1_UUID :: "affaa4ca-63fe-4d8e-b8ad-159000af4304" +IDebug1_UUID_STRING :: "affaa4ca-63fe-4d8e-b8ad-159000af4304" +IDebug1_UUID := &IID{0xaffaa4ca, 0x63fe, 0x4d8e, {0xb8, 0xad, 0x15, 0x90, 0x00, 0xaf, 0x43, 0x04}} IDebug1 :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debug1_vtable: ^IDebug1_VTable, @@ -3672,7 +3724,8 @@ IDebug2_VTable :: struct { } -IDebug3_UUID :: "5cf4e58f-f671-4ff1-a542-3686e3d153d1" +IDebug3_UUID_STRING :: "5cf4e58f-f671-4ff1-a542-3686e3d153d1" +IDebug3_UUID := &IID{0x5cf4e58f, 0xf671, 0x4ff1, {0xa5, 0x42, 0x36, 0x86, 0xe3, 0xd1, 0x53, 0xd1}} IDebug3 :: struct #raw_union { #subtype id3d12debug: IDebug, using id3d12debug3_vtable: ^IDebug3_VTable, @@ -3732,7 +3785,8 @@ DEBUG_DEVICE_GPU_SLOWDOWN_PERFORMANCE_FACTOR :: struct { } -IDebugDevice1_UUID :: "a9b71770-d099-4a65-a698-3dee10020f88" +IDebugDevice1_UUID_STRING :: "a9b71770-d099-4a65-a698-3dee10020f88" +IDebugDevice1_UUID := &IID{0xa9b71770, 0xd099, 0x4a65, {0xa6, 0x98, 0x3d, 0xee, 0x10, 0x02, 0x0f, 0x88}} IDebugDevice1 :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debugdevice1_vtable: ^IDebugDevice1_VTable, @@ -3745,7 +3799,8 @@ IDebugDevice1_VTable :: struct { } -IDebugDevice_UUID :: "3febd6dd-4973-4787-8194-e45f9e28923e" +IDebugDevice_UUID_STRING :: "3febd6dd-4973-4787-8194-e45f9e28923e" +IDebugDevice_UUID := &IID{0x3febd6dd, 0x4973, 0x4787, {0x81, 0x94, 0xe4, 0x5f, 0x9e, 0x28, 0x92, 0x3e}} IDebugDevice :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debugdevice_vtable: ^IDebugDevice_VTable, @@ -3758,7 +3813,8 @@ IDebugDevice_VTable :: struct { } -IDebugDevice2_UUID :: "60eccbc1-378d-4df1-894c-f8ac5ce4d7dd" +IDebugDevice2_UUID_STRING :: "60eccbc1-378d-4df1-894c-f8ac5ce4d7dd" +IDebugDevice2_UUID := &IID{0x60eccbc1, 0x378d, 0x4df1, {0x89, 0x4c, 0xf8, 0xac, 0x5c, 0xe4, 0xd7, 0xdd}} IDebugDevice2 :: struct #raw_union { #subtype id3d12debugdevice: IDebugDevice, using id3d12debugdevice2_vtable: ^IDebugDevice2_VTable, @@ -3770,8 +3826,8 @@ IDebugDevice2_VTable :: struct { } - -IDebugCommandQueue_UUID :: "09e0bf36-54ac-484f-8847-4baeeab6053a" +IDebugCommandQueue_UUID_STRING :: "09e0bf36-54ac-484f-8847-4baeeab6053a" +IDebugCommandQueue_UUID := &IID{0x09e0bf36, 0x54ac, 0x484f, {0x88, 0x47, 0x4b, 0xae, 0xea, 0xb6, 0x05, 0x3a}} IDebugCommandQueue :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debugcommandqueue_vtable: ^IDebugCommandQueue_VTable, From 67689ecb21bc1735871b36fdf1411fbffb02e8fb Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Wed, 27 Apr 2022 20:47:05 +0200 Subject: [PATCH 105/245] Typo fix in d3d12.odin --- vendor/directx/d3d12/d3d12.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index 739606249..9b3ebbe78 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -3360,7 +3360,7 @@ VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct { } -IDeviceRemovedExtendedDataSettings_UUID_SRING :: "82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63" +IDeviceRemovedExtendedDataSettings_UUID_STRING :: "82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63" IDeviceRemovedExtendedDataSettings_UUID := &IID{0x82BC481C, 0x6B9B, 0x4030, {0xAE, 0xDB, 0x7E, 0xE3, 0xD1, 0xDF, 0x1E, 0x63}} IDeviceRemovedExtendedDataSettings :: struct #raw_union { #subtype iunknown: IUnknown, From 03c921260091d7dd8b7834163ed3fbdaa4cd46e2 Mon Sep 17 00:00:00 2001 From: Karl Zylinski Date: Wed, 27 Apr 2022 22:30:28 +0200 Subject: [PATCH 106/245] Added some additional IID versions of Direct3D 12 UUIDs that I missed during my first pass. All are accounted for now. --- vendor/directx/d3d12/d3d12.odin | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index 9b3ebbe78..c61b6cfb5 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -3846,7 +3846,8 @@ DEBUG_COMMAND_LIST_GPU_BASED_VALIDATION_SETTINGS :: struct { } -IDebugCommandList1_UUID :: "102ca951-311b-4b01-b11f-ecb83e061b37" +IDebugCommandList1_UUID_STRING :: "102ca951-311b-4b01-b11f-ecb83e061b37" +IDebugCommandList1_UUID := &IID{0x102ca951, 0x311b, 0x4b01, {0xb1, 0x1f, 0xec, 0xb8, 0x3e, 0x06, 0x1b, 0x37}} IDebugCommandList1 :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debugcommandlist1_vtable: ^IDebugCommandList1_VTable, @@ -3859,7 +3860,8 @@ IDebugCommandList1_VTable :: struct { } -IDebugCommandList_UUID :: "09e0bf36-54ac-484f-8847-4baeeab6053f" +IDebugCommandList_UUID_STRING :: "09e0bf36-54ac-484f-8847-4baeeab6053f" +IDebugCommandList_UUID := &IID{0x09e0bf36, 0x54ac, 0x484f, {0x88, 0x47, 0x4b, 0xae, 0xea, 0xb6, 0x05, 0x3f}} IDebugCommandList :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12debugcommandlist_vtable: ^IDebugCommandList_VTable, @@ -3872,7 +3874,8 @@ IDebugCommandList_VTable :: struct { } -IDebugCommandList2_UUID :: "aeb575cf-4e06-48be-ba3b-c450fc96652e" +IDebugCommandList2_UUID_STRING :: "aeb575cf-4e06-48be-ba3b-c450fc96652e" +IDebugCommandList2_UUID := &IID{0xaeb575cf, 0x4e06, 0x48be, {0xba, 0x3b, 0xc4, 0x50, 0xfc, 0x96, 0x65, 0x2e}} IDebugCommandList2 :: struct #raw_union { #subtype id3d12debugcommandlist: IDebugCommandList, using id3d12debugcommandlist2_vtable: ^IDebugCommandList2_VTable, @@ -3884,7 +3887,8 @@ IDebugCommandList2_VTable :: struct { } -ISharingContract_UUID :: "0adf7d52-929c-4e61-addb-ffed30de66ef" +ISharingContract_UUID_STRING :: "0adf7d52-929c-4e61-addb-ffed30de66ef" +ISharingContract_UUID := &IID{0x0adf7d52, 0x929c, 0x4e61, {0xad, 0xdb, 0xff, 0xed, 0x30, 0xde, 0x66, 0xef}} ISharingContract :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12sharingcontract_vtable: ^ISharingContract_VTable, @@ -4789,7 +4793,8 @@ INFO_QUEUE_FILTER :: struct { } -IInfoQueue_UUID :: "0742a90b-c387-483f-b946-30a7e4e61458" +IInfoQueue_UUID_STRING :: "0742a90b-c387-483f-b946-30a7e4e61458" +IInfoQueue_UUID := &IID{0x0742a90b, 0xc387, 0x483f, {0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58}} IInfoQueue :: struct #raw_union { #subtype iunknown: IUnknown, using id3d12infoqueue_vtable: ^IInfoQueue_VTable, @@ -4861,7 +4866,8 @@ SHADING_RATE_COMBINER :: enum i32 { } -IGraphicsCommandList5_UUID :: "55050859-4024-474c-87f5-6472eaee44ea" +IGraphicsCommandList5_UUID_STRING :: "55050859-4024-474c-87f5-6472eaee44ea" +IGraphicsCommandList5_UUID := &IID{0x55050859, 0x4024, 0x474c, {0x87, 0xf5, 0x64, 0x72, 0xea, 0xee, 0x44, 0xea}} IGraphicsCommandList5 :: struct #raw_union { #subtype id3d12graphicscommandlist4: IGraphicsCommandList4, using id3d12graphicscommandlist5_vtable: ^IGraphicsCommandList5_VTable, @@ -4879,7 +4885,8 @@ DISPATCH_MESH_ARGUMENTS :: struct { } -IGraphicsCommandList6_UUID :: "c3827890-e548-4cfa-96cf-5689a9370f80" +IGraphicsCommandList6_UUID_STRING :: "c3827890-e548-4cfa-96cf-5689a9370f80" +IGraphicsCommandList6_UUID := &IID{0xc3827890, 0xe548, 0x4cfa, {0x96, 0xcf, 0x56, 0x89, 0xa9, 0x37, 0x0f, 0x80}} IGraphicsCommandList6 :: struct #raw_union { #subtype id3d12graphicscommandlist5: IGraphicsCommandList5, using id3d12graphicscommandlist6_vtable: ^IGraphicsCommandList6_VTable, From 80878264b63cd8476def629526b294b8e129791a Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 15:29:00 +0200 Subject: [PATCH 107/245] [xml] Speedup. --- core/encoding/xml/debug_print.odin | 18 +- core/encoding/xml/example/xml_example.odin | 77 ++++-- core/encoding/xml/helpers.odin | 28 +-- core/encoding/xml/tokenizer.odin | 11 + core/encoding/xml/xml_reader.odin | 278 +++++++++++---------- tests/core/encoding/xml/test_core_xml.odin | 17 +- 6 files changed, 246 insertions(+), 183 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index e6a8c9433..7c20ac123 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -1,8 +1,7 @@ -package xml /* An XML 1.0 / 1.1 parser - Copyright 2021 Jeroen van Rijn . + Copyright 2021-2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). @@ -10,6 +9,8 @@ package xml List of contributors: Jeroen van Rijn: Initial implementation. */ +package xml + import "core:io" import "core:fmt" @@ -40,17 +41,16 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error written += wprintf(writer, "[Pre-root comment] %v\n", comment) } - if doc.root != nil { + if len(doc.elements) > 0 { + wprintln(writer, " --- ") + print_element(writer, doc, 0) wprintln(writer, " --- ") - print_element(writer, doc.root) - wprintln(writer, " --- ") } return written, .None } -print_element :: proc(writer: io.Writer, element: ^Element, indent := 0) -> (written: int, err: io.Error) { - if element == nil { return } +print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID, indent := 0) -> (written: int, err: io.Error) { using fmt tab :: proc(writer: io.Writer, indent: int) { @@ -61,6 +61,8 @@ print_element :: proc(writer: io.Writer, element: ^Element, indent := 0) -> (wri tab(writer, indent) + element := doc.elements[element_id] + if element.kind == .Element { wprintf(writer, "<%v>\n", element.ident) if len(element.value) > 0 { @@ -74,7 +76,7 @@ print_element :: proc(writer: io.Writer, element: ^Element, indent := 0) -> (wri } for child in element.children { - print_element(writer, child, indent + 1) + print_element(writer, doc, child, indent + 1) } } else if element.kind == .Comment { wprintf(writer, "[COMMENT] %v\n", element.value) diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index daa3c5dab..cadfcfb43 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -1,52 +1,85 @@ package xml_example import "core:encoding/xml" -import "core:os" import "core:mem" import "core:fmt" import "core:time" import "core:strings" import "core:hash" +N :: 1 + example :: proc() { using fmt - doc: ^xml.Document - err: xml.Error + docs: [N]^xml.Document + errs: [N]xml.Error + times: [N]time.Duration + + defer for round in 0..` tag.") - os.exit(1) + eprintln("Could not locate top-level `` tag.") + return } - printf("Found `` with %v children.\n", len(charlist.children)) + printf("Found `` with %v children, %v elements total\n", len(docs[0].elements[charlist].children), docs[0].element_count) - crc32 := doc_hash(doc) + crc32 := doc_hash(docs[0]) printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32) + + for round in 0.. (crc32: u32) { diff --git a/core/encoding/xml/helpers.odin b/core/encoding/xml/helpers.odin index 14597ddbd..48f058334 100644 --- a/core/encoding/xml/helpers.odin +++ b/core/encoding/xml/helpers.odin @@ -1,22 +1,20 @@ -package xml /* An XML 1.0 / 1.1 parser - Copyright 2021 Jeroen van Rijn . + Copyright 2021-2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. This file contains helper functions. */ +package xml - -/* - Find `tag`'s nth child with a given ident. -*/ -find_child_by_ident :: proc(tag: ^Element, ident: string, nth := 0) -> (res: ^Element, found: bool) { - if tag == nil { return nil, false } +// Find parent's nth child with a given ident. +find_child_by_ident :: proc(doc: ^Document, parent_id: Element_ID, ident: string, nth := 0) -> (res: Element_ID, found: bool) { + tag := doc.elements[parent_id] count := 0 - for child in tag.children { + for child_id in tag.children { + child := doc.elements[child_id] /* Skip commments. They have no name. */ @@ -26,18 +24,16 @@ find_child_by_ident :: proc(tag: ^Element, ident: string, nth := 0) -> (res: ^El If the ident matches and it's the nth such child, return it. */ if child.ident == ident { - if count == nth { return child, true } + if count == nth { return child_id, true } count += 1 } } - return nil, false + return 0, false } -/* - Find an attribute by key. -*/ -find_attribute_val_by_key :: proc(tag: ^Element, key: string) -> (val: string, found: bool) { - if tag == nil { return "", false } +// Find an attribute by key. +find_attribute_val_by_key :: proc(doc: ^Document, parent_id: Element_ID, key: string) -> (val: string, found: bool) { + tag := doc.elements[parent_id] for attr in tag.attribs { /* diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index 2da3b7683..c3fece76e 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -1,3 +1,14 @@ +/* + An XML 1.0 / 1.1 parser + + Copyright 2021-2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ package xml import "core:fmt" diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 0315b0e05..636dd0ae4 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -1,8 +1,7 @@ -package xml /* An XML 1.0 / 1.1 parser - Copyright 2021 Jeroen van Rijn . + Copyright 2021-2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. A from-scratch XML implementation, loosely modelled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). @@ -25,12 +24,17 @@ package xml List of contributors: Jeroen van Rijn: Initial implementation. */ +package xml +// An XML 1.0 / 1.1 parser import "core:bytes" -import "core:strings" import "core:encoding/entity" +import "core:intrinsics" import "core:mem" import "core:os" +import "core:strings" + +likely :: intrinsics.expect DEFAULT_Options :: Options{ flags = { @@ -88,7 +92,9 @@ Option_Flag :: enum { Option_Flags :: bit_set[Option_Flag; u16] Document :: struct { - root: ^Element, + elements: [dynamic]Element, + element_count: Element_ID, + prolog: Attributes, encoding: Encoding, @@ -129,8 +135,8 @@ Element :: struct { Comment, }, - parent: ^Element, - children: [dynamic]^Element, + parent: Element_ID, + children: [dynamic]Element_ID, } Attr :: struct { @@ -185,7 +191,7 @@ Error :: enum { No_DocType, Too_Many_DocTypes, - DocType_Must_Proceed_Elements, + DocType_Must_Preceed_Elements, /* If a DOCTYPE is present _or_ the caller @@ -237,12 +243,16 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err doc.tokenizer = t doc.input = data + doc.elements = make([dynamic]Element, 1024, 1024, allocator) + // strings.intern_init(&doc.intern, allocator, allocator) err = .Unexpected_Token - element, parent: ^Element + element, parent: Element_ID - tag_is_open := false + tag_is_open := false + first_element := true + open: Token /* If a DOCTYPE is present, the root tag has to match. @@ -252,6 +262,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err loop: for { skip_whitespace(t) + // NOTE(Jeroen): This is faster as a switch. switch t.ch { case '<': /* @@ -259,35 +270,85 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err */ advance_rune(t) - open := scan(t) - #partial switch open.kind { - - case .Question: + open = scan(t) + // NOTE(Jeroen): We're not using a switch because this if-else chain ordered by likelihood is 2.5% faster at -o:size and -o:speed. + if likely(open.kind, Token_Kind.Ident) == .Ident { /* - 0 { - /* - We've already seen a prolog. - */ - return doc, .Too_Many_Prologs - } else { - /* - Could be ` 0 && expected_doctype != open.text { + error(t, t.offset, "Root Tag doesn't match DOCTYPE. Expected: %v, got: %v\n", expected_doctype, open.text) + return doc, .Invalid_DocType } + } + + /* + One of these should follow: + - `>`, which means we've just opened this tag and expect a later element to close it. + - `/>`, which means this is an 'empty' or self-closing tag. + */ + end_token := scan(t) + #partial switch end_token.kind { + case .Gt: + /* + We're now the new parent. + */ + parent = element + + case .Slash: + /* + Empty tag. Close it. + */ + expect(t, .Gt) or_return + parent = doc.elements[element].parent + element = parent + tag_is_open = false + case: - error(t, t.offset, "Expected \" 0 { return doc, .Too_Many_DocTypes } - if doc.root != nil { - return doc, .DocType_Must_Proceed_Elements + if doc.element_count > 0 { + return doc, .DocType_Must_Preceed_Elements } parse_doctype(doc) or_return @@ -327,14 +388,14 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err comment := scan_comment(t) or_return if .Intern_Comments in opts.flags { - if doc.root == nil { + if len(doc.elements) == 0 { append(&doc.comments, comment) } else { - el := new(Element) - el.parent = element - el.kind = .Comment - el.value = comment - append(&element.children, el) + el := new_element(doc) + doc.elements[el].parent = element + doc.elements[el].kind = .Comment + doc.elements[el].value = comment + append(&doc.elements[element].children, el) } } @@ -343,83 +404,32 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err return } - case .Ident: + } else if open.kind == .Question { /* - e.g. 0 && expected_doctype != open.text { - error(t, t.offset, "Root Tag doesn't match DOCTYPE. Expected: %v, got: %v\n", expected_doctype, open.text) - return doc, .Invalid_DocType + next := scan(t) + #partial switch next.kind { + case .Ident: + if len(next.text) == 3 && strings.to_lower(next.text, context.temp_allocator) == "xml" { + parse_prolog(doc) or_return + } else if len(doc.prolog) > 0 { + /* + We've already seen a prolog. + */ + return doc, .Too_Many_Prologs + } else { + /* + Could be ``, which means we've just opened this tag and expect a later element to close it. - - `/>`, which means this is an 'empty' or self-closing tag. - */ - end_token := scan(t) - #partial switch end_token.kind { - case .Gt: - /* - We're now the new parent. - */ - parent = element - - case .Slash: - /* - Empty tag. Close it. - */ - expect(t, .Gt) or_return - parent = element.parent - element = parent - tag_is_open = false - case: - error(t, t.offset, "Expected close tag, got: %#v\n", end_token) + error(t, t.offset, "Expected \" (err: Error) { */ doc.doctype.rest = string(t.src[offset : t.offset - 1]) return .None +} + +Element_ID :: u32 + +new_element :: proc(doc: ^Document) -> (id: Element_ID) { + element_space := len(doc.elements) + + // Need to resize + if int(doc.element_count) + 1 > element_space { + if element_space < 65536 { + element_space *= 2 + } else { + element_space += 65536 + } + resize(&doc.elements, element_space) + } + + cur := doc.element_count + doc.element_count += 1 + + return cur } \ No newline at end of file diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index 7669afe97..82386b2bb 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -224,7 +224,7 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) if len(doc.doctype.rest) > 0 { - wprintf(writer, "\t%v\n", doc.doctype.rest) + wprintf(writer, "\t%v\n", doc.doctype.rest) } } @@ -232,17 +232,16 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { written += wprintf(writer, "[Pre-root comment] %v\n", comment) } - if doc.root != nil { - wprintln(writer, " --- ") - print_element(writer, doc.root) - wprintln(writer, " --- ") + if doc.element_count > 0 { + wprintln(writer, " --- ") + print_element(writer, doc, 0) + wprintln(writer, " --- ") } return written, .None } - print_element :: proc(writer: io.Writer, element: ^xml.Element, indent := 0) -> (written: int, err: io.Error) { - if element == nil { return } + print_element :: proc(writer: io.Writer, doc: ^xml.Document, element_id: xml.Element_ID, indent := 0) -> (written: int, err: io.Error) { using fmt tab :: proc(writer: io.Writer, indent: int) { @@ -253,6 +252,8 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { tab(writer, indent) + element := doc.elements[element_id] + if element.kind == .Element { wprintf(writer, "<%v>\n", element.ident) if len(element.value) > 0 { @@ -266,7 +267,7 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { } for child in element.children { - print_element(writer, child, indent + 1) + print_element(writer, doc, child, indent + 1) } } else if element.kind == .Comment { wprintf(writer, "[COMMENT] %v\n", element.value) From 127b0ba65e473ae54fe514ea3e695959cefc3b68 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 15:46:36 +0200 Subject: [PATCH 108/245] [xml] Enable tests. --- tests/core/build.bat | 16 +++++++++------- tests/core/encoding/xml/test_core_xml.odin | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/core/build.bat b/tests/core/build.bat index b03fef4bb..8e4ba1d15 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -1,5 +1,6 @@ @echo off -set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. +set COMMON=-no-bounds-check -vet -strict-style +set COLLECTION=-collection:tests=.. set PATH_TO_ODIN==..\..\odin python3 download_assets.py echo --- @@ -35,9 +36,10 @@ echo --- echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa.exe -%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe +%PATH_TO_ODIN% run encoding/hxa %COMMON% %COLLECTION% -out:test_hxa.exe +%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe %PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe +%PATH_TO_ODIN% run encoding/xml %COMMON% -out:test_xml.exe echo --- echo Running core:math/noise tests @@ -47,19 +49,19 @@ echo --- echo --- echo Running core:math tests echo --- -%PATH_TO_ODIN% run math %COMMON% -out:test_core_math.exe +%PATH_TO_ODIN% run math %COMMON% %COLLECTION% -out:test_core_math.exe echo --- echo Running core:math/linalg/glsl tests echo --- -%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_linalg_glsl.exe +%PATH_TO_ODIN% run math/linalg/glsl %COMMON% %COLLECTION% -out:test_linalg_glsl.exe echo --- echo Running core:path/filepath tests echo --- -%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_core_filepath.exe +%PATH_TO_ODIN% run path/filepath %COMMON% %COLLECTION% -out:test_core_filepath.exe echo --- echo Running core:reflect tests echo --- -%PATH_TO_ODIN% run reflect %COMMON% -out:test_core_reflect.exe \ No newline at end of file +%PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe \ No newline at end of file diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index 82386b2bb..a79c939c8 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -168,6 +168,21 @@ TESTS :: []TEST{ err = .Invalid_DocType, crc32 = 0x49b83d0a, }, + + /* + Parse the 8.2 MiB unicode.xml for good measure. + */ + { + filename = "unicode.xml", + options = { + flags = { + .Ignore_Unsupported, + }, + expected_doctype = "", + }, + err = .None, + crc32 = 0xcaa042b9, + }, } when ODIN_TEST { From a1002e69606cf1d60a5936ddd8ab9d069b5d499b Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 17:46:36 +0200 Subject: [PATCH 109/245] Fix -error-pos-style:unix --- src/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 7b0364149..c9e908f11 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -630,6 +630,7 @@ enum BuildFlagKind { BuildFlag_IgnoreWarnings, BuildFlag_WarningsAsErrors, BuildFlag_VerboseErrors, + BuildFlag_ErrorPosStyle, // internal use only BuildFlag_InternalIgnoreLazy, @@ -793,6 +794,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_ErrorPosStyle, str_lit("error-pos-style"), BuildFlagParam_String, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); @@ -1472,6 +1474,15 @@ bool parse_build_flags(Array args) { case BuildFlag_VerboseErrors: build_context.show_error_line = true; break; + + case BuildFlag_ErrorPosStyle: + GB_ASSERT(value.kind == ExactValue_String); + build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Default; + if (value.value_string == "unix" || value.value_string == "UNIX") { + build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Unix; + } + break; + case BuildFlag_InternalIgnoreLazy: build_context.ignore_lazy = true; break; From 1ed84a064bd0d64ba4deba56d5a2704350866d1f Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 18:12:55 +0200 Subject: [PATCH 110/245] Make -error-pos-style case-insensitive. --- src/main.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c9e908f11..ff7bb9f67 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1477,9 +1477,14 @@ bool parse_build_flags(Array args) { case BuildFlag_ErrorPosStyle: GB_ASSERT(value.kind == ExactValue_String); - build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Default; - if (value.value_string == "unix" || value.value_string == "UNIX") { + + if (str_eq_ignore_case(value.value_string, str_lit("odin"))) { + build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Default; + } else if (str_eq_ignore_case(value.value_string, str_lit("unix"))) { build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Unix; + } else { + gb_printf_err("-error-pos-style options are 'unix' and 'odin'\n"); + bad_flags = true; } break; From e53ba3b11612db5c52ecf9b523e4d0ed87f7b1ad Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 18:18:25 +0200 Subject: [PATCH 111/245] Allow -error-pos-style:default as an alias for odin --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ff7bb9f67..818a783e1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1478,12 +1478,12 @@ bool parse_build_flags(Array args) { case BuildFlag_ErrorPosStyle: GB_ASSERT(value.kind == ExactValue_String); - if (str_eq_ignore_case(value.value_string, str_lit("odin"))) { + if (str_eq_ignore_case(value.value_string, str_lit("odin")) || str_eq_ignore_case(value.value_string, str_lit("default"))) { build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Default; } else if (str_eq_ignore_case(value.value_string, str_lit("unix"))) { build_context.ODIN_ERROR_POS_STYLE = ErrorPosStyle_Unix; } else { - gb_printf_err("-error-pos-style options are 'unix' and 'odin'\n"); + gb_printf_err("-error-pos-style options are 'unix', 'odin' and 'default' (odin)\n"); bad_flags = true; } break; From 2fae6eda2321881ccf8d942e2c27e6a7c29aebfd Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 18:58:49 +0200 Subject: [PATCH 112/245] [i18n] Initial i18n support. - Add initial GetText .MO parser - Add translation struct and helpers - Pluralized lookup TODO: - Support for more translation catalog file formats. --- core/i18n/example/i18n_example.odin | 64 +++++++++++ core/i18n/example/messages.pot | 30 +++++ core/i18n/example/nl_NL.mo | Bin 0 -> 672 bytes core/i18n/example/nl_NL.po | 33 ++++++ core/i18n/gettext.odin | 163 ++++++++++++++++++++++++++++ core/i18n/i18n.odin | 116 ++++++++++++++++++++ 6 files changed, 406 insertions(+) create mode 100644 core/i18n/example/i18n_example.odin create mode 100644 core/i18n/example/messages.pot create mode 100644 core/i18n/example/nl_NL.mo create mode 100644 core/i18n/example/nl_NL.po create mode 100644 core/i18n/gettext.odin create mode 100644 core/i18n/i18n.odin diff --git a/core/i18n/example/i18n_example.odin b/core/i18n/example/i18n_example.odin new file mode 100644 index 000000000..f9fb2a353 --- /dev/null +++ b/core/i18n/example/i18n_example.odin @@ -0,0 +1,64 @@ +package i18n_example + +import "core:mem" +import "core:fmt" +import "core:i18n" + +LOC :: i18n.get + +_main :: proc() { + using fmt + + err: i18n.Error + + /* + Parse MO file and set it as the active translation so we can omit `get`'s "catalog" parameter. + */ + i18n.ACTIVE, err = i18n.parse_mo(#load("nl_NL.mo")) + defer i18n.destroy() + + if err != .None { return } + + /* + These are in the .MO catalog. + */ + println("-----") + println(LOC("")) + println("-----") + println(LOC("There are 69,105 leaves here.")) + println("-----") + println(LOC("Hellope, World!")) + + /* + For ease of use, pluralized lookup can use both singular and plural form as key for the same translation. + */ + println("-----") + printf(LOC("There is %d leaf.\n", 1), 1) + printf(LOC("There is %d leaf.\n", 42), 42) + + printf(LOC("There are %d leaves.\n", 1), 1) + printf(LOC("There are %d leaves.\n", 42), 42) + + /* + This isn't. + */ + println("-----") + println(LOC("Come visit us on Discord!")) +} + +main :: proc() { + using fmt + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + _main() + + if len(track.allocation_map) > 0 { + println() + for _, v in track.allocation_map { + printf("%v Leaked %v bytes.\n", v.location, v.size) + } + } +} \ No newline at end of file diff --git a/core/i18n/example/messages.pot b/core/i18n/example/messages.pot new file mode 100644 index 000000000..53d521b6b --- /dev/null +++ b/core/i18n/example/messages.pot @@ -0,0 +1,30 @@ +# Odin i18n Example +# Copyright (C) 2021 Jeroen van Rijn +# This file is distributed under the same license as the PACKAGE package. +# Jeroen van Rijn , 2021. +# +#, fuzzy +msgid "" +msgstr "Project-Id-Version: Example 0.0.1\n" + "Report-Msgid-Bugs-To: Jeroen van Rijn \n" + "POT-Creation-Date: 2021-11-27 19:23+0100\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language: en-GB\n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + +#: i18n_example.odin:28 +msgid "There are 69,105 leaves here." +msgstr "Er zijn hier 69.105 bladeren." + +#: i18n_example.odin:30 +msgid "Hellope, World!" +msgstr "Hallo, Wereld!" + +#: i18n_example.odin:36 +msgid "There is %d leaf.\n" +msgid_plural "There are %d leaves.\n" +msgstr[0] "Er is %d blad.\n" +msgstr[1] "Er zijn %d bladeren.\n" \ No newline at end of file diff --git a/core/i18n/example/nl_NL.mo b/core/i18n/example/nl_NL.mo new file mode 100644 index 0000000000000000000000000000000000000000..0b1a668f4d225e8695e479d6135779288870ac39 GIT binary patch literal 672 zcmca7#4?qEfq{XAfq_AWfq}t>fq{XQfq@|gB*?(PP{6>zz|X+IP{_c*Aj`nO(8$2R zpuxbvFrR^ep@orw;RFK%10MqegD(?AK8A^bL6w1lp^AxtfsuiMff;HJ6Vwg{kJOx; z{DM>+h4B2MoD@Zdkc`x#RE5N%R0T6j9YX_Cg`CvHveaS)kgy(9HnUhkH3cM*rpE;p z0%?GVm8BNzaWMoGSt+DVDFkI^jtHkWr8fxbxABqwNfxLFf!CNG}JY+P%tpEGBwjSFf=gW z^7Zs}MYzUL&w$H0Kd&S;uS7SbvLMw;p(M4UM86;>F*DCvAvq(ls5rI6HZ;Ud*8-ug zC^4@%EwxD3H7_|oB{MJGO2Hy2vxLhhF)zI|F+Ei`BsDSDO2I!RGfx2~rT`M-iqLgW z%}XsxEXgmjQV7UTP01`#FxE5R@<}W%(G39^n*)(U3jnTwoYJDi99_5kqTFIDg}eeV zx7gOmS^>he)yPv&v{f+Fw1&IFN+B;N-p_}N!6PvzCtpV)Jhdnl6t%8J3RR#m&B#nG rQZTdB1I2DqPGU-GQEHwZgKLojBwj&6dR!nrShZ@30!Rd`h>HOL6VbdO literal 0 HcmV?d00001 diff --git a/core/i18n/example/nl_NL.po b/core/i18n/example/nl_NL.po new file mode 100644 index 000000000..1b8acbcc1 --- /dev/null +++ b/core/i18n/example/nl_NL.po @@ -0,0 +1,33 @@ +# Odin i18n Example +# Copyright (C) 2021 Jeroen van Rijn +# This file is distributed under the same license as the PACKAGE package. +# Jeroen van Rijn , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: Example 0.0.1\n" +"Report-Msgid-Bugs-To: Jeroen van Rijn \n" +"POT-Creation-Date: 2021-11-27 19:23+0100\n" +"PO-Revision-Date: 2021-11-28 02:56+0100\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: Odin Language Team\n" +"X-Generator: Poedit 3.0\n" +"Last-Translator: Jeroen van Rijn\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: nl_NL\n" + +#: i18n_example.odin:28 +msgid "There are 69,105 leaves here." +msgstr "Er zijn hier 69.105 bladeren." + +#: i18n_example.odin:30 +msgid "Hellope, World!" +msgstr "Hallo, Wereld!" + +#: i18n_example.odin:36 +msgid "There is %d leaf.\n" +msgid_plural "There are %d leaves.\n" +msgstr[0] "Er is %d blad.\n" +msgstr[1] "Er zijn %d bladeren.\n" diff --git a/core/i18n/gettext.odin b/core/i18n/gettext.odin new file mode 100644 index 000000000..7918e217e --- /dev/null +++ b/core/i18n/gettext.odin @@ -0,0 +1,163 @@ +package i18n +/* + A parser for GNU GetText .MO files. + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + A from-scratch implementation based after the specification found here: + https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ +import "core:os" +import "core:strings" +import "core:bytes" + +parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { + context.allocator = allocator + /* + An MO file should have at least a 4-byte magic, 2 x 2 byte version info, + a 4-byte number of strings value, and 2 x 4-byte offsets. + */ + if len(data) < 20 { + return {}, .MO_File_Invalid + } + + /* + Check magic. Should be 0x950412de in native Endianness. + */ + native := true + magic := read_u32(data, native) or_return + + if magic != 0x950412de { + native = false + magic = read_u32(data, native) or_return + + if magic != 0x950412de { return {}, .MO_File_Invalid_Signature } + } + + /* + We can ignore version_minor at offset 6. + */ + version_major := read_u16(data[4:]) or_return + if version_major > 1 { return {}, .MO_File_Unsupported_Version } + + count := read_u32(data[ 8:]) or_return + original_offset := read_u32(data[12:]) or_return + translated_offset := read_u32(data[16:]) or_return + + if count == 0 { return {}, .Empty_Translation_Catalog } + + /* + Initalize Translation, interner and optional pluralizer. + */ + translation = new(Translation) + translation.pluralize = pluralizer + strings.intern_init(&translation.intern, allocator, allocator) + + for n := u32(0); n < count; n += 1 { + /* + Grab string's original length and offset. + */ + offset := original_offset + 8 * n + if len(data) < int(offset + 8) { return translation, .MO_File_Invalid } + + o_length := read_u32(data[offset :], native) or_return + o_offset := read_u32(data[offset + 4:], native) or_return + + offset = translated_offset + 8 * n + if len(data) < int(offset + 8) { return translation, .MO_File_Invalid } + + t_length := read_u32(data[offset :], native) or_return + t_offset := read_u32(data[offset + 4:], native) or_return + + max_offset := int(max(o_offset + o_length + 1, t_offset + t_length + 1)) + if len(data) < max_offset { return translation, .Premature_EOF } + + key := data[o_offset:][:o_length] + val := data[t_offset:][:t_length] + + /* + Could be a pluralized string. + */ + zero := []byte{0} + + keys := bytes.split(key, zero) + vals := bytes.split(val, zero) + + if len(keys) != len(vals) || max(len(keys), len(vals)) > MAX_PLURALS { + return translation, .MO_File_Incorrect_Plural_Count + } + + for k in keys { + interned_key := strings.intern_get(&translation.intern, string(k)) + + interned_vals: [MAX_PLURALS]string = {} + last_val: string + + i := 0 + for v in vals { + interned_vals[i] = strings.intern_get(&translation.intern, string(v)) + last_val = interned_vals[i] + i += 1 + } + for ; i < MAX_PLURALS; i += 1 { + interned_vals[i] = last_val + } + translation.k_v[interned_key] = interned_vals + } + delete(vals) + delete(keys) + } + return +} + +parse_mo_file :: proc(filename: string, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { + context.allocator = allocator + + data, data_ok := os.read_entire_file(filename) + defer delete(data) + + if !data_ok { return {}, .File_Error } + + return parse_mo_from_slice(data, pluralizer) +} + +parse_mo :: proc { parse_mo_file, parse_mo_from_slice } + +/* + Helpers. +*/ +read_u32 :: proc(data: []u8, native_endian := true) -> (res: u32, err: Error) { + if len(data) < size_of(u32) { return 0, .Premature_EOF } + + val := (^u32)(raw_data(data))^ + + if native_endian { + return val, .None + } else { + when ODIN_ENDIAN == .Little { + return u32(transmute(u32be)val), .None + } else { + return u32(transmute(u32le)val), .None + } + } +} + +read_u16 :: proc(data: []u8, native_endian := true) -> (res: u16, err: Error) { + if len(data) < size_of(u16) { return 0, .Premature_EOF } + + val := (^u16)(raw_data(data))^ + + if native_endian { + return val, .None + } else { + when ODIN_ENDIAN == .Little { + return u16(transmute(u16be)val), .None + } else { + return u16(transmute(u16le)val), .None + } + } +} \ No newline at end of file diff --git a/core/i18n/i18n.odin b/core/i18n/i18n.odin new file mode 100644 index 000000000..7c72f9858 --- /dev/null +++ b/core/i18n/i18n.odin @@ -0,0 +1,116 @@ +package i18n +/* + Internationalization helpers. + + Copyright 2021 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ +import "core:strings" + +/* + TODO: + - Support for more translation catalog file formats. +*/ + +MAX_PLURALS :: 10 + +/* + Currently active catalog. +*/ +ACTIVE: ^Translation + +/* + The main data structure. This can be generated from various different file formats, as long as we have a parser for them. +*/ +Translation :: struct { + k_v: map[string][MAX_PLURALS]string, + intern: strings.Intern, + + pluralize: proc(number: int) -> int, +} + +Error :: enum { + /* + General return values. + */ + None = 0, + Empty_Translation_Catalog, + + /* + Couldn't find, open or read file. + */ + File_Error, + + /* + File too short. + */ + Premature_EOF, + + /* + GNU Gettext *.MO file errors. + */ + MO_File_Invalid_Signature, + MO_File_Unsupported_Version, + MO_File_Invalid, + MO_File_Incorrect_Plural_Count, +} + +/* + Several ways to use: + - get(key), which defaults to the singular form and i18n.ACTIVE catalog, or + - get(key, number), which returns the appropriate plural from the active catalog, or + - get(key, number, catalog) to grab text from a specific one. +*/ +get :: proc(key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: string) { + /* + A lot of languages use singular for 1 item and plural for 0 or more than 1 items. This is our default pluralize rule. + */ + plural := 1 if number != 1 else 0 + + if catalog.pluralize != nil { + plural = catalog.pluralize(number) + } + return get_by_slot(key, plural, catalog) +} + +/* + Several ways to use: + - get_by_slot(key), which defaults to the singular form and i18n.ACTIVE catalog, or + - get_by_slot(key, slot), which returns the requested plural from the active catalog, or + - get_by_slot(key, slot, catalog) to grab text from a specific one. + + If a file format parser doesn't (yet) support plural slots, each of the slots will point at the same string. +*/ +get_by_slot :: proc(key: string, slot := 0, catalog: ^Translation = ACTIVE) -> (value: string) { + if catalog == nil { + /* + Return the key if the catalog catalog hasn't been initialized yet. + */ + return key + } + + /* + Return the translation from the requested slot if this key is known, else return the key. + */ + if translations, ok := catalog.k_v[key]; ok { + plural := min(max(0, slot), MAX_PLURALS - 1) + return translations[plural] + } + return key +} + +/* + Same for destroy: + - destroy(), to clean up the currently active catalog catalog i18n.ACTIVE + - destroy(catalog), to clean up a specific catalog. +*/ +destroy :: proc(catalog: ^Translation = ACTIVE) { + if catalog != nil { + strings.intern_destroy(&catalog.intern) + delete(catalog.k_v) + free(catalog) + } +} \ No newline at end of file From ba23bfb7b9eb32eb9bcf22b0364a25b6ae32203e Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 28 Apr 2022 20:12:32 +0200 Subject: [PATCH 113/245] [i18n] Allow multiple sections. --- core/i18n/gettext.odin | 11 ++++---- core/i18n/i18n.odin | 57 +++++++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/core/i18n/gettext.odin b/core/i18n/gettext.odin index 7918e217e..70c922cfb 100644 --- a/core/i18n/gettext.odin +++ b/core/i18n/gettext.odin @@ -57,6 +57,10 @@ parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allo translation.pluralize = pluralizer strings.intern_init(&translation.intern, allocator, allocator) + // Gettext MO files only have one section. + translation.k_v[""] = {} + section := &translation.k_v[""] + for n := u32(0); n < count; n += 1 { /* Grab string's original length and offset. @@ -94,7 +98,7 @@ parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allo for k in keys { interned_key := strings.intern_get(&translation.intern, string(k)) - interned_vals: [MAX_PLURALS]string = {} + interned_vals := make([]string, len(keys)) last_val: string i := 0 @@ -103,10 +107,7 @@ parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allo last_val = interned_vals[i] i += 1 } - for ; i < MAX_PLURALS; i += 1 { - interned_vals[i] = last_val - } - translation.k_v[interned_key] = interned_vals + section[interned_key] = interned_vals } delete(vals) delete(keys) diff --git a/core/i18n/i18n.odin b/core/i18n/i18n.odin index 7c72f9858..1ee19c2b4 100644 --- a/core/i18n/i18n.odin +++ b/core/i18n/i18n.odin @@ -15,18 +15,19 @@ import "core:strings" - Support for more translation catalog file formats. */ -MAX_PLURALS :: 10 - /* Currently active catalog. */ ACTIVE: ^Translation +// Allow between 1 and 255 plural forms. Default: 10. +MAX_PLURALS :: min(max(#config(ODIN_i18N_MAX_PLURAL_FORMS, 10), 1), 255) + /* The main data structure. This can be generated from various different file formats, as long as we have a parser for them. */ Translation :: struct { - k_v: map[string][MAX_PLURALS]string, + k_v: map[string]map[string][]string, intern: strings.Intern, pluralize: proc(number: int) -> int, @@ -64,7 +65,7 @@ Error :: enum { - get(key, number), which returns the appropriate plural from the active catalog, or - get(key, number, catalog) to grab text from a specific one. */ -get :: proc(key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: string) { +get_single_section :: proc(key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: string) { /* A lot of languages use singular for 1 item and plural for 0 or more than 1 items. This is our default pluralize rule. */ @@ -76,6 +77,25 @@ get :: proc(key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: return get_by_slot(key, plural, catalog) } +/* + Several ways to use: + - get(section, key), which defaults to the singular form and i18n.ACTIVE catalog, or + - get(section, key, number), which returns the appropriate plural from the active catalog, or + - get(section, key, number, catalog) to grab text from a specific one. +*/ +get_by_section :: proc(section, key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: string) { + /* + A lot of languages use singular for 1 item and plural for 0 or more than 1 items. This is our default pluralize rule. + */ + plural := 1 if number != 1 else 0 + + if catalog.pluralize != nil { + plural = catalog.pluralize(number) + } + return get_by_slot(key, plural, catalog) +} +get :: proc{get_single_section, get_by_section} + /* Several ways to use: - get_by_slot(key), which defaults to the singular form and i18n.ACTIVE catalog, or @@ -84,10 +104,22 @@ get :: proc(key: string, number := 0, catalog: ^Translation = ACTIVE) -> (value: If a file format parser doesn't (yet) support plural slots, each of the slots will point at the same string. */ -get_by_slot :: proc(key: string, slot := 0, catalog: ^Translation = ACTIVE) -> (value: string) { - if catalog == nil { +get_by_slot_single_section :: proc(key: string, slot := 0, catalog: ^Translation = ACTIVE) -> (value: string) { + return get_by_slot_by_section("", key, slot, catalog) +} + +/* + Several ways to use: + - get_by_slot(key), which defaults to the singular form and i18n.ACTIVE catalog, or + - get_by_slot(key, slot), which returns the requested plural from the active catalog, or + - get_by_slot(key, slot, catalog) to grab text from a specific one. + + If a file format parser doesn't (yet) support plural slots, each of the slots will point at the same string. +*/ +get_by_slot_by_section :: proc(section, key: string, slot := 0, catalog: ^Translation = ACTIVE) -> (value: string) { + if catalog == nil || section not_in catalog.k_v { /* - Return the key if the catalog catalog hasn't been initialized yet. + Return the key if the catalog catalog hasn't been initialized yet, or the section is not present. */ return key } @@ -95,12 +127,13 @@ get_by_slot :: proc(key: string, slot := 0, catalog: ^Translation = ACTIVE) -> ( /* Return the translation from the requested slot if this key is known, else return the key. */ - if translations, ok := catalog.k_v[key]; ok { - plural := min(max(0, slot), MAX_PLURALS - 1) + if translations, ok := catalog.k_v[section][key]; ok { + plural := min(max(0, slot), len(catalog.k_v[section][key]) - 1) return translations[plural] } return key } +get_by_slot :: proc{get_by_slot_single_section, get_by_slot_by_section} /* Same for destroy: @@ -110,6 +143,12 @@ get_by_slot :: proc(key: string, slot := 0, catalog: ^Translation = ACTIVE) -> ( destroy :: proc(catalog: ^Translation = ACTIVE) { if catalog != nil { strings.intern_destroy(&catalog.intern) + for section in &catalog.k_v { + for key in &catalog.k_v[section] { + delete(catalog.k_v[section][key]) + } + delete(catalog.k_v[section]) + } delete(catalog.k_v) free(catalog) } From 1289c96e2cf9fdcdb9c4fb4988f73c0e319fb329 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 00:29:55 +0200 Subject: [PATCH 114/245] [i18n] QT Linguist TS reader. --- core/encoding/xml/xml_reader.odin | 1 - core/i18n/example/i18n_example.odin | 56 ++++++++-- core/i18n/gettext.odin | 2 +- core/i18n/i18n.odin | 21 +++- core/i18n/qt_linguist.odin | 153 +++++++++++++++++++++++++++ tests/core/assets/XML/nl_NL-qt-ts.ts | 52 ++++----- 6 files changed, 243 insertions(+), 42 deletions(-) create mode 100644 core/i18n/qt_linguist.odin diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 636dd0ae4..6d0d4e1aa 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -87,7 +87,6 @@ Option_Flag :: enum { If a tag body has a comment, it will be stripped unless this option is given. */ Keep_Tag_Body_Comments, - } Option_Flags :: bit_set[Option_Flag; u16] diff --git a/core/i18n/example/i18n_example.odin b/core/i18n/example/i18n_example.odin index f9fb2a353..8c173ee4a 100644 --- a/core/i18n/example/i18n_example.odin +++ b/core/i18n/example/i18n_example.odin @@ -4,9 +4,9 @@ import "core:mem" import "core:fmt" import "core:i18n" -LOC :: i18n.get +_T :: i18n.get -_main :: proc() { +mo :: proc() { using fmt err: i18n.Error @@ -23,27 +23,60 @@ _main :: proc() { These are in the .MO catalog. */ println("-----") - println(LOC("")) + println(_T("")) println("-----") - println(LOC("There are 69,105 leaves here.")) + println(_T("There are 69,105 leaves here.")) println("-----") - println(LOC("Hellope, World!")) + println(_T("Hellope, World!")) /* For ease of use, pluralized lookup can use both singular and plural form as key for the same translation. */ println("-----") - printf(LOC("There is %d leaf.\n", 1), 1) - printf(LOC("There is %d leaf.\n", 42), 42) + printf(_T("There is %d leaf.\n", 1), 1) + printf(_T("There is %d leaf.\n", 42), 42) - printf(LOC("There are %d leaves.\n", 1), 1) - printf(LOC("There are %d leaves.\n", 42), 42) + printf(_T("There are %d leaves.\n", 1), 1) + printf(_T("There are %d leaves.\n", 42), 42) /* This isn't. */ println("-----") - println(LOC("Come visit us on Discord!")) + println(_T("Come visit us on Discord!")) +} + +qt :: proc() { + using fmt + + err: i18n.Error + + /* + Parse QT file and set it as the active translation so we can omit `get`'s "catalog" parameter. + */ + i18n.ACTIVE, err = i18n.parse_qt(#load("../../../tests/core/assets/XML/nl_NL-qt-ts.ts")) + defer i18n.destroy() + + fmt.printf("parse_qt returned %v\n", err) + if err != .None { + return + } + + /* + These are in the .TS catalog. + */ + println("--- Page section ---") + println("Page:Text for translation =", _T("Page", "Text for translation")) + println("-----") + println("Page:Also text to translate =", _T("Page", "Also text to translate")) + println("-----") + println("--- installscript section ---") + println("installscript:99 bottles of beer on the wall =", _T("installscript", "99 bottles of beer on the wall")) + println("-----") + println("--- apple_count section ---") + println("apple_count:%d apple(s) =") + println("\t 1 =", _T("apple_count", "%d apple(s)", 1)) + println("\t 42 =", _T("apple_count", "%d apple(s)", 42)) } main :: proc() { @@ -53,7 +86,8 @@ main :: proc() { mem.tracking_allocator_init(&track, context.allocator) context.allocator = mem.tracking_allocator(&track) - _main() + // mo() + qt() if len(track.allocation_map) > 0 { println() diff --git a/core/i18n/gettext.odin b/core/i18n/gettext.odin index 70c922cfb..54c5a1111 100644 --- a/core/i18n/gettext.odin +++ b/core/i18n/gettext.odin @@ -2,7 +2,7 @@ package i18n /* A parser for GNU GetText .MO files. - Copyright 2021 Jeroen van Rijn . + Copyright 2021-2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. A from-scratch implementation based after the specification found here: diff --git a/core/i18n/i18n.odin b/core/i18n/i18n.odin index 1ee19c2b4..36204efd9 100644 --- a/core/i18n/i18n.odin +++ b/core/i18n/i18n.odin @@ -2,7 +2,7 @@ package i18n /* Internationalization helpers. - Copyright 2021 Jeroen van Rijn . + Copyright 2021-2022 Jeroen van Rijn . Made available under Odin's BSD-3 license. List of contributors: @@ -26,8 +26,11 @@ MAX_PLURALS :: min(max(#config(ODIN_i18N_MAX_PLURAL_FORMS, 10), 1), 255) /* The main data structure. This can be generated from various different file formats, as long as we have a parser for them. */ + +Section :: map[string][]string + Translation :: struct { - k_v: map[string]map[string][]string, + k_v: map[string]Section, // k_v[section][key][plural_form] = ... intern: strings.Intern, pluralize: proc(number: int) -> int, @@ -39,6 +42,7 @@ Error :: enum { */ None = 0, Empty_Translation_Catalog, + Duplicate_Key, /* Couldn't find, open or read file. @@ -57,6 +61,17 @@ Error :: enum { MO_File_Unsupported_Version, MO_File_Invalid, MO_File_Incorrect_Plural_Count, + + /* + Qt Linguist *.TS file errors. + */ + TS_File_Parse_Error, + TS_File_Expected_Context, + TS_File_Expected_Context_Name, + TS_File_Expected_Source, + TS_File_Expected_Translation, + TS_File_Expected_NumerusForm, + } /* @@ -92,7 +107,7 @@ get_by_section :: proc(section, key: string, number := 0, catalog: ^Translation if catalog.pluralize != nil { plural = catalog.pluralize(number) } - return get_by_slot(key, plural, catalog) + return get_by_slot(section, key, plural, catalog) } get :: proc{get_single_section, get_by_section} diff --git a/core/i18n/qt_linguist.odin b/core/i18n/qt_linguist.odin new file mode 100644 index 000000000..65d51444e --- /dev/null +++ b/core/i18n/qt_linguist.odin @@ -0,0 +1,153 @@ +package i18n +/* + A parser for Qt Linguist TS files. + + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + A from-scratch implementation based after the specification found here: + https://doc.qt.io/qt-5/linguist-ts-file-format.html + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ +import "core:os" +import "core:encoding/xml" +import "core:strings" + +TS_XML_Options := xml.Options{ + flags = { + .Input_May_Be_Modified, + .Must_Have_Prolog, + .Must_Have_DocType, + .Ignore_Unsupported, + .Unbox_CDATA, + .Decode_SGML_Entities, + }, + expected_doctype = "TS", +} + +parse_qt_linguist_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { + context.allocator = allocator + + ts, xml_err := xml.parse(data, TS_XML_Options) + defer xml.destroy(ts) + + if xml_err != .None || ts.element_count < 1 || ts.elements[0].ident != "TS" || len(ts.elements[0].children) == 0 { + return nil, .TS_File_Parse_Error + } + + /* + Initalize Translation, interner and optional pluralizer. + */ + translation = new(Translation) + translation.pluralize = pluralizer + strings.intern_init(&translation.intern, allocator, allocator) + + section: ^Section + + for child_id in ts.elements[0].children { + // These should be s. + child := ts.elements[child_id] + if child.ident != "context" { + return translation, .TS_File_Expected_Context + } + + // Find section name. + section_name_id, section_name_found := xml.find_child_by_ident(ts, child_id, "name") + if !section_name_found { + return translation, .TS_File_Expected_Context_Name, + } + + section_name := ts.elements[section_name_id].value + + if section_name not_in translation.k_v { + translation.k_v[section_name] = {} + } + section = &translation.k_v[section_name] + + // Find messages in section. + nth: int + for { + message_id, message_found := xml.find_child_by_ident(ts, child_id, "message", nth) + if !message_found { + break + } + + numerus_tag, _ := xml.find_attribute_val_by_key(ts, message_id, "numerus") + has_plurals := numerus_tag == "yes" + + // We must have a = key + source_id, source_found := xml.find_child_by_ident(ts, message_id, "source") + if !source_found { + return translation, .TS_File_Expected_Source + } + + // We must have a + translation_id, translation_found := xml.find_child_by_ident(ts, message_id, "translation") + if !translation_found { + return translation, .TS_File_Expected_Translation + } + + source := ts.elements[source_id] + xlat := ts.elements[translation_id] + + if source.value in section { + return translation, .Duplicate_Key + } + + if has_plurals { + if xlat.value != "" { + return translation, .TS_File_Expected_NumerusForm + } + + num_plurals: int + for { + numerus_id, numerus_found := xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) + if !numerus_found { + break + } + num_plurals += 1 + } + + if num_plurals < 2 { + return translation, .TS_File_Expected_NumerusForm + } + section[source.value] = make([]string, num_plurals) + + num_plurals = 0 + for { + numerus_id, numerus_found := xml.find_child_by_ident(ts, translation_id, "numerusform", num_plurals) + if !numerus_found { + break + } + numerus := ts.elements[numerus_id] + section[source.value][num_plurals] = strings.intern_get(&translation.intern, numerus.value) + + num_plurals += 1 + } + } else { + // Single translation + section[source.value] = make([]string, 1) + section[source.value][0] = strings.intern_get(&translation.intern, xlat.value) + } + + nth += 1 + } + } + + return +} + +parse_qt_linguist_file :: proc(filename: string, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { + context.allocator = allocator + + data, data_ok := os.read_entire_file(filename) + defer delete(data) + + if !data_ok { return {}, .File_Error } + + return parse_qt_linguist_from_slice(data, pluralizer) +} + +parse_qt :: proc { parse_qt_linguist_file, parse_qt_linguist_from_slice } \ No newline at end of file diff --git a/tests/core/assets/XML/nl_NL-qt-ts.ts b/tests/core/assets/XML/nl_NL-qt-ts.ts index 6ec3f2f47..36c95ce2e 100644 --- a/tests/core/assets/XML/nl_NL-qt-ts.ts +++ b/tests/core/assets/XML/nl_NL-qt-ts.ts @@ -2,34 +2,34 @@ - Page - - Text for translation - commenting - Tekst om te vertalen - - - Also text to translate - some text - Ook tekst om te vertalen - + Page + + Text for translation + commenting + Tekst om te vertalen + + + Also text to translate + some text + Ook tekst om te vertalen + - installscript - - 99 bottles of beer on the wall - some new comments here - 99 flessen bier op de muur - + installscript + + 99 bottles of beer on the wall + some new comments here + 99 flessen bier op de muur + - apple_count - - %d apple(s) - - %d appel - %d appels - - - + apple_count + + %d apple(s) + + %d appel + %d appels + + + From 9ce64916e6f6db558d53b9a852e2169b937317f8 Mon Sep 17 00:00:00 2001 From: sduman Date: Thu, 28 Apr 2022 17:08:48 -0600 Subject: [PATCH 115/245] Add missing result parameter names This adds some missing result parameters names back to pop_front_safe. Currently it the procedure won't compile since it's referencing missing variable names. --- core/container/small_array/small_array.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/container/small_array/small_array.odin b/core/container/small_array/small_array.odin index 5cd421c84..4dd16f30c 100644 --- a/core/container/small_array/small_array.odin +++ b/core/container/small_array/small_array.odin @@ -86,7 +86,7 @@ pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) { return } -pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (T, bool) { +pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) { if N > 0 && a.len > 0 { item = a.data[0] s := slice(a) @@ -114,4 +114,4 @@ push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) { append_elem :: push_back append_elems :: push_back_elems push :: proc{push_back, push_back_elems} -append :: proc{push_back, push_back_elems} \ No newline at end of file +append :: proc{push_back, push_back_elems} From 789ab99c4d2052f555721683ea0df8304508c9d1 Mon Sep 17 00:00:00 2001 From: awwdev Date: Fri, 29 Apr 2022 11:21:23 +0200 Subject: [PATCH 116/245] replaced a few [^]u8 with cstring --- vendor/OpenGL/impl.odin | 6 +++--- vendor/OpenGL/wrappers.odin | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vendor/OpenGL/impl.odin b/vendor/OpenGL/impl.odin index 966f8467d..4c5ff57a3 100644 --- a/vendor/OpenGL/impl.odin +++ b/vendor/OpenGL/impl.odin @@ -1250,14 +1250,14 @@ impl_VertexAttribLFormat: proc "c" (attribindex: u32, size: i32, typ impl_VertexAttribBinding: proc "c" (attribindex: u32, bindingindex: u32) impl_VertexBindingDivisor: proc "c" (bindingindex: u32, divisor: u32) impl_DebugMessageControl: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool) -impl_DebugMessageInsert: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: [^]u8) +impl_DebugMessageInsert: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring) impl_DebugMessageCallback: proc "c" (callback: debug_proc_t, userParam: rawptr) impl_GetDebugMessageLog: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32 impl_PushDebugGroup: proc "c" (source: u32, id: u32, length: i32, message: cstring) impl_PopDebugGroup: proc "c" () -impl_ObjectLabel: proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8) +impl_ObjectLabel: proc "c" (identifier: u32, name: u32, length: i32, label: cstring) impl_GetObjectLabel: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8) -impl_ObjectPtrLabel: proc "c" (ptr: rawptr, length: i32, label: [^]u8) +impl_ObjectPtrLabel: proc "c" (ptr: rawptr, length: i32, label: cstring) impl_GetObjectPtrLabel: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8) load_4_3 :: proc(set_proc_address: Set_Proc_Address_Type) { diff --git a/vendor/OpenGL/wrappers.odin b/vendor/OpenGL/wrappers.odin index 10a601eec..6113cf998 100644 --- a/vendor/OpenGL/wrappers.odin +++ b/vendor/OpenGL/wrappers.odin @@ -589,14 +589,14 @@ when !ODIN_DEBUG { VertexAttribBinding :: proc "c" (attribindex: u32, bindingindex: u32) { impl_VertexAttribBinding(attribindex, bindingindex) } VertexBindingDivisor :: proc "c" (bindingindex: u32, divisor: u32) { impl_VertexBindingDivisor(bindingindex, divisor) } DebugMessageControl :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool) { impl_DebugMessageControl(source, type, severity, count, ids, enabled) } - DebugMessageInsert :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8) { impl_DebugMessageInsert(source, type, id, severity, length, buf) } + DebugMessageInsert :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring) { impl_DebugMessageInsert(source, type, id, severity, length, message) } DebugMessageCallback :: proc "c" (callback: debug_proc_t, userParam: rawptr) { impl_DebugMessageCallback(callback, userParam) } GetDebugMessageLog :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32 { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog); return ret } PushDebugGroup :: proc "c" (source: u32, id: u32, length: i32, message: cstring) { impl_PushDebugGroup(source, id, length, message) } PopDebugGroup :: proc "c" () { impl_PopDebugGroup() } - ObjectLabel :: proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8) { impl_ObjectLabel(identifier, name, length, label) } + ObjectLabel :: proc "c" (identifier: u32, name: u32, length: i32, label: cstring) { impl_ObjectLabel(identifier, name, length, label) } GetObjectLabel :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8) { impl_GetObjectLabel(identifier, name, bufSize, length, label) } - ObjectPtrLabel :: proc "c" (ptr: rawptr, length: i32, label: [^]u8) { impl_ObjectPtrLabel(ptr, length, label) } + ObjectPtrLabel :: proc "c" (ptr: rawptr, length: i32, label: cstring) { impl_ObjectPtrLabel(ptr, length, label) } GetObjectPtrLabel :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8) { impl_GetObjectPtrLabel(ptr, bufSize, length, label) } // VERSION_4_4 @@ -1389,14 +1389,14 @@ when !ODIN_DEBUG { VertexAttribBinding :: proc "c" (attribindex: u32, bindingindex: u32, loc := #caller_location) { impl_VertexAttribBinding(attribindex, bindingindex); debug_helper(loc, 0, attribindex, bindingindex) } VertexBindingDivisor :: proc "c" (bindingindex: u32, divisor: u32, loc := #caller_location) { impl_VertexBindingDivisor(bindingindex, divisor); debug_helper(loc, 0, bindingindex, divisor) } DebugMessageControl :: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: bool, loc := #caller_location) { impl_DebugMessageControl(source, type, severity, count, ids, enabled); debug_helper(loc, 0, source, type, severity, count, ids, enabled) } - DebugMessageInsert :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8, loc := #caller_location) { impl_DebugMessageInsert(source, type, id, severity, length, buf); debug_helper(loc, 0, source, type, id, severity, length, buf) } + DebugMessageInsert :: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, message: cstring, loc := #caller_location) { impl_DebugMessageInsert(source, type, id, severity, length, message); debug_helper(loc, 0, source, type, id, severity, length, message) } DebugMessageCallback :: proc "c" (callback: debug_proc_t, userParam: rawptr, loc := #caller_location) { impl_DebugMessageCallback(callback, userParam); debug_helper(loc, 0, callback, userParam) } GetDebugMessageLog :: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8, loc := #caller_location) -> u32 { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog); debug_helper(loc, 1, ret, count, bufSize, sources, types, ids, severities, lengths, messageLog); return ret } PushDebugGroup :: proc "c" (source: u32, id: u32, length: i32, message: cstring, loc := #caller_location) { impl_PushDebugGroup(source, id, length, message); debug_helper(loc, 0, source, id, length, message) } PopDebugGroup :: proc "c" (loc := #caller_location) { impl_PopDebugGroup(); debug_helper(loc, 0) } - ObjectLabel :: proc "c" (identifier: u32, name: u32, length: i32, label: [^]u8, loc := #caller_location) { impl_ObjectLabel(identifier, name, length, label); debug_helper(loc, 0, identifier, name, length, label) } + ObjectLabel :: proc "c" (identifier: u32, name: u32, length: i32, label: cstring, loc := #caller_location) { impl_ObjectLabel(identifier, name, length, label); debug_helper(loc, 0, identifier, name, length, label) } GetObjectLabel :: proc "c" (identifier: u32, name: u32, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location) { impl_GetObjectLabel(identifier, name, bufSize, length, label); debug_helper(loc, 0, identifier, name, bufSize, length, label) } - ObjectPtrLabel :: proc "c" (ptr: rawptr, length: i32, label: [^]u8, loc := #caller_location) { impl_ObjectPtrLabel(ptr, length, label); debug_helper(loc, 0, ptr, length, label) } + ObjectPtrLabel :: proc "c" (ptr: rawptr, length: i32, label: cstring, loc := #caller_location) { impl_ObjectPtrLabel(ptr, length, label); debug_helper(loc, 0, ptr, length, label) } GetObjectPtrLabel :: proc "c" (ptr: rawptr, bufSize: i32, length: ^i32, label: [^]u8, loc := #caller_location) { impl_GetObjectPtrLabel(ptr, bufSize, length, label); debug_helper(loc, 0, ptr, bufSize, length, label) } // VERSION_4_4 From e9cfcf9eccb5af63ce0aa6a71894322f16beedc5 Mon Sep 17 00:00:00 2001 From: awwdev Date: Fri, 29 Apr 2022 11:26:57 +0200 Subject: [PATCH 117/245] fix typo in TexImage3D --- vendor/OpenGL/impl.odin | 2 +- vendor/OpenGL/wrappers.odin | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/OpenGL/impl.odin b/vendor/OpenGL/impl.odin index 4c5ff57a3..530865cb0 100644 --- a/vendor/OpenGL/impl.odin +++ b/vendor/OpenGL/impl.odin @@ -199,7 +199,7 @@ load_1_1 :: proc(set_proc_address: Set_Proc_Address_Type) { // VERSION_1_2 impl_DrawRangeElements: proc "c" (mode: u32, start: u32, end: u32, count: i32, type: u32, indices: rawptr) -impl_TexImage3D: proc "c" (target: u32, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, type: u32, pixels: rawptr) +impl_TexImage3D: proc "c" (target: u32, level: i32, internalformat: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, type: u32, data: rawptr) impl_TexSubImage3D: proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr) impl_CopyTexSubImage3D: proc "c" (target: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, x: i32, y: i32, width: i32, height: i32) diff --git a/vendor/OpenGL/wrappers.odin b/vendor/OpenGL/wrappers.odin index 6113cf998..c0b5304b0 100644 --- a/vendor/OpenGL/wrappers.odin +++ b/vendor/OpenGL/wrappers.odin @@ -70,7 +70,7 @@ when !ODIN_DEBUG { // VERSION_1_2 DrawRangeElements :: proc "c" (mode, start, end: u32, count: i32, type: u32, indices: rawptr) { impl_DrawRangeElements(mode, start, end, count, type, indices) } - TexImage3D :: proc "c" (target: u32, level, internalformat, width, height, depth, border: i32, format, type: u32, pixels: rawptr) { impl_TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) } + TexImage3D :: proc "c" (target: u32, level, internalformat, width, height, depth, border: i32, format, type: u32, data: rawptr) { impl_TexImage3D(target, level, internalformat, width, height, depth, border, format, type, data) } TexSubImage3D :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, width, height, depth: i32, format, type: u32, pixels: rawptr) { impl_TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) } CopyTexSubImage3D :: proc "c" (target: u32, level, xoffset, yoffset, zoffset, x, y, width, height: i32) { impl_CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height) } From 2e11a8da5b3d0031f99a7534b029f08dc0fe5a36 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 13:02:40 +0200 Subject: [PATCH 118/245] [i18n] Move to `core:text/i18n`. --- core/{ => text}/i18n/example/i18n_example.odin | 5 +++-- core/{ => text}/i18n/example/messages.pot | 0 core/{ => text}/i18n/example/nl_NL.mo | Bin core/{ => text}/i18n/example/nl_NL.po | 0 core/{ => text}/i18n/gettext.odin | 0 core/{ => text}/i18n/i18n.odin | 0 core/{ => text}/i18n/qt_linguist.odin | 0 7 files changed, 3 insertions(+), 2 deletions(-) rename core/{ => text}/i18n/example/i18n_example.odin (91%) rename core/{ => text}/i18n/example/messages.pot (100%) rename core/{ => text}/i18n/example/nl_NL.mo (100%) rename core/{ => text}/i18n/example/nl_NL.po (100%) rename core/{ => text}/i18n/gettext.odin (100%) rename core/{ => text}/i18n/i18n.odin (100%) rename core/{ => text}/i18n/qt_linguist.odin (100%) diff --git a/core/i18n/example/i18n_example.odin b/core/text/i18n/example/i18n_example.odin similarity index 91% rename from core/i18n/example/i18n_example.odin rename to core/text/i18n/example/i18n_example.odin index 8c173ee4a..32eb38a7d 100644 --- a/core/i18n/example/i18n_example.odin +++ b/core/text/i18n/example/i18n_example.odin @@ -2,7 +2,7 @@ package i18n_example import "core:mem" import "core:fmt" -import "core:i18n" +import "core:text/i18n" _T :: i18n.get @@ -31,6 +31,7 @@ mo :: proc() { /* For ease of use, pluralized lookup can use both singular and plural form as key for the same translation. + This is a quirk of the GetText format which has separate keys for their different plurals. */ println("-----") printf(_T("There is %d leaf.\n", 1), 1) @@ -54,7 +55,7 @@ qt :: proc() { /* Parse QT file and set it as the active translation so we can omit `get`'s "catalog" parameter. */ - i18n.ACTIVE, err = i18n.parse_qt(#load("../../../tests/core/assets/XML/nl_NL-qt-ts.ts")) + i18n.ACTIVE, err = i18n.parse_qt(#load("../../../../tests/core/assets/XML/nl_NL-qt-ts.ts")) defer i18n.destroy() fmt.printf("parse_qt returned %v\n", err) diff --git a/core/i18n/example/messages.pot b/core/text/i18n/example/messages.pot similarity index 100% rename from core/i18n/example/messages.pot rename to core/text/i18n/example/messages.pot diff --git a/core/i18n/example/nl_NL.mo b/core/text/i18n/example/nl_NL.mo similarity index 100% rename from core/i18n/example/nl_NL.mo rename to core/text/i18n/example/nl_NL.mo diff --git a/core/i18n/example/nl_NL.po b/core/text/i18n/example/nl_NL.po similarity index 100% rename from core/i18n/example/nl_NL.po rename to core/text/i18n/example/nl_NL.po diff --git a/core/i18n/gettext.odin b/core/text/i18n/gettext.odin similarity index 100% rename from core/i18n/gettext.odin rename to core/text/i18n/gettext.odin diff --git a/core/i18n/i18n.odin b/core/text/i18n/i18n.odin similarity index 100% rename from core/i18n/i18n.odin rename to core/text/i18n/i18n.odin diff --git a/core/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin similarity index 100% rename from core/i18n/qt_linguist.odin rename to core/text/i18n/qt_linguist.odin From 957ef8e8fe885fed32b62d532e642be5e756ea67 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 13:16:30 +0200 Subject: [PATCH 119/245] [i18n/xml] Move I18N XML files to their own assets directory. --- .../core/assets/I18N}/messages.pot | 0 .../core/assets/{XML => I18N}/nl_NL-qt-ts.ts | 0 .../{XML => I18N}/nl_NL-xliff-1.2.xliff | 0 .../{XML => I18N}/nl_NL-xliff-2.0.xliff | 0 .../core/assets/I18N}/nl_NL.mo | Bin .../core/assets/I18N}/nl_NL.po | 0 tests/core/encoding/xml/test_core_xml.odin | 33 ++++++------------ 7 files changed, 11 insertions(+), 22 deletions(-) rename {core/text/i18n/example => tests/core/assets/I18N}/messages.pot (100%) rename tests/core/assets/{XML => I18N}/nl_NL-qt-ts.ts (100%) rename tests/core/assets/{XML => I18N}/nl_NL-xliff-1.2.xliff (100%) rename tests/core/assets/{XML => I18N}/nl_NL-xliff-2.0.xliff (100%) rename {core/text/i18n/example => tests/core/assets/I18N}/nl_NL.mo (100%) rename {core/text/i18n/example => tests/core/assets/I18N}/nl_NL.po (100%) diff --git a/core/text/i18n/example/messages.pot b/tests/core/assets/I18N/messages.pot similarity index 100% rename from core/text/i18n/example/messages.pot rename to tests/core/assets/I18N/messages.pot diff --git a/tests/core/assets/XML/nl_NL-qt-ts.ts b/tests/core/assets/I18N/nl_NL-qt-ts.ts similarity index 100% rename from tests/core/assets/XML/nl_NL-qt-ts.ts rename to tests/core/assets/I18N/nl_NL-qt-ts.ts diff --git a/tests/core/assets/XML/nl_NL-xliff-1.2.xliff b/tests/core/assets/I18N/nl_NL-xliff-1.2.xliff similarity index 100% rename from tests/core/assets/XML/nl_NL-xliff-1.2.xliff rename to tests/core/assets/I18N/nl_NL-xliff-1.2.xliff diff --git a/tests/core/assets/XML/nl_NL-xliff-2.0.xliff b/tests/core/assets/I18N/nl_NL-xliff-2.0.xliff similarity index 100% rename from tests/core/assets/XML/nl_NL-xliff-2.0.xliff rename to tests/core/assets/I18N/nl_NL-xliff-2.0.xliff diff --git a/core/text/i18n/example/nl_NL.mo b/tests/core/assets/I18N/nl_NL.mo similarity index 100% rename from core/text/i18n/example/nl_NL.mo rename to tests/core/assets/I18N/nl_NL.mo diff --git a/core/text/i18n/example/nl_NL.po b/tests/core/assets/I18N/nl_NL.po similarity index 100% rename from core/text/i18n/example/nl_NL.po rename to tests/core/assets/I18N/nl_NL.po diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index a79c939c8..07cbc1779 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -27,7 +27,7 @@ TEST :: struct { /* Relative to ODIN_ROOT */ -TEST_FILE_PATH_PREFIX :: "tests/core/assets/XML" +TEST_FILE_PATH_PREFIX :: "tests/core/assets" TESTS :: []TEST{ /* @@ -35,23 +35,12 @@ TESTS :: []TEST{ */ { - /* - - - <恥ずべきフクロウ 올빼미_id="Foozle Hello, world!"]]>Barzle"> - <부끄러운:barzle> - ရှက်စရာ ဇီးကွက် - Owl of Shame - More CDATA Hello, world! Nonsense. - - */ - /* Tests UTF-8 idents and values. Test namespaced ident. Tests that nested partial CDATA start doesn't trip up parser. */ - filename = "utf8.xml", + filename = "XML/utf8.xml", options = { flags = { .Ignore_Unsupported, .Intern_Comments, @@ -66,7 +55,7 @@ TESTS :: []TEST{ Same as above. Unbox CDATA in data tag. */ - filename = "utf8.xml", + filename = "XML/utf8.xml", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, @@ -81,7 +70,7 @@ TESTS :: []TEST{ Simple Qt TS translation file. `core:i18n` requires it to be parsed properly. */ - filename = "nl_NL-qt-ts.ts", + filename = "I18N/nl_NL-qt-ts.ts", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, @@ -96,7 +85,7 @@ TESTS :: []TEST{ Simple XLiff 1.2 file. `core:i18n` requires it to be parsed properly. */ - filename = "nl_NL-xliff-1.2.xliff", + filename = "I18N/nl_NL-xliff-1.2.xliff", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, @@ -111,7 +100,7 @@ TESTS :: []TEST{ Simple XLiff 2.0 file. `core:i18n` requires it to be parsed properly. */ - filename = "nl_NL-xliff-2.0.xliff", + filename = "I18N/nl_NL-xliff-2.0.xliff", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, @@ -122,7 +111,7 @@ TESTS :: []TEST{ }, { - filename = "entities.html", + filename = "XML/entities.html", options = { flags = { .Ignore_Unsupported, .Intern_Comments, @@ -133,7 +122,7 @@ TESTS :: []TEST{ }, { - filename = "entities.html", + filename = "XML/entities.html", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, @@ -144,7 +133,7 @@ TESTS :: []TEST{ }, { - filename = "entities.html", + filename = "XML/entities.html", options = { flags = { .Ignore_Unsupported, .Intern_Comments, .Unbox_CDATA, .Decode_SGML_Entities, @@ -158,7 +147,7 @@ TESTS :: []TEST{ Then we test that certain errors are returned as expected. */ { - filename = "utf8.xml", + filename = "XML/utf8.xml", options = { flags = { .Ignore_Unsupported, .Intern_Comments, @@ -173,7 +162,7 @@ TESTS :: []TEST{ Parse the 8.2 MiB unicode.xml for good measure. */ { - filename = "unicode.xml", + filename = "XML/unicode.xml", options = { flags = { .Ignore_Unsupported, From 09e1c0fa27a262d7fbfaa5b3e305054304847e75 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 16:19:13 +0200 Subject: [PATCH 120/245] [i18n] Add tests. --- core/text/i18n/doc.odin | 111 ++++++++++++ core/text/i18n/example/i18n_example.odin | 99 ----------- core/text/i18n/gettext.odin | 9 +- core/text/i18n/i18n.odin | 8 + core/text/i18n/qt_linguist.odin | 8 +- examples/all/all_main.odin | 4 + tests/core/Makefile | 5 +- tests/core/assets/I18N/duplicate-key.ts | 22 +++ tests/core/build.bat | 7 +- tests/core/text/i18n/test_core_text_i18n.odin | 165 ++++++++++++++++++ 10 files changed, 329 insertions(+), 109 deletions(-) create mode 100644 core/text/i18n/doc.odin delete mode 100644 core/text/i18n/example/i18n_example.odin create mode 100644 tests/core/assets/I18N/duplicate-key.ts create mode 100644 tests/core/text/i18n/test_core_text_i18n.odin diff --git a/core/text/i18n/doc.odin b/core/text/i18n/doc.odin new file mode 100644 index 000000000..cff1ce11f --- /dev/null +++ b/core/text/i18n/doc.odin @@ -0,0 +1,111 @@ +//+ignore +package i18n + +/* + The i18n package is flexible and easy to use. + + It has one call to get a translation: `get`, which the user can alias into something like `T`. + + `get`, referred to as `T` here, has a few different signatures. + All of them will return the key if the entry can't be found in the active translation catalog. + + - `T(key)` returns the translation of `key`. + - `T(key, n)` returns a pluralized translation of `key` according to value `n`. + + - `T(section, key)` returns the translation of `key` in `section`. + - `T(section, key, n)` returns a pluralized translation of `key` in `section` according to value `n`. + + By default lookup take place in the global `i18n.ACTIVE` catalog for ease of use. + If you want to override which translation to use, for example in a language preview dialog, you can use the following: + + - `T(key, n, catalog)` returns the pluralized version of `key` from explictly supplied catalog. + - `T(section, key, n, catalog)` returns the pluralized version of `key` in `section` from explictly supplied catalog. + + If a catalog has translation contexts or sections, then ommitting it in the above calls looks up in section "". + + The default pluralization rule is n != 1, which is to say that passing n == 1 (or not passing n) returns the singular form. + Passing n != 1 returns plural form 1. + + Should a language not conform to this rule, you can pass a pluralizer procedure to the catalog parser. + This is a procedure that maps an integer to an integer, taking a value and returning which plural slot should be used. + + You can also assign it to a loaded catalog after parsing, of course. + + Some code examples follow. +*/ + +/* +```cpp +import "core:fmt" +import "core:text/i18n" + +T :: i18n.get + +mo :: proc() { + using fmt + + err: i18n.Error + + /* + Parse MO file and set it as the active translation so we can omit `get`'s "catalog" parameter. + */ + i18n.ACTIVE, err = i18n.parse_mo(#load("translations/nl_NL.mo")) + defer i18n.destroy() + + if err != .None { return } + + /* + These are in the .MO catalog. + */ + println("-----") + println(T("")) + println("-----") + println(T("There are 69,105 leaves here.")) + println("-----") + println(T("Hellope, World!")) + println("-----") + // We pass 1 into `T` to get the singular format string, then 1 again into printf. + printf(T("There is %d leaf.\n", 1), 1) + // We pass 42 into `T` to get the plural format string, then 42 again into printf. + printf(T("There is %d leaf.\n", 42), 42) + + /* + This isn't in the translation catalog, so the key is passed back untranslated. + */ + println("-----") + println(T("Come visit us on Discord!")) +} + +qt :: proc() { + using fmt + + err: i18n.Error + + /* + Parse QT file and set it as the active translation so we can omit `get`'s "catalog" parameter. + */ + i18n.ACTIVE, err = i18n.parse_qt(#load("translations/nl_NL-qt-ts.ts")) + defer i18n.destroy() + + if err != .None { + return + } + + /* + These are in the .TS catalog. As you can see they have sections. + */ + println("--- Page section ---") + println("Page:Text for translation =", T("Page", "Text for translation")) + println("-----") + println("Page:Also text to translate =", T("Page", "Also text to translate")) + println("-----") + println("--- installscript section ---") + println("installscript:99 bottles of beer on the wall =", T("installscript", "99 bottles of beer on the wall")) + println("-----") + println("--- apple_count section ---") + println("apple_count:%d apple(s) =") + println("\t 1 =", T("apple_count", "%d apple(s)", 1)) + println("\t 42 =", T("apple_count", "%d apple(s)", 42)) +} +``` +*/ \ No newline at end of file diff --git a/core/text/i18n/example/i18n_example.odin b/core/text/i18n/example/i18n_example.odin deleted file mode 100644 index 32eb38a7d..000000000 --- a/core/text/i18n/example/i18n_example.odin +++ /dev/null @@ -1,99 +0,0 @@ -package i18n_example - -import "core:mem" -import "core:fmt" -import "core:text/i18n" - -_T :: i18n.get - -mo :: proc() { - using fmt - - err: i18n.Error - - /* - Parse MO file and set it as the active translation so we can omit `get`'s "catalog" parameter. - */ - i18n.ACTIVE, err = i18n.parse_mo(#load("nl_NL.mo")) - defer i18n.destroy() - - if err != .None { return } - - /* - These are in the .MO catalog. - */ - println("-----") - println(_T("")) - println("-----") - println(_T("There are 69,105 leaves here.")) - println("-----") - println(_T("Hellope, World!")) - - /* - For ease of use, pluralized lookup can use both singular and plural form as key for the same translation. - This is a quirk of the GetText format which has separate keys for their different plurals. - */ - println("-----") - printf(_T("There is %d leaf.\n", 1), 1) - printf(_T("There is %d leaf.\n", 42), 42) - - printf(_T("There are %d leaves.\n", 1), 1) - printf(_T("There are %d leaves.\n", 42), 42) - - /* - This isn't. - */ - println("-----") - println(_T("Come visit us on Discord!")) -} - -qt :: proc() { - using fmt - - err: i18n.Error - - /* - Parse QT file and set it as the active translation so we can omit `get`'s "catalog" parameter. - */ - i18n.ACTIVE, err = i18n.parse_qt(#load("../../../../tests/core/assets/XML/nl_NL-qt-ts.ts")) - defer i18n.destroy() - - fmt.printf("parse_qt returned %v\n", err) - if err != .None { - return - } - - /* - These are in the .TS catalog. - */ - println("--- Page section ---") - println("Page:Text for translation =", _T("Page", "Text for translation")) - println("-----") - println("Page:Also text to translate =", _T("Page", "Also text to translate")) - println("-----") - println("--- installscript section ---") - println("installscript:99 bottles of beer on the wall =", _T("installscript", "99 bottles of beer on the wall")) - println("-----") - println("--- apple_count section ---") - println("apple_count:%d apple(s) =") - println("\t 1 =", _T("apple_count", "%d apple(s)", 1)) - println("\t 42 =", _T("apple_count", "%d apple(s)", 42)) -} - -main :: proc() { - using fmt - - track: mem.Tracking_Allocator - mem.tracking_allocator_init(&track, context.allocator) - context.allocator = mem.tracking_allocator(&track) - - // mo() - qt() - - if len(track.allocation_map) > 0 { - println() - for _, v in track.allocation_map { - printf("%v Leaked %v bytes.\n", v.location, v.size) - } - } -} \ No newline at end of file diff --git a/core/text/i18n/gettext.odin b/core/text/i18n/gettext.odin index 54c5a1111..eed73855b 100644 --- a/core/text/i18n/gettext.odin +++ b/core/text/i18n/gettext.odin @@ -8,6 +8,9 @@ package i18n A from-scratch implementation based after the specification found here: https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html + Options are ignored as they're not applicable to this format. + They're part of the signature for consistency with other catalog formats. + List of contributors: Jeroen van Rijn: Initial implementation. */ @@ -15,7 +18,7 @@ import "core:os" import "core:strings" import "core:bytes" -parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_mo_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator /* An MO file should have at least a 4-byte magic, 2 x 2 byte version info, @@ -115,7 +118,7 @@ parse_mo_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allo return } -parse_mo_file :: proc(filename: string, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_mo_file :: proc(filename: string, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator data, data_ok := os.read_entire_file(filename) @@ -123,7 +126,7 @@ parse_mo_file :: proc(filename: string, pluralizer: proc(int) -> int = nil, allo if !data_ok { return {}, .File_Error } - return parse_mo_from_slice(data, pluralizer) + return parse_mo_from_slice(data, options, pluralizer, allocator) } parse_mo :: proc { parse_mo_file, parse_mo_from_slice } diff --git a/core/text/i18n/i18n.odin b/core/text/i18n/i18n.odin index 36204efd9..e007401af 100644 --- a/core/text/i18n/i18n.odin +++ b/core/text/i18n/i18n.odin @@ -74,6 +74,14 @@ Error :: enum { } +Parse_Options :: struct { + merge_sections: bool, +} + +DEFAULT_PARSE_OPTIONS :: Parse_Options{ + merge_sections = false, +} + /* Several ways to use: - get(key), which defaults to the singular form and i18n.ACTIVE catalog, or diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin index 65d51444e..0a241c1aa 100644 --- a/core/text/i18n/qt_linguist.odin +++ b/core/text/i18n/qt_linguist.odin @@ -27,7 +27,7 @@ TS_XML_Options := xml.Options{ expected_doctype = "TS", } -parse_qt_linguist_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator ts, xml_err := xml.parse(data, TS_XML_Options) @@ -59,7 +59,7 @@ parse_qt_linguist_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = return translation, .TS_File_Expected_Context_Name, } - section_name := ts.elements[section_name_id].value + section_name := "" if options.merge_sections else ts.elements[section_name_id].value if section_name not_in translation.k_v { translation.k_v[section_name] = {} @@ -139,7 +139,7 @@ parse_qt_linguist_from_slice :: proc(data: []u8, pluralizer: proc(int) -> int = return } -parse_qt_linguist_file :: proc(filename: string, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_qt_linguist_file :: proc(filename: string, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator data, data_ok := os.read_entire_file(filename) @@ -147,7 +147,7 @@ parse_qt_linguist_file :: proc(filename: string, pluralizer: proc(int) -> int = if !data_ok { return {}, .File_Error } - return parse_qt_linguist_from_slice(data, pluralizer) + return parse_qt_linguist_from_slice(data, options, pluralizer, allocator) } parse_qt :: proc { parse_qt_linguist_file, parse_qt_linguist_from_slice } \ No newline at end of file diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 27f199062..36acf7714 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -56,6 +56,7 @@ import csv "core:encoding/csv" import hxa "core:encoding/hxa" import json "core:encoding/json" import varint "core:encoding/varint" +import xml "core:encoding/xml" import fmt "core:fmt" import hash "core:hash" @@ -100,6 +101,7 @@ import strings "core:strings" import sync "core:sync" import testing "core:testing" import scanner "core:text/scanner" +import i18n "core:text/i18n" import thread "core:thread" import time "core:time" @@ -158,6 +160,7 @@ _ :: csv _ :: hxa _ :: json _ :: varint +_ :: xml _ :: fmt _ :: hash _ :: image @@ -192,6 +195,7 @@ _ :: strings _ :: sync _ :: testing _ :: scanner +_ :: i18n _ :: thread _ :: time _ :: unicode diff --git a/tests/core/Makefile b/tests/core/Makefile index 2c24fef75..1405ae5c6 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -26,9 +26,10 @@ noise_test: $(ODIN) run math/noise -out:test_noise encoding_test: - $(ODIN) run encoding/hxa -collection:tests=.. -out:test_hxa - $(ODIN) run encoding/json -out:test_json + $(ODIN) run encoding/hxa -out:test_hxa -collection:tests=.. + $(ODIN) run encoding/json -out:test_json $(ODIN) run encoding/varint -out:test_varint + $(ODIN) run encoding/xml -out:test_xml math_test: $(ODIN) run math/test_core_math.odin -file -collection:tests=.. -out:test_core_math diff --git a/tests/core/assets/I18N/duplicate-key.ts b/tests/core/assets/I18N/duplicate-key.ts new file mode 100644 index 000000000..a38824d01 --- /dev/null +++ b/tests/core/assets/I18N/duplicate-key.ts @@ -0,0 +1,22 @@ + + + + + Page + + %d apple(s) + commenting + Tekst om te vertalen + + + + apple_count + + %d apple(s) + + %d appel + %d appels + + + + diff --git a/tests/core/build.bat b/tests/core/build.bat index 8e4ba1d15..77ff38038 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -64,4 +64,9 @@ echo --- echo --- echo Running core:reflect tests echo --- -%PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe \ No newline at end of file +%PATH_TO_ODIN% run reflect %COMMON% %COLLECTION% -out:test_core_reflect.exe + +echo --- +echo Running core:text/i18n tests +echo --- +%PATH_TO_ODIN% run text\i18n %COMMON% -out:test_core_i18n.exe \ No newline at end of file diff --git a/tests/core/text/i18n/test_core_text_i18n.odin b/tests/core/text/i18n/test_core_text_i18n.odin new file mode 100644 index 000000000..ba668c4fd --- /dev/null +++ b/tests/core/text/i18n/test_core_text_i18n.odin @@ -0,0 +1,165 @@ +package test_core_text_i18n + +import "core:mem" +import "core:fmt" +import "core:os" +import "core:testing" +import "core:text/i18n" + +TEST_count := 0 +TEST_fail := 0 + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} +T :: i18n.get + +Test :: struct { + section: string, + key: string, + val: string, + n: int, +} + +Test_Suite :: struct { + file: string, + loader: proc(string, i18n.Parse_Options, proc(int) -> int, mem.Allocator) -> (^i18n.Translation, i18n.Error), + err: i18n.Error, + options: i18n.Parse_Options, + tests: []Test, +} + +TESTS := []Test_Suite{ + { + file = "assets/I18N/nl_NL.mo", + loader = i18n.parse_mo_file, + tests = { + // These are in the catalog. + { "", "There are 69,105 leaves here.", "Er zijn hier 69.105 bladeren.", 1 }, + { "", "Hellope, World!", "Hallo, Wereld!", 1 }, + { "", "There is %d leaf.\n", "Er is %d blad.\n", 1 }, + { "", "There are %d leaves.\n", "Er is %d blad.\n", 1 }, + { "", "There is %d leaf.\n", "Er zijn %d bladeren.\n", 42 }, + { "", "There are %d leaves.\n", "Er zijn %d bladeren.\n", 42 }, + + // This isn't in the catalog, so should ruturn the key. + { "", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, + }, + }, + + // QT Linguist with default loader options. + { + file = "assets/I18N/nl_NL-qt-ts.ts", + loader = i18n.parse_qt_linguist_file, + tests = { + // These are in the catalog. + { "Page", "Text for translation", "Tekst om te vertalen", 1}, + { "Page", "Also text to translate", "Ook tekst om te vertalen", 1}, + { "installscript", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1}, + { "apple_count", "%d apple(s)", "%d appel", 1}, + { "apple_count", "%d apple(s)", "%d appels", 42}, + + // These aren't in the catalog, so should ruturn the key. + { "", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, + { "Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, + }, + }, + + // QT Linguist, merging sections. + { + file = "assets/I18N/nl_NL-qt-ts.ts", + loader = i18n.parse_qt_linguist_file, + options = {merge_sections = true}, + tests = { + // All of them are now in section "", lookup with original section should return the key. + { "", "Text for translation", "Tekst om te vertalen", 1}, + { "", "Also text to translate", "Ook tekst om te vertalen", 1}, + { "", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1}, + { "", "%d apple(s)", "%d appel", 1}, + { "", "%d apple(s)", "%d appels", 42}, + + // All of them are now in section "", lookup with original section should return the key. + { "Page", "Text for translation", "Text for translation", 1}, + { "Page", "Also text to translate", "Also text to translate", 1}, + { "installscript", "99 bottles of beer on the wall", "99 bottles of beer on the wall", 1}, + { "apple_count", "%d apple(s)", "%d apple(s)", 1}, + { "apple_count", "%d apple(s)", "%d apple(s)", 42}, + }, + }, + + // QT Linguist, merging sections. Expecting .Duplicate_Key error because same key exists in more than 1 section. + { + file = "assets/I18N/duplicate-key.ts", + loader = i18n.parse_qt_linguist_file, + options = {merge_sections = true}, + err = .Duplicate_Key, + }, + + // QT Linguist, not merging sections. Shouldn't return error despite same key existing in more than 1 section. + { + file = "assets/I18N/duplicate-key.ts", + loader = i18n.parse_qt_linguist_file, + }, +} + +@test +tests :: proc(t: ^testing.T) { + using fmt + + cat: ^i18n.Translation + err: i18n.Error + + for suite in TESTS { + cat, err = suite.loader(suite.file, suite.options, nil, context.allocator) + + msg := fmt.tprintf("Expected loading %v to return %v, got %v", suite.file, suite.err, err) + expect(t, err == suite.err, msg) + + if err == .None { + for test in suite.tests { + val := T(test.section, test.key, test.n, cat) + + msg = fmt.tprintf("Expected key `%v` from section `%v`'s form for value `%v` to equal `%v`, got `%v`", test.key, test.section, test.n, test.val, val) + expect(t, val == test.val, msg) + } + } + i18n.destroy(cat) + } +} + +main :: proc() { + using fmt + + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + t := testing.T{} + tests(&t) + + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } + + if len(track.allocation_map) > 0 { + println() + for _, v in track.allocation_map { + printf("%v Leaked %v bytes.\n", v.location, v.size) + } + } +} \ No newline at end of file From ff0f0c447fb52b5836edb603e1fb8c3ae4ed4b50 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 18:10:13 +0200 Subject: [PATCH 121/245] [i18n] Fix segfault on destroy on Linux Forgot to intern the section string in QT TS loader. --- core/text/i18n/i18n.odin | 26 ++++++++++++++----------- core/text/i18n/qt_linguist.odin | 5 ++++- tests/core/assets/I18N/duplicate-key.ts | 18 ++++++++--------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/core/text/i18n/i18n.odin b/core/text/i18n/i18n.odin index e007401af..9d030db16 100644 --- a/core/text/i18n/i18n.odin +++ b/core/text/i18n/i18n.odin @@ -163,16 +163,20 @@ get_by_slot :: proc{get_by_slot_single_section, get_by_slot_by_section} - destroy(), to clean up the currently active catalog catalog i18n.ACTIVE - destroy(catalog), to clean up a specific catalog. */ -destroy :: proc(catalog: ^Translation = ACTIVE) { - if catalog != nil { - strings.intern_destroy(&catalog.intern) - for section in &catalog.k_v { - for key in &catalog.k_v[section] { - delete(catalog.k_v[section][key]) - } - delete(catalog.k_v[section]) - } - delete(catalog.k_v) - free(catalog) +destroy :: proc(catalog: ^Translation = ACTIVE, allocator := context.allocator) { + context.allocator = allocator + + if catalog == nil { + return } + + for section in &catalog.k_v { + for key in &catalog.k_v[section] { + delete(catalog.k_v[section][key]) + } + delete(catalog.k_v[section]) + } + delete(catalog.k_v) + strings.intern_destroy(&catalog.intern) + free(catalog) } \ No newline at end of file diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin index 0a241c1aa..e23e9aef4 100644 --- a/core/text/i18n/qt_linguist.odin +++ b/core/text/i18n/qt_linguist.odin @@ -59,7 +59,10 @@ parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTION return translation, .TS_File_Expected_Context_Name, } - section_name := "" if options.merge_sections else ts.elements[section_name_id].value + section_name := strings.intern_get(&translation.intern, "") + if !options.merge_sections { + section_name = strings.intern_get(&translation.intern, ts.elements[section_name_id].value) + } if section_name not_in translation.k_v { translation.k_v[section_name] = {} diff --git a/tests/core/assets/I18N/duplicate-key.ts b/tests/core/assets/I18N/duplicate-key.ts index a38824d01..44c09d91d 100644 --- a/tests/core/assets/I18N/duplicate-key.ts +++ b/tests/core/assets/I18N/duplicate-key.ts @@ -10,13 +10,13 @@ - apple_count - - %d apple(s) - - %d appel - %d appels - - - + apple_count + + %d apple(s) + + %d appel + %d appels + + + From 36263399a0159d9ca3a109b50542638264e5642b Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 18:13:46 +0200 Subject: [PATCH 122/245] [i18n] Enable i18n test on Linux. --- tests/core/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/core/Makefile b/tests/core/Makefile index 1405ae5c6..5c2918e30 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -2,7 +2,7 @@ ODIN=../../odin PYTHON=$(shell which python3) all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ - math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test + math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test i18n_test download_test_assets: $(PYTHON) download_assets.py @@ -44,4 +44,7 @@ reflect_test: $(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect os_exit_test: - $(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0 \ No newline at end of file + $(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0 + +i18n_test: + $(ODIN) run text/i18n -out:test_core_i18n \ No newline at end of file From 819345caa6dccb983e496682a78829074f777011 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 18:28:42 +0200 Subject: [PATCH 123/245] Disable i18n test for *nix for now. --- tests/core/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/Makefile b/tests/core/Makefile index 5c2918e30..2e1e4f78d 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -2,7 +2,7 @@ ODIN=../../odin PYTHON=$(shell which python3) all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ - math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test i18n_test + math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test download_test_assets: $(PYTHON) download_assets.py From 9c9c2b483c93be2f6e78911d997229a4b543c66d Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 29 Apr 2022 18:41:21 +0200 Subject: [PATCH 124/245] [i18n] Enable *nix tests again. --- core/text/i18n/qt_linguist.odin | 18 +++++++++--------- tests/core/Makefile | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin index e23e9aef4..15a88a42f 100644 --- a/core/text/i18n/qt_linguist.odin +++ b/core/text/i18n/qt_linguist.odin @@ -92,15 +92,15 @@ parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTION return translation, .TS_File_Expected_Translation } - source := ts.elements[source_id] - xlat := ts.elements[translation_id] + source := strings.intern_get(&translation.intern, ts.elements[source_id].value) + xlat := strings.intern_get(&translation.intern, ts.elements[translation_id].value) - if source.value in section { + if source in section { return translation, .Duplicate_Key } if has_plurals { - if xlat.value != "" { + if xlat != "" { return translation, .TS_File_Expected_NumerusForm } @@ -116,7 +116,7 @@ parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTION if num_plurals < 2 { return translation, .TS_File_Expected_NumerusForm } - section[source.value] = make([]string, num_plurals) + section[source] = make([]string, num_plurals) num_plurals = 0 for { @@ -124,15 +124,15 @@ parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTION if !numerus_found { break } - numerus := ts.elements[numerus_id] - section[source.value][num_plurals] = strings.intern_get(&translation.intern, numerus.value) + numerus := strings.intern_get(&translation.intern, ts.elements[numerus_id].value) + section[source][num_plurals] = numerus num_plurals += 1 } } else { // Single translation - section[source.value] = make([]string, 1) - section[source.value][0] = strings.intern_get(&translation.intern, xlat.value) + section[source] = make([]string, 1) + section[source][0] = xlat } nth += 1 diff --git a/tests/core/Makefile b/tests/core/Makefile index 2e1e4f78d..5c2918e30 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -2,7 +2,7 @@ ODIN=../../odin PYTHON=$(shell which python3) all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ - math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test + math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test i18n_test download_test_assets: $(PYTHON) download_assets.py From 0ad448f1c71da7bc522012a894f02c9864e448d6 Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 30 Apr 2022 11:21:37 +0300 Subject: [PATCH 125/245] sys/windows: add a couple of procedures and types --- core/image/common.odin | 2 +- core/sys/windows/gdi32.odin | 5 +++++ core/sys/windows/types.odin | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/image/common.odin b/core/image/common.odin index 8c77ec48a..9955f0ee1 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -1131,4 +1131,4 @@ write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Er return compress.General_Error.Resize_Failed } return nil -} \ No newline at end of file +} diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index 15d5567c7..8c686f2dc 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -62,5 +62,10 @@ foreign gdi32 { ChoosePixelFormat :: proc(hdc: HDC, ppfd: ^PIXELFORMATDESCRIPTOR) -> c_int --- SwapBuffers :: proc(HDC) -> BOOL --- + SetDCBrushColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF --- PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL --- } + +RGB :: proc(r, g, b: u8) -> COLORREF { + return COLORREF(COLORREF(r) | COLORREF(g) << 8 | COLORREF(b) << 16) +} diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 6bded29e1..4093fd3f9 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -55,6 +55,8 @@ UINT_PTR :: uintptr ULONG :: c_ulong UCHAR :: BYTE NTSTATUS :: c.long +COLORREF :: DWORD +LPCOLORREF :: ^COLORREF LPARAM :: LONG_PTR WPARAM :: UINT_PTR LRESULT :: LONG_PTR From 40bea95fb0c1f561f2bb53c967c698823c8c951b Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 30 Apr 2022 12:41:04 +0300 Subject: [PATCH 126/245] sys/windows: add GetDCBrushColor --- core/sys/windows/gdi32.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index 8c686f2dc..eb863b586 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -63,6 +63,7 @@ foreign gdi32 { SwapBuffers :: proc(HDC) -> BOOL --- SetDCBrushColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF --- + GetDCBrushColor :: proc(hdc: HDC) -> COLORREF --- PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL --- } From 8c7f3fd1e6f9b04da2b01e25bd7a5dee6feeee28 Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 30 Apr 2022 13:34:11 +0300 Subject: [PATCH 127/245] sys/windows: change macro and add comment --- core/sys/windows/gdi32.odin | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index eb863b586..bec5225a7 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -67,6 +67,8 @@ foreign gdi32 { PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL --- } -RGB :: proc(r, g, b: u8) -> COLORREF { - return COLORREF(COLORREF(r) | COLORREF(g) << 8 | COLORREF(b) << 16) +// Windows colors are packed as ABGR +RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF { + res: [4]u8 = {0, rgb.b, rgb.g, rgb.r} + return transmute(COLORREF)res } From d2bac0c35e8f7c2347b6bd3763d64de6e902494b Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 30 Apr 2022 13:40:38 +0300 Subject: [PATCH 128/245] sys/windows: fix build issues --- core/sys/windows/gdi32.odin | 2 +- core/sys/windows/types.odin | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index bec5225a7..e728503d2 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -69,6 +69,6 @@ foreign gdi32 { // Windows colors are packed as ABGR RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF { - res: [4]u8 = {0, rgb.b, rgb.g, rgb.r} + res: [4]u8 = {0, b, g, r} return transmute(COLORREF)res } diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 4093fd3f9..c3e461ba0 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -55,7 +55,7 @@ UINT_PTR :: uintptr ULONG :: c_ulong UCHAR :: BYTE NTSTATUS :: c.long -COLORREF :: DWORD +COLORREF :: DWORD // Windows colors are packed as ABGR LPCOLORREF :: ^COLORREF LPARAM :: LONG_PTR WPARAM :: UINT_PTR From dd6337224f817044be01fd270e9d70ddbc0571a5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 11:42:28 +0100 Subject: [PATCH 129/245] Correct explicit atomic orderings --- core/sync/primitives_atomic.odin | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 665b515ba..a0f08c412 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -298,7 +298,7 @@ atomic_cond_wait :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex) { } atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duration: time.Duration) -> (ok: bool) { - state := u32(atomic_load(&c.state)) + state := u32(atomic_load_explicit(&c.state, .Relaxed)) unlock(m) ok = futex_wait_with_timeout(&c.state, state, duration) lock(m) @@ -307,12 +307,12 @@ atomic_cond_wait_with_timeout :: proc(c: ^Atomic_Cond, m: ^Atomic_Mutex, duratio atomic_cond_signal :: proc(c: ^Atomic_Cond) { - atomic_add_explicit(&c.state, 1, .Relaxed) + atomic_add_explicit(&c.state, 1, .Release) futex_signal(&c.state) } atomic_cond_broadcast :: proc(c: ^Atomic_Cond) { - atomic_add_explicit(&c.state, 1, .Relaxed) + atomic_add_explicit(&c.state, 1, .Release) futex_broadcast(&c.state) } @@ -351,7 +351,6 @@ atomic_sema_wait_with_timeout :: proc(s: ^Atomic_Sema, duration: time.Duration) return false } for { - original_count := atomic_load_explicit(&s.count, .Relaxed) for start := time.tick_now(); original_count == 0; /**/ { remaining := duration - time.tick_since(start) From d5886c1572c6b093079e3be9911d5aaad0e65a7d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 12:37:14 +0100 Subject: [PATCH 130/245] Remove the wait group based semaphore implementation It was a misuse of the data structure --- core/sync/extended.odin | 15 ++++-------- core/sync/primitives_internal.odin | 19 +++++++++++++++ core/sync/sema_internal.odin | 39 ------------------------------ 3 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 core/sync/sema_internal.odin diff --git a/core/sync/extended.odin b/core/sync/extended.odin index 2cca6f961..180d9b633 100644 --- a/core/sync/extended.odin +++ b/core/sync/extended.odin @@ -16,8 +16,7 @@ wait_group_add :: proc(wg: ^Wait_Group, delta: int) { return } - mutex_lock(&wg.mutex) - defer mutex_unlock(&wg.mutex) + guard(&wg.mutex) atomic_add(&wg.counter, delta) if wg.counter < 0 { @@ -36,8 +35,7 @@ wait_group_done :: proc(wg: ^Wait_Group) { } wait_group_wait :: proc(wg: ^Wait_Group) { - mutex_lock(&wg.mutex) - defer mutex_unlock(&wg.mutex) + guard(&wg.mutex) if wg.counter != 0 { cond_wait(&wg.cond, &wg.mutex) @@ -51,8 +49,7 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) - if duration <= 0 { return false } - mutex_lock(&wg.mutex) - defer mutex_unlock(&wg.mutex) + guard(&wg.mutex) if wg.counter != 0 { if !cond_wait_with_timeout(&wg.cond, &wg.mutex, duration) { @@ -119,8 +116,7 @@ barrier_init :: proc(b: ^Barrier, thread_count: int) { // Block the current thread until all threads have rendezvoused // Barrier can be reused after all threads rendezvoused once, and can be used continuously barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) { - mutex_lock(&b.mutex) - defer mutex_unlock(&b.mutex) + guard(&b.mutex) local_gen := b.generation_id b.index += 1 if b.index < b.thread_count { @@ -289,8 +285,7 @@ Once :: struct { once_do :: proc(o: ^Once, fn: proc()) { @(cold) do_slow :: proc(o: ^Once, fn: proc()) { - mutex_lock(&o.m) - defer mutex_unlock(&o.m) + guard(&o.m) if !o.done { fn() atomic_store_explicit(&o.done, true, .Release) diff --git a/core/sync/primitives_internal.odin b/core/sync/primitives_internal.odin index de9aca991..deacf632c 100644 --- a/core/sync/primitives_internal.odin +++ b/core/sync/primitives_internal.odin @@ -1,6 +1,25 @@ //+private package sync +import "core:time" + +_Sema :: struct { + atomic: Atomic_Sema, +} + +_sema_post :: proc(s: ^Sema, count := 1) { + atomic_sema_post(&s.impl.atomic, count) +} + +_sema_wait :: proc(s: ^Sema) { + atomic_sema_wait(&s.impl.atomic) +} + +_sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { + return atomic_sema_wait_with_timeout(&s.impl.atomic, duration) +} + + when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { _Recursive_Mutex :: struct { owner: Futex, diff --git a/core/sync/sema_internal.odin b/core/sync/sema_internal.odin deleted file mode 100644 index 5e2203c34..000000000 --- a/core/sync/sema_internal.odin +++ /dev/null @@ -1,39 +0,0 @@ -//+private -package sync - -import "core:time" - - -when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { - _Sema :: struct { - atomic: Atomic_Sema, - } - - _sema_post :: proc(s: ^Sema, count := 1) { - atomic_sema_post(&s.impl.atomic, count) - } - - _sema_wait :: proc(s: ^Sema) { - atomic_sema_wait(&s.impl.atomic) - } - - _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { - return atomic_sema_wait_with_timeout(&s.impl.atomic, duration) - } -} else { - _Sema :: struct { - wg: Wait_Group, - } - - _sema_post :: proc(s: ^Sema, count := 1) { - wait_group_add(&s.impl.wg, count) - } - - _sema_wait :: proc(s: ^Sema) { - wait_group_wait(&s.impl.wg) - } - - _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { - return wait_group_wait_with_timeout(&s.impl.wg, duration) - } -} \ No newline at end of file From 78a8da5fea73538fab2597a4691f87e63972535f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 12:37:39 +0100 Subject: [PATCH 131/245] Add `sync.Parker` --- core/sync/extended.odin | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/core/sync/extended.odin b/core/sync/extended.odin index 180d9b633..49d296c90 100644 --- a/core/sync/extended.odin +++ b/core/sync/extended.odin @@ -297,3 +297,59 @@ once_do :: proc(o: ^Once, fn: proc()) { do_slow(o, fn) } } + + + +// A Parker is an associated token which is initially not present: +// * The `park` procedure blocks the current thread unless or until the token +// is available, at which point the token is consumed. +// * The `park_with_timeout` procedures works the same as `park` but only +// blocks for the specified duration. +// * The `unpark` procedure automatically makes the token available if it +// was not already. +Parker :: struct { + state: Futex, +} + +// Blocks the current thread until the token is made available. +// +// Assumes this is only called by the thread that owns the Parker. +park :: proc(p: ^Parker) { + EMPTY :: 0 + NOTIFIED :: 1 + PARKED :: max(u32) + if atomic_sub_explicit(&p.state, 1, .Acquire) == NOTIFIED { + return + } + for { + futex_wait(&p.state, PARKED) + if _, ok := atomic_compare_exchange_strong_explicit(&p.state, NOTIFIED, EMPTY, .Acquire, .Acquire); ok { + return + } + } +} + +// Blocks the current thread until the token is made available, but only +// for a limited duration. +// +// Assumes this is only called by the thread that owns the Parker +park_with_timeout :: proc(p: ^Parker, duration: time.Duration) { + EMPTY :: 0 + NOTIFIED :: 1 + PARKED :: max(u32) + if atomic_sub_explicit(&p.state, 1, .Acquire) == NOTIFIED { + return + } + futex_wait_with_timeout(&p.state, PARKED, duration) + atomic_exchange_explicit(&p.state, EMPTY, .Acquire) +} + +// Automatically makes thee token available if it was not already. +unpark :: proc(p: ^Parker) { + EMPTY :: 0 + NOTIFIED :: 1 + PARKED :: max(Futex) + if atomic_exchange_explicit(&p.state, NOTIFIED, .Release) == PARKED { + futex_signal(&p.state) + } +} \ No newline at end of file From 4e39629a9a316817b20387b2dc7860f95ab110b4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 13:09:24 +0100 Subject: [PATCH 132/245] Unify implementation for *nix platforms --- core/sync/primitives_darwin.odin | 38 -------- core/sync/primitives_freebsd.odin | 36 ------- core/sync/primitives_internal.odin | 145 +++++++++++++---------------- core/sync/primitives_linux.odin | 37 -------- core/sync/primitives_openbsd.odin | 36 ------- 5 files changed, 67 insertions(+), 225 deletions(-) diff --git a/core/sync/primitives_darwin.odin b/core/sync/primitives_darwin.odin index 514f66f3e..521c8fe35 100644 --- a/core/sync/primitives_darwin.odin +++ b/core/sync/primitives_darwin.odin @@ -17,41 +17,3 @@ _current_thread_id :: proc "contextless" () -> int { pthread_threadid_np(nil, &tid) return int(tid) } - - - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_freebsd.odin b/core/sync/primitives_freebsd.odin index b88fca181..9fdabb7c9 100644 --- a/core/sync/primitives_freebsd.odin +++ b/core/sync/primitives_freebsd.odin @@ -8,39 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() } - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_internal.odin b/core/sync/primitives_internal.odin index deacf632c..ba17c2eb5 100644 --- a/core/sync/primitives_internal.odin +++ b/core/sync/primitives_internal.odin @@ -20,99 +20,89 @@ _sema_wait_with_timeout :: proc(s: ^Sema, duration: time.Duration) -> bool { } -when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { - _Recursive_Mutex :: struct { - owner: Futex, - recursion: i32, - } +_Recursive_Mutex :: struct { + owner: Futex, + recursion: i32, +} - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := Futex(current_thread_id()) - for { - prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) - switch prev_owner { - case 0, tid: - m.impl.recursion += 1 - // inside the lock - return - } - - futex_wait(&m.impl.owner, u32(prev_owner)) - } - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - m.impl.recursion -= 1 - if m.impl.recursion != 0 { - return - } - atomic_exchange_explicit(&m.impl.owner, 0, .Release) - - futex_signal(&m.impl.owner) - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := Futex(current_thread_id()) +_recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { + tid := Futex(current_thread_id()) + for { prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) switch prev_owner { case 0, tid: m.impl.recursion += 1 // inside the lock - return true + return } - return false - } -} else { - _Recursive_Mutex :: struct { - owner: int, - recursion: int, - mutex: Mutex, - } - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - if tid != m.impl.owner { - mutex_lock(&m.impl.mutex) - } - // inside the lock - m.impl.owner = tid + futex_wait(&m.impl.owner, u32(prev_owner)) + } +} + +_recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { + m.impl.recursion -= 1 + if m.impl.recursion != 0 { + return + } + atomic_exchange_explicit(&m.impl.owner, 0, .Release) + + futex_signal(&m.impl.owner) + // outside the lock + +} + +_recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { + tid := Futex(current_thread_id()) + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) + switch prev_owner { + case 0, tid: m.impl.recursion += 1 - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - assert(tid == m.impl.owner) - m.impl.recursion -= 1 - recursion := m.impl.recursion - if recursion == 0 { - m.impl.owner = 0 - } - if recursion == 0 { - mutex_unlock(&m.impl.mutex) - } - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := current_thread_id() - if m.impl.owner == tid { - return mutex_try_lock(&m.impl.mutex) - } - if !mutex_try_lock(&m.impl.mutex) { - return false - } // inside the lock - m.impl.owner = tid - m.impl.recursion += 1 return true } + return false } when ODIN_OS != .Windows { + _Mutex :: struct { + mutex: Atomic_Mutex, + } + + _mutex_lock :: proc(m: ^Mutex) { + atomic_mutex_lock(&m.impl.mutex) + } + + _mutex_unlock :: proc(m: ^Mutex) { + atomic_mutex_unlock(&m.impl.mutex) + } + + _mutex_try_lock :: proc(m: ^Mutex) -> bool { + return atomic_mutex_try_lock(&m.impl.mutex) + } + + _Cond :: struct { + cond: Atomic_Cond, + } + + _cond_wait :: proc(c: ^Cond, m: ^Mutex) { + atomic_cond_wait(&c.impl.cond, &m.impl.mutex) + } + + _cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { + return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) + } + + _cond_signal :: proc(c: ^Cond) { + atomic_cond_signal(&c.impl.cond) + } + + _cond_broadcast :: proc(c: ^Cond) { + atomic_cond_broadcast(&c.impl.cond) + } + + _RW_Mutex :: struct { mutex: Atomic_RW_Mutex, } @@ -140,5 +130,4 @@ when ODIN_OS != .Windows { _rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex) } - } \ No newline at end of file diff --git a/core/sync/primitives_linux.odin b/core/sync/primitives_linux.odin index 0a9f0cc33..4cc99bdf1 100644 --- a/core/sync/primitives_linux.odin +++ b/core/sync/primitives_linux.odin @@ -8,40 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return unix.sys_gettid() } - - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} diff --git a/core/sync/primitives_openbsd.odin b/core/sync/primitives_openbsd.odin index 7794016f8..fd56a4837 100644 --- a/core/sync/primitives_openbsd.odin +++ b/core/sync/primitives_openbsd.odin @@ -8,39 +8,3 @@ import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() } - -_Mutex :: struct { - mutex: Atomic_Mutex, -} - -_mutex_lock :: proc(m: ^Mutex) { - atomic_mutex_lock(&m.impl.mutex) -} - -_mutex_unlock :: proc(m: ^Mutex) { - atomic_mutex_unlock(&m.impl.mutex) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - return atomic_mutex_try_lock(&m.impl.mutex) -} - -_Cond :: struct { - cond: Atomic_Cond, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - atomic_cond_wait(&c.impl.cond, &m.impl.mutex) -} - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) -} - -_cond_signal :: proc(c: ^Cond) { - atomic_cond_signal(&c.impl.cond) -} - -_cond_broadcast :: proc(c: ^Cond) { - atomic_cond_broadcast(&c.impl.cond) -} From 2720f64c06da7e9aaf49b96e25230c8036055203 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Apr 2022 13:28:45 +0100 Subject: [PATCH 133/245] Remove unused imports --- core/sync/primitives_darwin.odin | 1 - core/sync/primitives_freebsd.odin | 1 - core/sync/primitives_linux.odin | 1 - core/sync/primitives_openbsd.odin | 1 - 4 files changed, 4 deletions(-) diff --git a/core/sync/primitives_darwin.odin b/core/sync/primitives_darwin.odin index 521c8fe35..726113ae7 100644 --- a/core/sync/primitives_darwin.odin +++ b/core/sync/primitives_darwin.odin @@ -3,7 +3,6 @@ package sync import "core:c" -import "core:time" import "core:intrinsics" foreign import pthread "System.framework" diff --git a/core/sync/primitives_freebsd.odin b/core/sync/primitives_freebsd.odin index 9fdabb7c9..e6219acf1 100644 --- a/core/sync/primitives_freebsd.odin +++ b/core/sync/primitives_freebsd.odin @@ -3,7 +3,6 @@ package sync import "core:os" -import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() diff --git a/core/sync/primitives_linux.odin b/core/sync/primitives_linux.odin index 4cc99bdf1..1e75891df 100644 --- a/core/sync/primitives_linux.odin +++ b/core/sync/primitives_linux.odin @@ -3,7 +3,6 @@ package sync import "core:sys/unix" -import "core:time" _current_thread_id :: proc "contextless" () -> int { return unix.sys_gettid() diff --git a/core/sync/primitives_openbsd.odin b/core/sync/primitives_openbsd.odin index fd56a4837..4072a14e8 100644 --- a/core/sync/primitives_openbsd.odin +++ b/core/sync/primitives_openbsd.odin @@ -3,7 +3,6 @@ package sync import "core:os" -import "core:time" _current_thread_id :: proc "contextless" () -> int { return os.current_thread_id() From d6a8216ce48eb9478f307ccf70e5295424bd78ed Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 14:34:07 +0200 Subject: [PATCH 134/245] [pbm] Normalize some errors, correct .depth --- core/image/common.odin | 41 +++++++++++------- core/image/netpbm/netpbm.odin | 61 +++++++++++---------------- core/image/png/png.odin | 16 +++---- core/image/qoi/qoi.odin | 12 +++--- core/image/tga/tga.odin | 5 +-- tests/core/image/test_core_image.odin | 12 +++--- 6 files changed, 70 insertions(+), 77 deletions(-) diff --git a/core/image/common.odin b/core/image/common.odin index 2196565bd..6722036ff 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -45,7 +45,7 @@ Image :: struct { width: int, height: int, channels: int, - depth: int, + depth: int, // Channel depth in bits, typically 8 or 16 pixels: bytes.Buffer, /* Some image loaders/writers can return/take an optional background color. @@ -141,13 +141,14 @@ Option :: enum { alpha_drop_if_present, // Unimplemented for QOI. Returns error. alpha_premultiply, // Unimplemented for QOI. Returns error. blend_background, // Ignored for non-PNG formats + // Unimplemented do_not_expand_grayscale, do_not_expand_indexed, do_not_expand_channels, // SAVE OPTIONS - qoi_all_channels_linear, // QOI, informative info. If not set, defaults to sRGB with linear alpha. + qoi_all_channels_linear, // QOI, informative only. If not set, defaults to sRGB with linear alpha. } Options :: distinct bit_set[Option] @@ -166,12 +167,29 @@ Error :: union #shared_nil { General_Image_Error :: enum { None = 0, + // File I/O + Unable_To_Read_File, + Unable_To_Write_File, + + // Invalid + Invalid_Signature, + Invalid_Input_Image, + Image_Dimensions_Too_Large, Invalid_Image_Dimensions, Invalid_Number_Of_Channels, - Image_Dimensions_Too_Large, Image_Does_Not_Adhere_to_Spec, - Invalid_Input_Image, + Invalid_Image_Depth, + Invalid_Bit_Depth, + Invalid_Color_Space, + + // More data than pixels to decode into, for example. + Corrupt, + + // Output buffer is the wrong size Invalid_Output, + + // Allocation + Unable_To_Allocate_Or_Resize, } /* @@ -201,8 +219,6 @@ Netpbm_Error :: enum { None = 0, // reading - File_Not_Readable, - Invalid_Signature, Invalid_Header_Token_Character, Incomplete_Header, Invalid_Header_Value, @@ -212,9 +228,7 @@ Netpbm_Error :: enum { Invalid_Buffer_Value, // writing - File_Not_Writable, Invalid_Format, - Invalid_Image_Depth, } /* @@ -222,7 +236,6 @@ Netpbm_Error :: enum { */ PNG_Error :: enum { None = 0, - Invalid_PNG_Signature, IHDR_Not_First_Chunk, IHDR_Corrupt, IDAT_Missing, @@ -338,14 +351,10 @@ PNG_Interlace_Method :: enum u8 { */ QOI_Error :: enum { None = 0, - Invalid_QOI_Signature, - Invalid_Bit_Depth, // QOI supports only 8-bit images, error only returned from writer. - Invalid_Color_Space, // QOI allows 0 = sRGB or 1 = linear. - Corrupt, // More data than pixels to decode into, for example. Missing_Or_Corrupt_Trailer, // Image seemed to have decoded okay, but trailer is missing or corrupt. } -QOI_Magic :: u32be(0x716f6966) // "qoif" +QOI_Magic :: u32be(0x716f6966) // "qoif" QOI_Color_Space :: enum u8 { sRGB = 0, @@ -1170,10 +1179,10 @@ write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Er return nil } else if len(data) == 1 { if bytes.buffer_write_byte(buf, data[0]) != nil { - return compress.General_Error.Resize_Failed + return .Resize_Failed } } else if n, _ := bytes.buffer_write(buf, data); n != len(data) { - return compress.General_Error.Resize_Failed + return .Resize_Failed } return nil } \ No newline at end of file diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 5c082e384..54935d6c6 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -9,8 +9,6 @@ import "core:strconv" import "core:strings" import "core:unicode" - - Image :: image.Image Format :: image.Netpbm_Format Header :: image.Netpbm_Header @@ -18,8 +16,6 @@ Info :: image.Netpbm_Info Error :: image.Error Format_Error :: image.Netpbm_Error - - Formats :: bit_set[Format] PBM :: Formats{.P1, .P4} PGM :: Formats{.P2, .P5} @@ -30,14 +26,12 @@ PFM :: Formats{.Pf, .PF} ASCII :: Formats{.P1, .P2, .P3} BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM - - -read :: proc { - read_from_file, - read_from_buffer, +load :: proc { + load_from_file, + load_from_buffer, } -read_from_file :: proc(filename: string, allocator := context.allocator) -> (img: Image, err: Error) { +load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: Image, err: Error) { context.allocator = allocator data, ok := os.read_entire_file(filename); defer delete(data) @@ -49,7 +43,7 @@ read_from_file :: proc(filename: string, allocator := context.allocator) -> (img return read_from_buffer(data) } -read_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { +load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { context.allocator = allocator header: Header; defer header_destroy(&header) @@ -70,14 +64,12 @@ read_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: return } - - -write :: proc { - write_to_file, - write_to_buffer, +save :: proc { + save_to_file, + save_to_buffer, } -write_to_file :: proc(filename: string, img: Image, allocator := context.allocator) -> (err: Error) { +save_to_file :: proc(filename: string, img: Image, allocator := context.allocator) -> (err: Error) { context.allocator = allocator data: []byte; defer delete(data) @@ -90,7 +82,7 @@ write_to_file :: proc(filename: string, img: Image, allocator := context.allocat return Format_Error.None } -write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: []byte, err: Error) { +save_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: []byte, err: Error) { context.allocator = allocator info, ok := img.metadata.(^image.Netpbm_Info) @@ -109,12 +101,12 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: } if header.format in (PNM + PAM) { - if header.maxval <= int(max(u8)) && img.depth != 1 \ - || header.maxval > int(max(u8)) && header.maxval <= int(max(u16)) && img.depth != 2 { + if header.maxval <= int(max(u8)) && img.depth != 8 \ + || header.maxval > int(max(u8)) && header.maxval <= int(max(u16)) && img.depth != 16 { err = Format_Error.Invalid_Image_Depth return } - } else if header.format in PFM && img.depth != 4 { + } else if header.format in PFM && img.depth != 32 { err = Format_Error.Invalid_Image_Depth return } @@ -179,7 +171,7 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: mem.copy(raw_data(data.buf[len(header_buf):]), raw_data(pixels), len(pixels)) // convert from native endianness - if img.depth == 2 { + if img.depth == 16 { pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):]) for p in &pixels { p = u16be(transmute(u16) p) @@ -212,7 +204,7 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: // Token ASCII case .P2, .P3: switch img.depth { - case 1: + case 8: pixels := img.pixels.buf[:] for y in 0 ..< img.height { for x in 0 ..< img.width { @@ -226,7 +218,7 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: fmt.sbprint(&data, "\n") } - case 2: + case 16: pixels := mem.slice_data_cast([]u16, img.pixels.buf[:]) for y in 0 ..< img.height { for x in 0 ..< img.width { @@ -251,8 +243,6 @@ write_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: return data.buf[:], Format_Error.None } - - parse_header :: proc(data: []byte, allocator := context.allocator) -> (header: Header, length: int, err: Error) { context.allocator = allocator @@ -351,7 +341,7 @@ _parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Er // set extra info header.channels = 3 if header.format in PPM else 1 - header.depth = 2 if header.maxval > int(max(u8)) else 1 + header.depth = 16 if header.maxval > int(max(u8)) else 8 // limit checking if current_field < len(header_fields) { @@ -448,12 +438,11 @@ _parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (head } // extra info - header.depth = 2 if header.maxval > int(max(u8)) else 1 + header.depth = 16 if header.maxval > int(max(u8)) else 8 // limit checking if header.width < 1 \ || header.height < 1 \ - || header.depth < 1 \ || header.maxval < 1 \ || header.maxval > int(max(u16)) { err = Format_Error.Invalid_Header_Value @@ -484,7 +473,7 @@ _parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Er } // floating point - header.depth = 4 + header.depth = 32 // width field, ok = strings.fields_iterator(&field_iterator) @@ -542,8 +531,6 @@ _parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Er return } - - decode_image :: proc(header: Header, data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { context.allocator = allocator @@ -554,7 +541,7 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato depth = header.depth, } - buffer_size := img.width * img.height * img.channels * img.depth + buffer_size := image.compute_buffer_size(img.width, img.height, img.channels, img.depth) // we can check data size for binary formats if header.format in BINARY { @@ -615,7 +602,7 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato } } } else { - if img.depth == 2 { + if img.depth == 16 { pixels := mem.slice_data_cast([]u16, img.pixels.buf[:]) for p in &pixels { p = u16(transmute(u16be) p) @@ -658,9 +645,9 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato } switch img.depth { - case 1: + case 8: bytes.buffer_write_byte(&img.pixels, u8(value)) - case 2: + case 16: vb := transmute([2]u8) u16(value) bytes.buffer_write(&img.pixels, vb[:]) } @@ -678,4 +665,4 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato err = Format_Error.None return -} +} \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index ba888cb78..d526dfb27 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -238,7 +238,7 @@ append_chunk :: proc(list: ^[dynamic]image.PNG_Chunk, src: image.PNG_Chunk, allo append(list, c) if len(list) != length + 1 { // Resize during append failed. - return mem.Allocator_Error.Out_Of_Memory + return .Unable_To_Allocate_Or_Resize } return @@ -347,7 +347,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont return load_from_slice(data, options) } else { img = new(Image) - return img, compress.General_Error.File_Not_Found + return img, .Unable_To_Read_File } } @@ -381,7 +381,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a signature, io_error := compress.read_data(ctx, Signature) if io_error != .None || signature != .PNG { - return img, .Invalid_PNG_Signature + return img, .Invalid_Signature } idat: []u8 @@ -747,7 +747,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8) t := bytes.Buffer{} if !resize(&t.buf, dest_raw_size) { - return {}, mem.Allocator_Error.Out_Of_Memory + return {}, .Unable_To_Allocate_Or_Resize } i := 0; j := 0 @@ -828,7 +828,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16) t := bytes.Buffer{} if !resize(&t.buf, dest_raw_size) { - return {}, mem.Allocator_Error.Out_Of_Memory + return {}, .Unable_To_Allocate_Or_Resize } p16 := mem.slice_data_cast([]u16, temp.buf[:]) @@ -1027,7 +1027,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8) t := bytes.Buffer{} if !resize(&t.buf, dest_raw_size) { - return {}, mem.Allocator_Error.Out_Of_Memory + return {}, .Unable_To_Allocate_Or_Resize } p := mem.slice_data_cast([]u8, temp.buf[:]) @@ -1535,7 +1535,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8) if !resize(&img.pixels.buf, num_bytes) { - return mem.Allocator_Error.Out_Of_Memory + return .Unable_To_Allocate_Or_Resize } filter_ok: bool @@ -1577,7 +1577,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH temp: bytes.Buffer temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8) if !resize(&temp.buf, temp_len) { - return mem.Allocator_Error.Out_Of_Memory + return .Unable_To_Allocate_Or_Resize } params := Filter_Params{ diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index fdbaab686..83b212be8 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -12,14 +12,12 @@ // The QOI specification is at https://qoiformat.org. package qoi -import "core:mem" import "core:image" import "core:compress" import "core:bytes" import "core:os" Error :: image.Error -General :: compress.General_Error Image :: image.Image Options :: image.Options @@ -57,7 +55,7 @@ save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be) if !resize(&output.buf, max_size) { - return General.Resize_Failed + return .Unable_To_Allocate_Or_Resize } header := image.QOI_Header{ @@ -177,7 +175,7 @@ save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocato save_to_memory(out, img, options) or_return write_ok := os.write_entire_file(output, out.buf[:]) - return nil if write_ok else General.Cannot_Open_File + return nil if write_ok else .Unable_To_Write_File } save :: proc{save_to_memory, save_to_file} @@ -201,7 +199,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont return load_from_slice(data, options) } else { img = new(Image) - return img, compress.General_Error.File_Not_Found + return img, .Unable_To_Read_File } } @@ -221,7 +219,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a header := image.read_data(ctx, image.QOI_Header) or_return if header.magic != image.QOI_Magic { - return img, .Invalid_QOI_Signature + return img, .Invalid_Signature } if img == nil { @@ -264,7 +262,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) if !resize(&img.pixels.buf, bytes_needed) { - return img, mem.Allocator_Error.Out_Of_Memory + return img, .Unable_To_Allocate_Or_Resize } /* diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 3c860cb62..0539706b3 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -17,7 +17,6 @@ import "core:bytes" import "core:os" Error :: image.Error -General :: compress.General_Error Image :: image.Image Options :: image.Options @@ -55,7 +54,7 @@ save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} necessary := pixels * img.channels + size_of(image.TGA_Header) if !resize(&output.buf, necessary) { - return General.Resize_Failed + return .Unable_To_Allocate_Or_Resize } header := image.TGA_Header{ @@ -97,7 +96,7 @@ save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocato save_to_memory(out, img, options) or_return write_ok := os.write_entire_file(output, out.buf[:]) - return nil if write_ok else General.Cannot_Open_File + return nil if write_ok else .Unable_To_Write_File } save :: proc{save_to_memory, save_to_file} \ No newline at end of file diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 0c11ca5ae..c328757e4 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1199,37 +1199,37 @@ Corrupt_PNG_Tests := []PNG_Test{ { "xs1n0g01", // signature byte 1 MSBit reset to zero { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { "xs2n0g01", // signature byte 2 is a 'Q' { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { "xs4n0g01", // signature byte 4 lowercase { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { "xs7n0g01", // 7th byte a space instead of control-Z { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { "xcrn0g04", // added cr bytes { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { "xlfn0g04", // added lf bytes { - {Default, .Invalid_PNG_Signature, {}, 0x_0000_0000}, + {Default, .Invalid_Signature, {}, 0x_0000_0000}, }, }, { From 3978e7e1cac9305698e9270fec02d7cd9557cf35 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 14:43:58 +0200 Subject: [PATCH 135/245] [xml] Add `parse_from_string` overload. `parse` now takes either a `[]u8` slice or a string. `load_from_file` takes a path string. --- core/encoding/xml/xml_reader.odin | 13 ++++++++++--- tests/core/encoding/xml/test_core_xml.odin | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 6d0d4e1aa..151d44e2a 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -493,7 +493,16 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err return doc, .None } -parse_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { +parse_from_string :: proc(data: string, options := DEFAULT_Options, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { + _data := transmute([]u8)data + + return parse_from_slice(_data, options, path, error_handler, allocator) +} + +parse :: proc { parse_from_string, parse_from_slice } + +// Load an XML file +load_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { context.allocator = allocator options := options @@ -505,8 +514,6 @@ parse_from_file :: proc(filename: string, options := DEFAULT_Options, error_hand return parse_from_slice(data, options, filename, error_handler, allocator) } -parse :: proc { parse_from_file, parse_from_slice } - destroy :: proc(doc: ^Document) { if doc == nil { return } diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index 07cbc1779..c8b02b635 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -295,7 +295,7 @@ run_tests :: proc(t: ^testing.T) { path := test_file_path(test.filename) log(t, fmt.tprintf("Trying to parse %v", path)) - doc, err := xml.parse(path, test.options, Silent) + doc, err := xml.load_from_file(path, test.options, Silent) defer xml.destroy(doc) tree_string := doc_to_string(doc) From d24bebdb9eb6a0a1e733fc2b325bc3472c648af9 Mon Sep 17 00:00:00 2001 From: hikari Date: Sat, 30 Apr 2022 16:55:26 +0300 Subject: [PATCH 136/245] sys/windows: add a couple procedures and tons of constants --- core/sys/windows/system_params.odin | 271 ++++++++++++++++++++++++++++ core/sys/windows/user32.odin | 4 + 2 files changed, 275 insertions(+) create mode 100644 core/sys/windows/system_params.odin diff --git a/core/sys/windows/system_params.odin b/core/sys/windows/system_params.odin new file mode 100644 index 000000000..e94d777bf --- /dev/null +++ b/core/sys/windows/system_params.odin @@ -0,0 +1,271 @@ +// +build windows +package sys_windows + +// Parameter for SystemParametersInfo. +SPI_GETBEEP :: 0x0001 +SPI_SETBEEP :: 0x0002 +SPI_GETMOUSE :: 0x0003 +SPI_SETMOUSE :: 0x0004 +SPI_GETBORDER :: 0x0005 +SPI_SETBORDER :: 0x0006 +SPI_GETKEYBOARDSPEED :: 0x000A +SPI_SETKEYBOARDSPEED :: 0x000B +SPI_LANGDRIVER :: 0x000C +SPI_ICONHORIZONTALSPACING :: 0x000D +SPI_GETSCREENSAVETIMEOUT :: 0x000E +SPI_SETSCREENSAVETIMEOUT :: 0x000F +SPI_GETSCREENSAVEACTIVE :: 0x0010 +SPI_SETSCREENSAVEACTIVE :: 0x0011 +SPI_GETGRIDGRANULARITY :: 0x0012 +SPI_SETGRIDGRANULARITY :: 0x0013 +SPI_SETDESKWALLPAPER :: 0x0014 +SPI_SETDESKPATTERN :: 0x0015 +SPI_GETKEYBOARDDELAY :: 0x0016 +SPI_SETKEYBOARDDELAY :: 0x0017 +SPI_ICONVERTICALSPACING :: 0x0018 +SPI_GETICONTITLEWRAP :: 0x0019 +SPI_SETICONTITLEWRAP :: 0x001A +SPI_GETMENUDROPALIGNMENT :: 0x001B +SPI_SETMENUDROPALIGNMENT :: 0x001C +SPI_SETDOUBLECLKWIDTH :: 0x001D +SPI_SETDOUBLECLKHEIGHT :: 0x001E +SPI_GETICONTITLELOGFONT :: 0x001F +SPI_SETDOUBLECLICKTIME :: 0x0020 +SPI_SETMOUSEBUTTONSWAP :: 0x0021 +SPI_SETICONTITLELOGFONT :: 0x0022 +SPI_GETFASTTASKSWITCH :: 0x0023 +SPI_SETFASTTASKSWITCH :: 0x0024 + +SPI_SETDRAGFULLWINDOWS :: 0x0025 +SPI_GETDRAGFULLWINDOWS :: 0x0026 +SPI_GETNONCLIENTMETRICS :: 0x0029 +SPI_SETNONCLIENTMETRICS :: 0x002A +SPI_GETMINIMIZEDMETRICS :: 0x002B +SPI_SETMINIMIZEDMETRICS :: 0x002C +SPI_GETICONMETRICS :: 0x002D +SPI_SETICONMETRICS :: 0x002E +SPI_SETWORKAREA :: 0x002F +SPI_GETWORKAREA :: 0x0030 +SPI_SETPENWINDOWS :: 0x0031 +SPI_GETHIGHCONTRAST :: 0x0042 +SPI_SETHIGHCONTRAST :: 0x0043 +SPI_GETKEYBOARDPREF :: 0x0044 +SPI_SETKEYBOARDPREF :: 0x0045 +SPI_GETSCREENREADER :: 0x0046 +SPI_SETSCREENREADER :: 0x0047 +SPI_GETANIMATION :: 0x0048 +SPI_SETANIMATION :: 0x0049 +SPI_GETFONTSMOOTHING :: 0x004A +SPI_SETFONTSMOOTHING :: 0x004B +SPI_SETDRAGWIDTH :: 0x004C +SPI_SETDRAGHEIGHT :: 0x004D +SPI_SETHANDHELD :: 0x004E +SPI_GETLOWPOWERTIMEOUT :: 0x004F +SPI_GETPOWEROFFTIMEOUT :: 0x0050 +SPI_SETLOWPOWERTIMEOUT :: 0x0051 +SPI_SETPOWEROFFTIMEOUT :: 0x0052 +SPI_GETLOWPOWERACTIVE :: 0x0053 +SPI_GETPOWEROFFACTIVE :: 0x0054 +SPI_SETLOWPOWERACTIVE :: 0x0055 +SPI_SETPOWEROFFACTIVE :: 0x0056 +SPI_SETCURSORS :: 0x0057 +SPI_SETICONS :: 0x0058 +SPI_GETDEFAULTINPUTLANG :: 0x0059 +SPI_SETDEFAULTINPUTLANG :: 0x005A +SPI_SETLANGTOGGLE :: 0x005B +SPI_GETWINDOWSEXTENSION :: 0x005C +SPI_SETMOUSETRAILS :: 0x005D +SPI_GETMOUSETRAILS :: 0x005E +SPI_SETSCREENSAVERRUNNING :: 0x0061 + +SPI_SCREENSAVERRUNNING :: SPI_SETSCREENSAVERRUNNING +SPI_GETFILTERKEYS :: 0x0032 +SPI_SETFILTERKEYS :: 0x0033 +SPI_GETTOGGLEKEYS :: 0x0034 +SPI_SETTOGGLEKEYS :: 0x0035 +SPI_GETMOUSEKEYS :: 0x0036 +SPI_SETMOUSEKEYS :: 0x0037 +SPI_GETSHOWSOUNDS :: 0x0038 +SPI_SETSHOWSOUNDS :: 0x0039 +SPI_GETSTICKYKEYS :: 0x003A +SPI_SETSTICKYKEYS :: 0x003B +SPI_GETACCESSTIMEOUT :: 0x003C +SPI_SETACCESSTIMEOUT :: 0x003D +SPI_GETSERIALKEYS :: 0x003E +SPI_SETSERIALKEYS :: 0x003F +SPI_GETSOUNDSENTRY :: 0x0040 +SPI_SETSOUNDSENTRY :: 0x0041 +SPI_GETSNAPTODEFBUTTON :: 0x005F +SPI_SETSNAPTODEFBUTTON :: 0x0060 +SPI_GETMOUSEHOVERWIDTH :: 0x0062 +SPI_SETMOUSEHOVERWIDTH :: 0x0063 +SPI_GETMOUSEHOVERHEIGHT :: 0x0064 +SPI_SETMOUSEHOVERHEIGHT :: 0x0065 +SPI_GETMOUSEHOVERTIME :: 0x0066 +SPI_SETMOUSEHOVERTIME :: 0x0067 +SPI_GETWHEELSCROLLLINES :: 0x0068 +SPI_SETWHEELSCROLLLINES :: 0x0069 +SPI_GETMENUSHOWDELAY :: 0x006A +SPI_SETMENUSHOWDELAY :: 0x006B + +SPI_GETWHEELSCROLLCHARS :: 0x006C +SPI_SETWHEELSCROLLCHARS :: 0x006D +SPI_GETSHOWIMEUI :: 0x006E +SPI_SETSHOWIMEUI :: 0x006F +SPI_GETMOUSESPEED :: 0x0070 +SPI_SETMOUSESPEED :: 0x0071 +SPI_GETSCREENSAVERRUNNING :: 0x0072 +SPI_GETDESKWALLPAPER :: 0x0073 +SPI_GETAUDIODESCRIPTION :: 0x0074 +SPI_SETAUDIODESCRIPTION :: 0x0075 +SPI_GETSCREENSAVESECURE :: 0x0076 +SPI_SETSCREENSAVESECURE :: 0x0077 + +SPI_GETHUNGAPPTIMEOUT :: 0x0078 +SPI_SETHUNGAPPTIMEOUT :: 0x0079 +SPI_GETWAITTOKILLTIMEOUT :: 0x007A +SPI_SETWAITTOKILLTIMEOUT :: 0x007B +SPI_GETWAITTOKILLSERVICETIMEOUT :: 0x007C +SPI_SETWAITTOKILLSERVICETIMEOUT :: 0x007D +SPI_GETMOUSEDOCKTHRESHOLD :: 0x007E +SPI_SETMOUSEDOCKTHRESHOLD :: 0x007F +SPI_GETPENDOCKTHRESHOLD :: 0x0080 +SPI_SETPENDOCKTHRESHOLD :: 0x0081 +SPI_GETWINARRANGING :: 0x0082 +SPI_SETWINARRANGING :: 0x0083 +SPI_GETMOUSEDRAGOUTTHRESHOLD :: 0x0084 +SPI_SETMOUSEDRAGOUTTHRESHOLD :: 0x0085 +SPI_GETPENDRAGOUTTHRESHOLD :: 0x0086 +SPI_SETPENDRAGOUTTHRESHOLD :: 0x0087 +SPI_GETMOUSESIDEMOVETHRESHOLD :: 0x0088 +SPI_SETMOUSESIDEMOVETHRESHOLD :: 0x0089 +SPI_GETPENSIDEMOVETHRESHOLD :: 0x008A +SPI_SETPENSIDEMOVETHRESHOLD :: 0x008B +SPI_GETDRAGFROMMAXIMIZE :: 0x008C +SPI_SETDRAGFROMMAXIMIZE :: 0x008D +SPI_GETSNAPSIZING :: 0x008E +SPI_SETSNAPSIZING :: 0x008F +SPI_GETDOCKMOVING :: 0x0090 +SPI_SETDOCKMOVING :: 0x0091 + +SPI_GETACTIVEWINDOWTRACKING :: 0x1000 +SPI_SETACTIVEWINDOWTRACKING :: 0x1001 +SPI_GETMENUANIMATION :: 0x1002 +SPI_SETMENUANIMATION :: 0x1003 +SPI_GETCOMBOBOXANIMATION :: 0x1004 +SPI_SETCOMBOBOXANIMATION :: 0x1005 +SPI_GETLISTBOXSMOOTHSCROLLING :: 0x1006 +SPI_SETLISTBOXSMOOTHSCROLLING :: 0x1007 +SPI_GETGRADIENTCAPTIONS :: 0x1008 +SPI_SETGRADIENTCAPTIONS :: 0x1009 +SPI_GETKEYBOARDCUES :: 0x100A +SPI_SETKEYBOARDCUES :: 0x100B +SPI_GETMENUUNDERLINES :: SPI_GETKEYBOARDCUES +SPI_SETMENUUNDERLINES :: SPI_SETKEYBOARDCUES +SPI_GETACTIVEWNDTRKZORDER :: 0x100C +SPI_SETACTIVEWNDTRKZORDER :: 0x100D +SPI_GETHOTTRACKING :: 0x100E +SPI_SETHOTTRACKING :: 0x100F +SPI_GETMENUFADE :: 0x1012 +SPI_SETMENUFADE :: 0x1013 +SPI_GETSELECTIONFADE :: 0x1014 +SPI_SETSELECTIONFADE :: 0x1015 +SPI_GETTOOLTIPANIMATION :: 0x1016 +SPI_SETTOOLTIPANIMATION :: 0x1017 +SPI_GETTOOLTIPFADE :: 0x1018 +SPI_SETTOOLTIPFADE :: 0x1019 +SPI_GETCURSORSHADOW :: 0x101A +SPI_SETCURSORSHADOW :: 0x101B +SPI_GETMOUSESONAR :: 0x101C +SPI_SETMOUSESONAR :: 0x101D +SPI_GETMOUSECLICKLOCK :: 0x101E +SPI_SETMOUSECLICKLOCK :: 0x101F +SPI_GETMOUSEVANISH :: 0x1020 +SPI_SETMOUSEVANISH :: 0x1021 +SPI_GETFLATMENU :: 0x1022 +SPI_SETFLATMENU :: 0x1023 +SPI_GETDROPSHADOW :: 0x1024 +SPI_SETDROPSHADOW :: 0x1025 +SPI_GETBLOCKSENDINPUTRESETS :: 0x1026 +SPI_SETBLOCKSENDINPUTRESETS :: 0x1027 +SPI_GETUIEFFECTS :: 0x103E +SPI_SETUIEFFECTS :: 0x103F +SPI_GETDISABLEOVERLAPPEDCONTENT :: 0x1040 +SPI_SETDISABLEOVERLAPPEDCONTENT :: 0x1041 +SPI_GETCLIENTAREAANIMATION :: 0x1042 +SPI_SETCLIENTAREAANIMATION :: 0x1043 +SPI_GETCLEARTYPE :: 0x1048 +SPI_SETCLEARTYPE :: 0x1049 +SPI_GETSPEECHRECOGNITION :: 0x104A +SPI_SETSPEECHRECOGNITION :: 0x104B +SPI_GETCARETBROWSING :: 0x104C +SPI_SETCARETBROWSING :: 0x104D +SPI_GETTHREADLOCALINPUTSETTINGS :: 0x104E +SPI_SETTHREADLOCALINPUTSETTINGS :: 0x104F +SPI_GETSYSTEMLANGUAGEBAR :: 0x1050 +SPI_SETSYSTEMLANGUAGEBAR :: 0x1051 +SPI_GETFOREGROUNDLOCKTIMEOUT :: 0x2000 +SPI_SETFOREGROUNDLOCKTIMEOUT :: 0x2001 +SPI_GETACTIVEWNDTRKTIMEOUT :: 0x2002 +SPI_SETACTIVEWNDTRKTIMEOUT :: 0x2003 +SPI_GETFOREGROUNDFLASHCOUNT :: 0x2004 +SPI_SETFOREGROUNDFLASHCOUNT :: 0x2005 +SPI_GETCARETWIDTH :: 0x2006 +SPI_SETCARETWIDTH :: 0x2007 +SPI_GETMOUSECLICKLOCKTIME :: 0x2008 +SPI_SETMOUSECLICKLOCKTIME :: 0x2009 +SPI_GETFONTSMOOTHINGTYPE :: 0x200A +SPI_SETFONTSMOOTHINGTYPE :: 0x200B +// constants for SPI_GETFONTSMOOTHINGTYPE and SPI_SETFONTSMOOTHINGTYPE: +FE_FONTSMOOTHINGSTANDARD :: 0x0001 +FE_FONTSMOOTHINGCLEARTYPE :: 0x0002 + +SPI_GETFONTSMOOTHINGCONTRAST :: 0x200C +SPI_SETFONTSMOOTHINGCONTRAST :: 0x200D + +SPI_GETFOCUSBORDERWIDTH :: 0x200E +SPI_SETFOCUSBORDERWIDTH :: 0x200F +SPI_GETFOCUSBORDERHEIGHT :: 0x2010 +SPI_SETFOCUSBORDERHEIGHT :: 0x2011 + +SPI_GETFONTSMOOTHINGORIENTATION :: 0x2012 +SPI_SETFONTSMOOTHINGORIENTATION :: 0x2013 + +// constants for SPI_GETFONTSMOOTHINGORIENTATION and SPI_SETFONTSMOOTHINGORIENTATION: +FE_FONTSMOOTHINGORIENTATIONBGR :: 0x0000 +FE_FONTSMOOTHINGORIENTATIONRGB :: 0x0001 + +SPI_GETMINIMUMHITRADIUS :: 0x2014 +SPI_SETMINIMUMHITRADIUS :: 0x2015 +SPI_GETMESSAGEDURATION :: 0x2016 +SPI_SETMESSAGEDURATION :: 0x2017 + +SPI_GETCONTACTVISUALIZATION :: 0x2018 +SPI_SETCONTACTVISUALIZATION :: 0x2019 +// constants for SPI_GETCONTACTVISUALIZATION and SPI_SETCONTACTVISUALIZATION +CONTACTVISUALIZATION_OFF :: 0x0000 +CONTACTVISUALIZATION_ON :: 0x0001 +CONTACTVISUALIZATION_PRESENTATIONMODE :: 0x0002 + +SPI_GETGESTUREVISUALIZATION :: 0x201A +SPI_SETGESTUREVISUALIZATION :: 0x201B +// constants for SPI_GETGESTUREVISUALIZATION and SPI_SETGESTUREVISUALIZATION +GESTUREVISUALIZATION_OFF :: 0x0000 +GESTUREVISUALIZATION_ON :: 0x001F +GESTUREVISUALIZATION_TAP :: 0x0001 +GESTUREVISUALIZATION_DOUBLETAP :: 0x0002 +GESTUREVISUALIZATION_PRESSANDTAP :: 0x0004 +GESTUREVISUALIZATION_PRESSANDHOLD :: 0x0008 +GESTUREVISUALIZATION_RIGHTTAP :: 0x0010 + +SPI_GETMOUSEWHEELROUTING :: 0x201C +SPI_SETMOUSEWHEELROUTING :: 0x201D + +MOUSEWHEEL_ROUTING_FOCUS :: 0 +MOUSEWHEEL_ROUTING_HYBRID :: 1 +MOUSEWHEEL_ROUTING_MOUSE_POS :: 2 + +// Flags +SPIF_UPDATEINIFILE :: 0x0001 +SPIF_SENDWININICHANGE :: 0x0002 +SPIF_SENDCHANGE :: SPIF_SENDWININICHANGE diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index dd45df42a..6f42267db 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -114,10 +114,14 @@ foreign user32 { cy: c_int, uFlags: UINT, ) -> BOOL --- + MoveWindow :: proc(hWnd: HWND, X, Y, hWidth, hHeight: c_int, bRepaint: BOOL) -> BOOL --- GetSystemMetrics :: proc(nIndex: c_int) -> c_int --- AdjustWindowRect :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL) -> BOOL --- AdjustWindowRectEx :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD) -> BOOL --- + SystemParametersInfoA :: proc(uiAction, uiParam: UINT, pvParam: PVOID, fWinIni: UINT) -> BOOL --- + SystemParametersInfoW :: proc(uiAction, uiParam: UINT, pvParam: PVOID, fWinIni: UINT) -> BOOL --- + GetWindowDC :: proc(hWnd: HWND) -> HDC --- GetDC :: proc(hWnd: HWND) -> HDC --- ReleaseDC :: proc(hWnd: HWND, hDC: HDC) -> c_int --- From dd8b71e353bc72eecf95ca2ae45c437dc01e89bf Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 17:52:23 +0200 Subject: [PATCH 137/245] [pbm] WIP unit tests. --- core/image/netpbm/helpers.odin | 1 + core/image/netpbm/netpbm.odin | 138 +++++++++++++++++++++----- tests/core/image/test_core_image.odin | 58 ++++++++--- 3 files changed, 155 insertions(+), 42 deletions(-) diff --git a/core/image/netpbm/helpers.odin b/core/image/netpbm/helpers.odin index 5a3000a87..8c5cdd622 100644 --- a/core/image/netpbm/helpers.odin +++ b/core/image/netpbm/helpers.odin @@ -14,6 +14,7 @@ destroy :: proc(img: ^image.Image) -> bool { header_destroy(&info.header) free(info) img.metadata = nil + free(img) return true } diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 54935d6c6..cccf7e865 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -31,19 +31,19 @@ load :: proc { load_from_buffer, } -load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: Image, err: Error) { +load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator data, ok := os.read_entire_file(filename); defer delete(data) if !ok { - err = .File_Not_Readable + err = .Unable_To_Read_File return } - return read_from_buffer(data) + return load_from_buffer(data) } -load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { +load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator header: Header; defer header_destroy(&header) @@ -51,7 +51,9 @@ load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: header, header_size = parse_header(data) or_return img_data := data[header_size:] - img = decode_image(header, img_data) or_return + + img = new(Image) + decode_image(img, header, img_data) or_return info := new(Info) info.header = header @@ -69,27 +71,42 @@ save :: proc { save_to_buffer, } -save_to_file :: proc(filename: string, img: Image, allocator := context.allocator) -> (err: Error) { +save_to_file :: proc(filename: string, img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (err: Error) { context.allocator = allocator data: []byte; defer delete(data) - data = write_to_buffer(img) or_return + data = save_to_buffer(img, custom_info) or_return if ok := os.write_entire_file(filename, data); !ok { - return .File_Not_Writable + return .Unable_To_Write_File } return Format_Error.None } -save_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: []byte, err: Error) { +save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context.allocator) -> (buffer: []byte, err: Error) { context.allocator = allocator - info, ok := img.metadata.(^image.Netpbm_Info) - if !ok { - err = image.General_Image_Error.Invalid_Input_Image - return + info: Info = {} + if custom_info.header.width > 0 { + // Custom info has been set, use it. + info = custom_info + } else { + img_info, ok := img.metadata.(^image.Netpbm_Info) + if !ok { + // image doesn't have .Netpbm info, guess it + auto_info, auto_info_found := autoselect_pbm_format_from_image(img) + if auto_info_found { + info = auto_info + } else { + return {}, .Invalid_Input_Image + } + } else { + // use info as stored on image + info = img_info^ + } } + // using info so we can just talk about the header using info @@ -103,11 +120,11 @@ save_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: [ if header.format in (PNM + PAM) { if header.maxval <= int(max(u8)) && img.depth != 8 \ || header.maxval > int(max(u8)) && header.maxval <= int(max(u16)) && img.depth != 16 { - err = Format_Error.Invalid_Image_Depth + err = .Invalid_Image_Depth return } } else if header.format in PFM && img.depth != 32 { - err = Format_Error.Invalid_Image_Depth + err = .Invalid_Image_Depth return } @@ -233,11 +250,11 @@ save_to_buffer :: proc(img: Image, allocator := context.allocator) -> (buffer: [ } case: - return data.buf[:], Format_Error.Invalid_Image_Depth + return data.buf[:], .Invalid_Image_Depth } case: - return data.buf[:], Format_Error.Invalid_Format + return data.buf[:], .Invalid_Format } return data.buf[:], Format_Error.None @@ -263,7 +280,7 @@ parse_header :: proc(data: []byte, allocator := context.allocator) -> (header: H } } - err = Format_Error.Invalid_Signature + err = .Invalid_Signature return } @@ -366,7 +383,7 @@ _parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (head // the spec needs the newline apparently if string(data[0:3]) != "P7\n" { - err = Format_Error.Invalid_Signature + err = .Invalid_Signature return } header.format = .P7 @@ -468,7 +485,7 @@ _parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Er header.format = .PF header.channels = 3 case: - err = Format_Error.Invalid_Signature + err = .Invalid_Signature return } @@ -531,18 +548,18 @@ _parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Er return } -decode_image :: proc(header: Header, data: []byte, allocator := context.allocator) -> (img: Image, err: Error) { +decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := context.allocator) -> (err: Error) { + assert(img != nil) context.allocator = allocator - img = Image { - width = header.width, - height = header.height, - channels = header.channels, - depth = header.depth, - } + img.width = header.width + img.height = header.height + img.channels = header.channels + img.depth = header.depth buffer_size := image.compute_buffer_size(img.width, img.height, img.channels, img.depth) + when false { // we can check data size for binary formats if header.format in BINARY { if header.format == .P4 { @@ -558,6 +575,7 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato } } } + } // for ASCII and P4, we use length for the termination condition, so start at 0 // BINARY will be a simple memcopy so the buffer length should also be initialised @@ -665,4 +683,70 @@ decode_image :: proc(header: Header, data: []byte, allocator := context.allocato err = Format_Error.None return +} + +// Automatically try to select an appropriate format to save to based on `img.channel` and `img.depth` +autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, force_black_and_white := false, pfm_scale := f32(1.0)) -> (res: Info, ok: bool) { + /* + PBM (P1, P4): Portable Bit Map, stores black and white images (1 channel) + PGM (P2, P5): Portable Gray Map, stores greyscale images (1 channel, 1 or 2 bytes per value) + PPM (P3, P6): Portable Pixel Map, stores colour images (3 channel, 1 or 2 bytes per value) + PAM (P7 ): Portable Arbitrary Map, stores arbitrary channel images (1 or 2 bytes per value) + PFM (Pf, PF): Portable Float Map, stores floating-point images (Pf: 1 channel, PF: 3 channel) + + ASCII :: Formats{.P1, .P2, .P3} + */ + using res.header + + width = img.width + height = img.height + channels = img.channels + depth = img.depth + maxval = 255 if img.depth == 8 else 65535 + little_endian = true if ODIN_ENDIAN == .Little else false + + // Assume we'll find a suitable format + ok = true + + switch img.channels { + case 1: + // Must be Portable Float Map + if img.depth == 32 { + format = .Pf + return + } + + if force_black_and_white { + // Portable Bit Map + format = .P4 if prefer_binary else .P1 + maxval = 1 + return + } else { + // Portable Gray Map + format = .P5 if prefer_binary else .P2 + return + } + + case 3: + // Must be Portable Float Map + if img.depth == 32 { + format = .PF + return + } + + // Portable Pixel Map + format = .P6 if prefer_binary else .P3 + return + + case: + // Portable Arbitrary Map + if img.depth == 8 || img.depth == 16 { + format = .P7 + scale = pfm_scale + return + } + } + + // We couldn't find a suitable format + return {}, false } \ No newline at end of file diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index c328757e4..1ffd3b93d 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -13,6 +13,7 @@ import "core:testing" import "core:compress" import "core:image" +import pbm "core:image/netpbm" import "core:image/png" import "core:image/qoi" @@ -1506,26 +1507,53 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { passed &= test.hash == png_hash - // Roundtrip through QOI to test the QOI encoder and decoder. - if passed && img.depth == 8 && (img.channels == 3 || img.channels == 4) { - qoi_buffer: bytes.Buffer - defer bytes.buffer_destroy(&qoi_buffer) - qoi_save_err := qoi.save(&qoi_buffer, img) + if passed { + // Roundtrip through QOI to test the QOI encoder and decoder. + if img.depth == 8 && (img.channels == 3 || img.channels == 4) { + qoi_buffer: bytes.Buffer + defer bytes.buffer_destroy(&qoi_buffer) + qoi_save_err := qoi.save(&qoi_buffer, img) - error = fmt.tprintf("%v test %v QOI save failed with %v.", file.file, count, qoi_save_err) - expect(t, qoi_save_err == nil, error) + error = fmt.tprintf("%v test %v QOI save failed with %v.", file.file, count, qoi_save_err) + expect(t, qoi_save_err == nil, error) - if qoi_save_err == nil { - qoi_img, qoi_load_err := qoi.load(qoi_buffer.buf[:]) - defer qoi.destroy(qoi_img) + if qoi_save_err == nil { + qoi_img, qoi_load_err := qoi.load(qoi_buffer.buf[:]) + defer qoi.destroy(qoi_img) - error = fmt.tprintf("%v test %v QOI load failed with %v.", file.file, count, qoi_load_err) - expect(t, qoi_load_err == nil, error) + error = fmt.tprintf("%v test %v QOI load failed with %v.", file.file, count, qoi_load_err) + expect(t, qoi_load_err == nil, error) - qoi_hash := hash.crc32(qoi_img.pixels.buf[:]) - error = fmt.tprintf("%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options) - expect(t, qoi_hash == png_hash, error) + qoi_hash := hash.crc32(qoi_img.pixels.buf[:]) + error = fmt.tprintf("%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options) + expect(t, qoi_hash == png_hash, error) + } } + + // Roundtrip through PBM to test the PBM encoders and decoders - prefer binary + pbm_buf, pbm_save_err := pbm.save_to_buffer(img) + defer delete(pbm_buf) + + error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) + expect(t, pbm_save_err == nil, error) + + if pbm_save_err == nil { + // Try to load it again. + pbm_img, pbm_load_err := pbm.load(pbm_buf) + defer pbm.destroy(pbm_img) + + if pbm_load_err == nil { + fmt.printf("%v test %v PBM load worked with %v.\n", file.file, count, pbm_load_err) + } + error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) + expect(t, pbm_load_err == nil, error) + } + + // Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII + // pbm_info, pbm_format_selected = pbm.autoselect_pbm_format_from_image(img, false) + // fmt.printf("Autoselect PBM: %v (%v)\n", pbm_info, pbm_format_selected) + + } if .return_metadata in test.options { From 234d52986776812641a2766de40e63798b55c857 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 19:25:16 +0200 Subject: [PATCH 138/245] [pbm] WIP unit tests. part deux. --- tests/core/image/test_core_image.odin | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 1ffd3b93d..93baa76ec 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1534,6 +1534,9 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { pbm_buf, pbm_save_err := pbm.save_to_buffer(img) defer delete(pbm_buf) + filename := fmt.tprintf("%v-%v.ppm", file.file, count) + pbm.save_to_file(filename, img) + error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) expect(t, pbm_save_err == nil, error) @@ -1544,9 +1547,30 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { if pbm_load_err == nil { fmt.printf("%v test %v PBM load worked with %v.\n", file.file, count, pbm_load_err) + + pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) + if pbm_hash == png_hash { + fmt.printf("\t%v test %v PBM load hash %08x matched PNG's\n", file.file, count, png_hash) + } else { + if img.width != pbm_img.width || img.height != pbm_img.height || img.channels != pbm_img.channels || img.depth != pbm_img.depth { + fmt.printf("\tHash failed. IMG: %v, %v, %v, %v PBM: %v, %v, %v, %v\n", img.width, img.height, img.channels, img.depth, pbm_img.width, pbm_img.height, pbm_img.channels, pbm_img.depth) + } else if len(img.pixels.buf) != len(pbm_img.pixels.buf) { + fmt.printf("\tLengths differ. IMG: %v PBM: %v\n", len(img.pixels.buf), len(pbm_img.pixels.buf)) + } else if file.file[:3] == "bas" { + for v, i in img.pixels.buf { + if v != pbm_img.pixels.buf[i] { + fmt.printf("\tChannels: %v, Depth: %v, Pixel %v differs. PNG: %v, PBM: %v\n", img.channels, img.depth, i, img.pixels.buf[i:][:4], pbm_img.pixels.buf[i:][:4]) + break + } + } + } + // error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) + // expect(t, pbm_hash == png_hash, error) + } + } else { + // error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) + // expect(t, pbm_load_err == nil, error) } - error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) - expect(t, pbm_load_err == nil, error) } // Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII From 8bd16c32f3bbe724321127fcaaf798a1928cf0fe Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 21:00:32 +0200 Subject: [PATCH 139/245] [pbm] Fixes. --- core/image/netpbm/helpers.odin | 5 +- core/image/netpbm/netpbm.odin | 45 ++++++++-------- tests/core/image/test_core_image.odin | 76 ++++++++++++++------------- 3 files changed, 64 insertions(+), 62 deletions(-) diff --git a/core/image/netpbm/helpers.odin b/core/image/netpbm/helpers.odin index 8c5cdd622..2fbd32ecc 100644 --- a/core/image/netpbm/helpers.odin +++ b/core/image/netpbm/helpers.odin @@ -6,15 +6,16 @@ import "core:image" destroy :: proc(img: ^image.Image) -> bool { if img == nil do return false + defer free(img) + bytes.buffer_destroy(&img.pixels) + //! TEMP CAST info, ok := img.metadata.(^image.Netpbm_Info) if !ok do return false - bytes.buffer_destroy(&img.pixels) header_destroy(&info.header) free(info) img.metadata = nil - free(img) return true } diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index cccf7e865..768c06110 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -46,13 +46,13 @@ load_from_file :: proc(filename: string, allocator := context.allocator) -> (img load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator + img = new(Image) + header: Header; defer header_destroy(&header) header_size: int header, header_size = parse_header(data) or_return img_data := data[header_size:] - - img = new(Image) decode_image(img, header, img_data) or_return info := new(Info) @@ -62,8 +62,7 @@ load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: } img.metadata = info - err = Format_Error.None - return + return img, nil } save :: proc { @@ -140,8 +139,14 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context fmt.sbprintf(&data, "%i\n", header.maxval) } } else if header.format in PAM { - fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nTUPLTYPE %s\nENDHDR\n", - img.width, img.height, header.maxval, img.channels, header.tupltype) + if len(header.tupltype) > 0 { + fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nTUPLTYPE %s\nENDHDR\n", + img.width, img.height, header.maxval, img.channels, header.tupltype) + } else { + fmt.sbprintf(&data, "WIDTH %i\nHEIGHT %i\nMAXVAL %i\nDEPTH %i\nENDHDR\n", + img.width, img.height, header.maxval, img.channels) + } + } else if header.format in PFM { scale := -header.scale if header.little_endian else header.scale fmt.sbprintf(&data, "%i %i\n%f\n", img.width, img.height, scale) @@ -369,10 +374,12 @@ _parse_header_pnm :: proc(data: []byte) -> (header: Header, length: int, err: Er if header.width < 1 \ || header.height < 1 \ || header.maxval < 1 || header.maxval > int(max(u16)) { - err = Format_Error.Invalid_Header_Value + fmt.printf("[pnm] Header: {{width = %v, height = %v, maxval: %v}}\n", header.width, header.height, header.maxval) + err = .Invalid_Header_Value return } + length -= 1 err = Format_Error.None return } @@ -427,7 +434,7 @@ _parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (head case "TUPLTYPE": if len(value) == 0 { - err = Format_Error.Invalid_Header_Value + err = .Invalid_Header_Value return } @@ -462,6 +469,7 @@ _parse_header_pam :: proc(data: []byte, allocator := context.allocator) -> (head || header.height < 1 \ || header.maxval < 1 \ || header.maxval > int(max(u16)) { + fmt.printf("[pam] Header: {{width = %v, height = %v, maxval: %v}}\n", header.width, header.height, header.maxval) err = Format_Error.Invalid_Header_Value return } @@ -540,7 +548,8 @@ _parse_header_pfm :: proc(data: []byte) -> (header: Header, length: int, err: Er if header.width < 1 \ || header.height < 1 \ || header.scale == 0.0 { - err = Format_Error.Invalid_Header_Value + fmt.printf("[pfm] Header: {{width = %v, height = %v, scale: %v}}\n", header.width, header.height, header.scale) + err = .Invalid_Header_Value return } @@ -559,23 +568,13 @@ decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := con buffer_size := image.compute_buffer_size(img.width, img.height, img.channels, img.depth) - when false { // we can check data size for binary formats if header.format in BINARY { - if header.format == .P4 { - p4_size := (img.width / 8 + 1) * img.height - if len(data) < p4_size { - err = Format_Error.Buffer_Too_Small - return - } - } else { - if len(data) < buffer_size { - err = Format_Error.Buffer_Too_Small - return - } + if len(data) < buffer_size { + fmt.printf("len(data): %v, buffer size: %v\n", len(data), buffer_size) + return .Buffer_Too_Small } } - } // for ASCII and P4, we use length for the termination condition, so start at 0 // BINARY will be a simple memcopy so the buffer length should also be initialised @@ -605,7 +604,7 @@ decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := con // Simple binary case .P5, .P6, .P7, .Pf, .PF: - mem.copy(raw_data(img.pixels.buf), raw_data(data), buffer_size) + copy(img.pixels.buf[:], data[:]) // convert to native endianness if header.format in PFM { diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 93baa76ec..f1f1e1244 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1530,54 +1530,56 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { } } - // Roundtrip through PBM to test the PBM encoders and decoders - prefer binary - pbm_buf, pbm_save_err := pbm.save_to_buffer(img) - defer delete(pbm_buf) + { + // Roundtrip through PBM to test the PBM encoders and decoders - prefer binary + pbm_buf, pbm_save_err := pbm.save_to_buffer(img) + defer delete(pbm_buf) - filename := fmt.tprintf("%v-%v.ppm", file.file, count) - pbm.save_to_file(filename, img) + error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) + expect(t, pbm_save_err == nil, error) - error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) - expect(t, pbm_save_err == nil, error) + if pbm_save_err == nil { + // Try to load it again. + pbm_img, pbm_load_err := pbm.load(pbm_buf) + defer pbm.destroy(pbm_img) - if pbm_save_err == nil { - // Try to load it again. - pbm_img, pbm_load_err := pbm.load(pbm_buf) - defer pbm.destroy(pbm_img) + error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) + expect(t, pbm_load_err == nil, error) - if pbm_load_err == nil { - fmt.printf("%v test %v PBM load worked with %v.\n", file.file, count, pbm_load_err) + if pbm_load_err == nil { + pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) - pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) - if pbm_hash == png_hash { - fmt.printf("\t%v test %v PBM load hash %08x matched PNG's\n", file.file, count, png_hash) - } else { - if img.width != pbm_img.width || img.height != pbm_img.height || img.channels != pbm_img.channels || img.depth != pbm_img.depth { - fmt.printf("\tHash failed. IMG: %v, %v, %v, %v PBM: %v, %v, %v, %v\n", img.width, img.height, img.channels, img.depth, pbm_img.width, pbm_img.height, pbm_img.channels, pbm_img.depth) - } else if len(img.pixels.buf) != len(pbm_img.pixels.buf) { - fmt.printf("\tLengths differ. IMG: %v PBM: %v\n", len(img.pixels.buf), len(pbm_img.pixels.buf)) - } else if file.file[:3] == "bas" { - for v, i in img.pixels.buf { - if v != pbm_img.pixels.buf[i] { - fmt.printf("\tChannels: %v, Depth: %v, Pixel %v differs. PNG: %v, PBM: %v\n", img.channels, img.depth, i, img.pixels.buf[i:][:4], pbm_img.pixels.buf[i:][:4]) - break - } - } - } - // error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) - // expect(t, pbm_hash == png_hash, error) + error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) + expect(t, pbm_hash == png_hash, error) } - } else { - // error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) - // expect(t, pbm_load_err == nil, error) } } - // Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII - // pbm_info, pbm_format_selected = pbm.autoselect_pbm_format_from_image(img, false) - // fmt.printf("Autoselect PBM: %v (%v)\n", pbm_info, pbm_format_selected) + { + // Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII + pbm_info, pbm_format_selected := pbm.autoselect_pbm_format_from_image(img, false) + pbm_buf, pbm_save_err := pbm.save_to_buffer(img, pbm_info) + defer delete(pbm_buf) + error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) + expect(t, pbm_save_err == nil, error) + if pbm_save_err == nil { + // Try to load it again. + pbm_img, pbm_load_err := pbm.load(pbm_buf) + defer pbm.destroy(pbm_img) + + error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) + expect(t, pbm_load_err == nil, error) + + if pbm_load_err == nil { + pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) + + error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) + expect(t, pbm_hash == png_hash, error) + } + } + } } if .return_metadata in test.options { From 7a032cf9f9818cfb566e91b7f5926bd7278daf07 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 21:57:14 +0200 Subject: [PATCH 140/245] [pbm] Also test PFM formats. --- tests/core/image/test_core_image.odin | 109 ++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index f1f1e1244..2ecc67151 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1558,25 +1558,106 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { { // Roundtrip through PBM to test the PBM encoders and decoders - prefer ASCII pbm_info, pbm_format_selected := pbm.autoselect_pbm_format_from_image(img, false) - pbm_buf, pbm_save_err := pbm.save_to_buffer(img, pbm_info) - defer delete(pbm_buf) - error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) - expect(t, pbm_save_err == nil, error) + // We already tested the binary formats above. + if pbm_info.header.format in pbm.ASCII { + pbm_buf, pbm_save_err := pbm.save_to_buffer(img, pbm_info) + defer delete(pbm_buf) - if pbm_save_err == nil { - // Try to load it again. - pbm_img, pbm_load_err := pbm.load(pbm_buf) - defer pbm.destroy(pbm_img) + error = fmt.tprintf("%v test %v PBM save failed with %v.", file.file, count, pbm_save_err) + expect(t, pbm_save_err == nil, error) - error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) - expect(t, pbm_load_err == nil, error) + if pbm_save_err == nil { + // Try to load it again. + pbm_img, pbm_load_err := pbm.load(pbm_buf) + defer pbm.destroy(pbm_img) - if pbm_load_err == nil { - pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) + error = fmt.tprintf("%v test %v PBM load failed with %v.", file.file, count, pbm_load_err) + expect(t, pbm_load_err == nil, error) - error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) - expect(t, pbm_hash == png_hash, error) + if pbm_load_err == nil { + pbm_hash := hash.crc32(pbm_img.pixels.buf[:]) + + error = fmt.tprintf("%v test %v PBM load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, pbm_hash, png_hash, test.options) + expect(t, pbm_hash == png_hash, error) + } + } + } + } + + { + // We still need to test Portable Float Maps + if (img.channels == 1 || img.channels == 3) && (img.depth == 8 || img.depth == 16) { + + // Make temporary float image + float_img := new(image.Image) + defer png.destroy(float_img) + + float_img.width = img.width + float_img.height = img.height + float_img.channels = img.channels + float_img.depth = 32 + + buffer_size := image.compute_buffer_size(img.width, img.height, img.channels, 32) + resize(&float_img.pixels.buf, buffer_size) + + pbm_info := pbm.Info { + header = { + width = img.width, + height = img.height, + channels = img.channels, + depth = img.depth, + maxval = 255 if img.depth == 8 else 65535, + little_endian = true if ODIN_ENDIAN == .Little else false, + scale = 1.0, + format = .Pf if img.channels == 1 else .PF, + }, + } + + // Transform data... + orig_float := mem.slice_data_cast([]f32, float_img.pixels.buf[:]) + + switch img.depth { + case 8: + for v, i in img.pixels.buf { + orig_float[i] = f32(v) / f32(256) + } + case 16: + wide := mem.slice_data_cast([]u16, img.pixels.buf[:]) + for v, i in wide { + orig_float[i] = f32(v) / f32(65536) + } + } + + float_pbm_buf, float_pbm_save_err := pbm.save_to_buffer(float_img, pbm_info) + defer delete(float_pbm_buf) + + error = fmt.tprintf("%v test %v save as PFM failed with %v", file.file, count, float_pbm_save_err) + expect(t, float_pbm_save_err == nil, error) + + if float_pbm_save_err == nil { + // Load float image and compare. + float_pbm_img, float_pbm_load_err := pbm.load(float_pbm_buf) + defer pbm.destroy(float_pbm_img) + + error = fmt.tprintf("%v test %v PFM load failed with %v", file.file, count, float_pbm_load_err) + expect(t, float_pbm_load_err == nil, error) + + load_float := mem.slice_data_cast([]f32, float_pbm_img.pixels.buf[:]) + + error = fmt.tprintf("%v test %v PFM load returned %v floats, expected %v", file.file, count, len(load_float), len(orig_float)) + expect(t, len(load_float) == len(orig_float), error) + + // Compare floats + equal := true + for orig, i in orig_float { + if orig != load_float[i] { + equal = false + break + } + } + error = fmt.tprintf("%v test %v PFM loaded floats to match", file.file, count) + expect(t, equal, error) } } } From 2081f8fcd66efa71ab526d10751bbe882be228ba Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 22:04:47 +0200 Subject: [PATCH 141/245] [tests/core/image] Remove old crappy PPM writer. --- tests/core/image/test_core_image.odin | 201 -------------------------- 1 file changed, 201 deletions(-) diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 2ecc67151..9c9831199 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -27,7 +27,6 @@ import "core:time" import "core:runtime" -WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false) TEST_SUITE_PATH :: "assets/PNG" TEST_count := 0 @@ -1879,12 +1878,6 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { } } - if WRITE_PPM_ON_FAIL && !passed && err == nil { // It loaded but had an error in its compares. - testing.logf(t, "Test failed, writing ppm/%v-%v.ppm to help debug.\n", file.file, count) - output := fmt.tprintf("ppm/%v-%v.ppm", file.file, count) - write_image_as_ppm(output, img) - } - png.destroy(img) for _, v in track.allocation_map { @@ -1895,198 +1888,4 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { } return -} - -// Crappy PPM writer used during testing. Don't use in production. -write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: bool) { - - _bg :: proc(x, y: int, high := true) -> (res: [3]u16) { - if high { - l := u16(30 * 256 + 30) - - if (x & 4 == 0) ~ (y & 4 == 0) { - res = [3]u16{l, l, l} - } else { - res = [3]u16{l >> 1, l >> 1, l >> 1} - } - } else { - if (x & 4 == 0) ~ (y & 4 == 0) { - res = [3]u16{30, 30, 30} - } else { - res = [3]u16{15, 15, 15} - } - } - return - } - - using image - using os - - flags: int = O_WRONLY|O_CREATE|O_TRUNC - - img := image - - // PBM 16-bit images are big endian - when ODIN_ENDIAN == .Little { - if img.depth == 16 { - // The pixel components are in Big Endian. Let's byteswap back. - input := mem.slice_data_cast([]u16, img.pixels.buf[:]) - output := mem.slice_data_cast([]u16be, img.pixels.buf[:]) - #no_bounds_check for v, i in input { - output[i] = u16be(v) - } - } - } - - pix := bytes.buffer_to_bytes(&img.pixels) - - if len(pix) == 0 || len(pix) < image.width * image.height * int(image.channels) { - return false - } - - mode: int = 0 - when ODIN_OS == .Linux || ODIN_OS == .Darwin { - // NOTE(justasd): 644 (owner read, write; group read; others read) - mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH - } - - fd, err := open(filename, flags, mode) - if err != 0 { - return false - } - defer close(fd) - - write_string(fd, - fmt.tprintf("P6\n%v %v\n%v\n", width, height, (1 << uint(depth) -1)), - ) - - if channels == 3 { - // We don't handle transparency here... - write_ptr(fd, raw_data(pix), len(pix)) - } else { - bpp := depth == 16 ? 2 : 1 - bytes_needed := width * height * 3 * bpp - - op := bytes.Buffer{} - bytes.buffer_init_allocator(&op, bytes_needed, bytes_needed) - defer bytes.buffer_destroy(&op) - - if channels == 1 { - if depth == 16 { - assert(len(pix) == width * height * 2) - p16 := mem.slice_data_cast([]u16, pix) - o16 := mem.slice_data_cast([]u16, op.buf[:]) - #no_bounds_check for len(p16) != 0 { - r := u16(p16[0]) - o16[0] = r - o16[1] = r - o16[2] = r - p16 = p16[1:] - o16 = o16[3:] - } - } else { - o := 0 - for i := 0; i < len(pix); i += 1 { - r := pix[i] - op.buf[o ] = r - op.buf[o+1] = r - op.buf[o+2] = r - o += 3 - } - } - write_ptr(fd, raw_data(op.buf), len(op.buf)) - } else if channels == 2 { - if depth == 16 { - p16 := mem.slice_data_cast([]u16, pix) - o16 := mem.slice_data_cast([]u16, op.buf[:]) - - bgcol := img.background - - #no_bounds_check for len(p16) != 0 { - r := f64(u16(p16[0])) - bg: f64 - if bgcol != nil { - v := bgcol.([3]u16)[0] - bg = f64(v) - } - a := f64(u16(p16[1])) / 65535.0 - l := (a * r) + (1 / a) * bg - - o16[0] = u16(l) - o16[1] = u16(l) - o16[2] = u16(l) - - p16 = p16[2:] - o16 = o16[3:] - } - } else { - o := 0 - for i := 0; i < len(pix); i += 2 { - r := pix[i]; a := pix[i+1]; a1 := f32(a) / 255.0 - c := u8(f32(r) * a1) - op.buf[o ] = c - op.buf[o+1] = c - op.buf[o+2] = c - o += 3 - } - } - write_ptr(fd, raw_data(op.buf), len(op.buf)) - } else if channels == 4 { - if depth == 16 { - p16 := mem.slice_data_cast([]u16be, pix) - o16 := mem.slice_data_cast([]u16be, op.buf[:]) - - i := 0 - for len(p16) > 0 { - i += 1 - x := i % width - y := i / width - bg := _bg(x, y, true) - - r := f32(p16[0]) - g := f32(p16[1]) - b := f32(p16[2]) - a := f32(p16[3]) / 65535.0 - - lr := (a * r) + (1 / a) * f32(bg[0]) - lg := (a * g) + (1 / a) * f32(bg[1]) - lb := (a * b) + (1 / a) * f32(bg[2]) - - o16[0] = u16be(lr) - o16[1] = u16be(lg) - o16[2] = u16be(lb) - - p16 = p16[4:] - o16 = o16[3:] - } - } else { - o := 0 - - for i := 0; i < len(pix); i += 4 { - - x := (i / 4) % width - y := i / width / 4 - _b := _bg(x, y, false) - bgcol := [3]u8{u8(_b[0]), u8(_b[1]), u8(_b[2])} - - r := f32(pix[i]) - g := f32(pix[i+1]) - b := f32(pix[i+2]) - a := f32(pix[i+3]) / 255.0 - - lr := u8(f32(r) * a + (1 / a) * f32(bgcol[0])) - lg := u8(f32(g) * a + (1 / a) * f32(bgcol[1])) - lb := u8(f32(b) * a + (1 / a) * f32(bgcol[2])) - op.buf[o ] = lr - op.buf[o+1] = lg - op.buf[o+2] = lb - o += 3 - } - } - write_ptr(fd, raw_data(op.buf), len(op.buf)) - } else { - return false - } - } - return true } \ No newline at end of file From 6ade9acc4d220a9912fb7d88ae26d82131351e12 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 30 Apr 2022 22:54:53 +0200 Subject: [PATCH 142/245] [pbm] Remove stray comment. --- core/image/netpbm/helpers.odin | 1 - 1 file changed, 1 deletion(-) diff --git a/core/image/netpbm/helpers.odin b/core/image/netpbm/helpers.odin index 2fbd32ecc..016f9453e 100644 --- a/core/image/netpbm/helpers.odin +++ b/core/image/netpbm/helpers.odin @@ -9,7 +9,6 @@ destroy :: proc(img: ^image.Image) -> bool { defer free(img) bytes.buffer_destroy(&img.pixels) - //! TEMP CAST info, ok := img.metadata.(^image.Netpbm_Info) if !ok do return false From b2fdb881eb6734b973b4bb0a8ff04a3a775c9454 Mon Sep 17 00:00:00 2001 From: hikari Date: Sun, 1 May 2022 13:21:28 +0300 Subject: [PATCH 143/245] sys/windows: remove A variant for one SystemParametersInfoW --- core/sys/windows/user32.odin | 1 - 1 file changed, 1 deletion(-) diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 6f42267db..f83713a33 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -119,7 +119,6 @@ foreign user32 { AdjustWindowRect :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL) -> BOOL --- AdjustWindowRectEx :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD) -> BOOL --- - SystemParametersInfoA :: proc(uiAction, uiParam: UINT, pvParam: PVOID, fWinIni: UINT) -> BOOL --- SystemParametersInfoW :: proc(uiAction, uiParam: UINT, pvParam: PVOID, fWinIni: UINT) -> BOOL --- GetWindowDC :: proc(hWnd: HWND) -> HDC --- From 335b7242099153f0777ce5417b8ef8261de03ec8 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 1 May 2022 12:47:05 +0200 Subject: [PATCH 144/245] [xxh3] Fix flaws in streaming implementation --- core/hash/xxhash/streaming.odin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index d6df1089f..68a4920a5 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -52,9 +52,6 @@ XXH3_128_reset_with_seed :: proc(state: ^XXH3_state, seed: XXH64_hash) -> (err: XXH3_64_reset_with_seed :: XXH3_128_reset_with_seed XXH3_128_update :: proc(state: ^XXH3_state, input: []u8) -> (err: Error) { - if len(input) < XXH3_MIDSIZE_MAX { - return .Error - } return XXH3_update(state, input, XXH3_accumulate_512, XXH3_scramble_accumulator) } XXH3_64_update :: XXH3_128_update @@ -127,6 +124,7 @@ XXH3_create_state :: proc(allocator := context.allocator) -> (res: ^XXH3_state, err = nil if mem_error == nil else .Error XXH3_init_state(state) + XXH3_128_reset(state) return state, nil } @@ -234,7 +232,9 @@ XXH3_update :: #force_inline proc( */ if state.buffered_size > 0 { load_size := int(XXH3_INTERNAL_BUFFER_SIZE - state.buffered_size) - mem_copy(&state.buffer[state.buffered_size], &input[0], load_size) + + state_ptr := rawptr(uintptr(raw_data(state.buffer[:])) + uintptr(state.buffered_size)) + mem_copy(state_ptr, raw_data(input), load_size) input = input[load_size:] XXH3_consume_stripes( From 74d3bcec05e693889b075ef64d88ee3ef985d13c Mon Sep 17 00:00:00 2001 From: WalterPlinge <22519813+WalterPlinge@users.noreply.github.com> Date: Sun, 1 May 2022 21:29:09 +0100 Subject: [PATCH 145/245] Fixed the depth values in the doc file, made some info more clear --- core/image/netpbm/doc.odin | 19 ++++++++++--------- core/image/netpbm/netpbm.odin | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/core/image/netpbm/doc.odin b/core/image/netpbm/doc.odin index baeb99968..1b5b46856 100644 --- a/core/image/netpbm/doc.odin +++ b/core/image/netpbm/doc.odin @@ -6,24 +6,25 @@ Formats: PAM (P7 ): Portable Arbitrary Map, stores arbitrary channel images (1 or 2 bytes per value) PFM (Pf, PF): Portable Float Map, stores floating-point images (Pf: 1 channel, PF: 3 channel) -Reading +Reading: All formats fill out header fields `format`, `width`, `height`, `channels`, `depth` Specific formats use more fields - PGM, PPM, and PAM set `maxval` - PAM also sets `tupltype`, and is able to set `channels` to an arbitrary value - PFM sets `scale` and `little_endian` + PGM, PPM, and PAM set `maxval` (maximum of 65535) + PAM sets `tupltype` if there is one, and can set `channels` to any value (not just 1 or 3) + PFM sets `scale` (float equivalent of `maxval`) and `little_endian` (endianness of stored floats) Currently doesn't support reading multiple images from one binary-format file -Writing +Writing: + You can use your own `Netpbm_Info` struct to control how images are written All formats require the header field `format` to be specified Additional header fields are required for specific formats - PGM, PPM, and PAM require `maxval` + PGM, PPM, and PAM require `maxval` (maximum of 65535) PAM also uses `tupltype`, though it may be left as default (empty or nil string) - PFM requires `scale` and `little_endian`, though the latter may be left untouched (default is false) + PFM requires `scale`, and optionally `little_endian` Some syntax differences from the specifications: - `channels` stores what the PAM specification calls `depth` - `depth` instead stores how many bytes will fit `maxval` (should only be 1, 2, or 4) + `channels` stores the number of values per pixel, what the PAM specification calls `depth` + `depth` instead is the number of bits for a single value (32 for PFM, 16 or 8 otherwise) `scale` and `little_endian` are separated, so the `header` will always store a positive `scale` `little_endian` will only be true for a negative `scale` PFM, every other format will be false `little_endian` only describes the netpbm data being read/written, the image buffer will be native diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 768c06110..9574faa26 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -109,7 +109,7 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context // using info so we can just talk about the header using info - //? validation + // validation if header.format in (PBM + PGM + Formats{.Pf}) && img.channels != 1 \ || header.format in (PPM + Formats{.PF}) && img.channels != 3 { err = .Invalid_Number_Of_Channels From 10a311092b3a025921bdf62710972bcd91b57730 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 May 2022 23:15:06 +0100 Subject: [PATCH 146/245] Add basic arm32 ABI support (linux_arm32) --- src/build_settings.cpp | 15 ++++++- src/llvm_abi.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 89d370144..1619c342b 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -30,6 +30,7 @@ enum TargetArchKind : u16 { TargetArch_amd64, TargetArch_i386, + TargetArch_arm32, TargetArch_arm64, TargetArch_wasm32, TargetArch_wasm64, @@ -75,6 +76,7 @@ String target_arch_names[TargetArch_COUNT] = { str_lit(""), str_lit("amd64"), str_lit("i386"), + str_lit("arm32"), str_lit("arm64"), str_lit("wasm32"), str_lit("wasm64"), @@ -98,6 +100,7 @@ TargetEndianKind target_endians[TargetArch_COUNT] = { TargetEndian_Little, TargetEndian_Little, TargetEndian_Little, + TargetEndian_Little, }; #ifndef ODIN_VERSION_RAW @@ -367,7 +370,16 @@ gb_global TargetMetrics target_linux_arm64 = { 8, 16, str_lit("aarch64-linux-elf"), - str_lit("e-m:e-i8:8:32-i16:32-i64:64-i128:128-n32:64-S128"), + str_lit("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"), +}; + +gb_global TargetMetrics target_linux_arm32 = { + TargetOs_linux, + TargetArch_arm32, + 4, + 8, + str_lit("aapcs-linux-gnu"), + str_lit("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"), }; gb_global TargetMetrics target_darwin_amd64 = { @@ -483,6 +495,7 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("linux_i386"), &target_linux_i386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, { str_lit("linux_arm64"), &target_linux_arm64 }, + { str_lit("linux_arm32"), &target_linux_arm32 }, { str_lit("windows_i386"), &target_windows_i386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, { str_lit("freebsd_i386"), &target_freebsd_i386 }, diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 07d2dd6e3..c6ff12f95 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -516,6 +516,10 @@ namespace lbAbiAmd64SysV { bool is_register(LLVMTypeRef type) { LLVMTypeKind kind = LLVMGetTypeKind(type); + i64 sz = lb_sizeof(type); + if (sz == 0) { + return false; + } switch (kind) { case LLVMIntegerTypeKind: case LLVMHalfTypeKind: @@ -1164,6 +1168,88 @@ namespace lbAbiWasm32 { } } +namespace lbAbiArm32 { + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention); + lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined); + + LB_ABI_INFO(abi_info) { + lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType); + ft->ctx = c; + ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention); + ft->ret = compute_return_type(c, return_type, return_is_defined); + ft->calling_convention = calling_convention; + return ft; + } + + bool is_register(LLVMTypeRef type, bool is_return) { + LLVMTypeKind kind = LLVMGetTypeKind(type); + switch (kind) { + case LLVMHalfTypeKind: + case LLVMFloatTypeKind: + case LLVMDoubleTypeKind: + return true; + case LLVMIntegerTypeKind: + return lb_sizeof(type) <= 8; + case LLVMFunctionTypeKind: + return true; + case LLVMPointerTypeKind: + return true; + case LLVMVectorTypeKind: + return true; + } + return false; + } + + lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type, bool is_return) { + LLVMAttributeRef attr = nullptr; + LLVMTypeRef i1 = LLVMInt1TypeInContext(c); + if (type == i1) { + attr = lb_create_enum_attribute(c, "zeroext"); + } + return lb_arg_type_direct(type, nullptr, nullptr, attr); + } + + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention) { + auto args = array_make(heap_allocator(), arg_count); + + for (unsigned i = 0; i < arg_count; i++) { + LLVMTypeRef t = arg_types[i]; + if (is_register(t, false)) { + args[i] = non_struct(c, t, false); + } else { + i64 sz = lb_sizeof(t); + i64 a = lb_alignof(t); + if (is_calling_convention_odin(calling_convention) && sz > 8) { + // Minor change to improve performance using the Odin calling conventions + args[i] = lb_arg_type_indirect(t, nullptr); + } else if (a <= 4) { + unsigned n = cast(unsigned)((sz + 3) / 4); + args[i] = lb_arg_type_direct(LLVMArrayType(LLVMIntTypeInContext(c, 32), n)); + } else { + unsigned n = cast(unsigned)((sz + 7) / 8); + args[i] = lb_arg_type_direct(LLVMArrayType(LLVMIntTypeInContext(c, 64), n)); + } + } + } + return args; + } + + lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined) { + if (!return_is_defined) { + return lb_arg_type_direct(LLVMVoidTypeInContext(c)); + } else if (!is_register(return_type, true)) { + switch (lb_sizeof(return_type)) { + case 1: return lb_arg_type_direct(LLVMIntTypeInContext(c, 8), return_type, nullptr, nullptr); + case 2: return lb_arg_type_direct(LLVMIntTypeInContext(c, 16), return_type, nullptr, nullptr); + case 3: case 4: return lb_arg_type_direct(LLVMIntTypeInContext(c, 32), return_type, nullptr, nullptr); + } + LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", return_type); + return lb_arg_type_indirect(return_type, attr); + } + return non_struct(c, return_type, true); + } +}; + LB_ABI_INFO(lb_get_abi_info) { switch (calling_convention) { @@ -1203,6 +1289,8 @@ LB_ABI_INFO(lb_get_abi_info) { } case TargetArch_i386: return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); + case TargetArch_arm32: + return lbAbiArm32::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); case TargetArch_arm64: return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); case TargetArch_wasm32: From 0e27b27b81f4b51ae4691d4dc84ae130867b3f67 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 May 2022 23:28:32 +0100 Subject: [PATCH 147/245] Fix building issues with arm32 --- src/build_settings.cpp | 46 +++++++++++++++++++++++++----------------- src/checker.cpp | 1 + 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 1619c342b..e596e54e5 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -378,7 +378,7 @@ gb_global TargetMetrics target_linux_arm32 = { TargetArch_arm32, 4, 8, - str_lit("aapcs-linux-gnu"), + str_lit("arm-linux-gnu"), str_lit("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"), }; @@ -1127,6 +1127,15 @@ void init_build_context(TargetMetrics *cross_target) { bc->link_flags = str_lit("-arch x86 "); break; } + } else if (bc->metrics.arch == TargetArch_arm32) { + switch (bc->metrics.os) { + case TargetOs_linux: + bc->link_flags = str_lit("-arch arm "); + break; + default: + gb_printf_err("Compiler Error: Unsupported architecture\n"); + gb_exit(1); + } } else if (bc->metrics.arch == TargetArch_arm64) { switch (bc->metrics.os) { case TargetOs_darwin: @@ -1214,27 +1223,28 @@ bool init_build_paths(String init_filename) { return false; } - GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); - GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); - - if (find_result.windows_sdk_root.len > 0) { - bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root); - } - if (find_result.windows_sdk_um_library_path.len > 0) { - bc->build_paths[BuildPath_Win_SDK_UM_Lib] = path_from_string(ha, find_result.windows_sdk_um_library_path); - } + GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); - if (find_result.windows_sdk_ucrt_library_path.len > 0) { - bc->build_paths[BuildPath_Win_SDK_UCRT_Lib] = path_from_string(ha, find_result.windows_sdk_ucrt_library_path); - } + if (find_result.windows_sdk_root.len > 0) { + bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root); + } - if (find_result.vs_exe_path.len > 0) { - bc->build_paths[BuildPath_VS_EXE] = path_from_string(ha, find_result.vs_exe_path); - } + if (find_result.windows_sdk_um_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UM_Lib] = path_from_string(ha, find_result.windows_sdk_um_library_path); + } - if (find_result.vs_library_path.len > 0) { - bc->build_paths[BuildPath_VS_LIB] = path_from_string(ha, find_result.vs_library_path); + if (find_result.windows_sdk_ucrt_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UCRT_Lib] = path_from_string(ha, find_result.windows_sdk_ucrt_library_path); + } + + if (find_result.vs_exe_path.len > 0) { + bc->build_paths[BuildPath_VS_EXE] = path_from_string(ha, find_result.vs_exe_path); + } + + if (find_result.vs_library_path.len > 0) { + bc->build_paths[BuildPath_VS_LIB] = path_from_string(ha, find_result.vs_library_path); + } } gb_free(ha, find_result.windows_sdk_root.text); diff --git a/src/checker.cpp b/src/checker.cpp index 1bb786ea1..1e33c6e9d 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -944,6 +944,7 @@ void init_universal(void) { {"Unknown", TargetArch_Invalid}, {"amd64", TargetArch_amd64}, {"i386", TargetArch_i386}, + {"arm32", TargetArch_arm32}, {"arm64", TargetArch_arm64}, {"wasm32", TargetArch_wasm32}, {"wasm64", TargetArch_wasm64}, From 18ad6c33ef896fc7b7bbf27af8b807b36b59e561 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 May 2022 23:32:31 +0100 Subject: [PATCH 148/245] Implement syscall for arm32 --- src/llvm_backend_proc.cpp | 167 ++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 71 deletions(-) diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 96ff19d10..06a74f625 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -189,7 +189,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) GB_ASSERT(entity->kind == Entity_Procedure); String link_name = entity->Procedure.link_name; if (entity->flags & EntityFlag_CustomLinkName && - link_name != "") { + link_name != "") { if (string_starts_with(link_name, str_lit("__"))) { LLVMSetLinkage(p->value, LLVMExternalLinkage); } else { @@ -200,12 +200,12 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) } } lb_set_linkage_from_entity_flags(p->module, p->value, entity->flags); - - + + if (p->is_foreign) { lb_set_wasm_import_attributes(p->value, entity, p->name); } - + // NOTE(bill): offset==0 is the return value isize offset = 1; @@ -280,7 +280,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) if (p->body != nullptr) { // String debug_name = entity->token.string.text; String debug_name = p->name; - + p->debug_info = LLVMDIBuilderCreateFunction(m->debug_builder, scope, cast(char const *)debug_name.text, debug_name.len, cast(char const *)p->name.text, p->name.len, @@ -1315,22 +1315,22 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_clamp: return lb_emit_clamp(p, type_of_expr(expr), - lb_build_expr(p, ce->args[0]), - lb_build_expr(p, ce->args[1]), - lb_build_expr(p, ce->args[2])); + lb_build_expr(p, ce->args[0]), + lb_build_expr(p, ce->args[1]), + lb_build_expr(p, ce->args[2])); case BuiltinProc_soa_zip: return lb_soa_zip(p, ce, tv); case BuiltinProc_soa_unzip: return lb_soa_unzip(p, ce, tv); - + case BuiltinProc_transpose: { lbValue m = lb_build_expr(p, ce->args[0]); return lb_emit_matrix_tranpose(p, m, tv.type); } - + case BuiltinProc_outer_product: { lbValue a = lb_build_expr(p, ce->args[0]); @@ -1347,13 +1347,13 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_ASSERT(is_type_matrix(tv.type)); return lb_emit_arith_matrix(p, Token_Mul, a, b, tv.type, true); } - + case BuiltinProc_matrix_flatten: { lbValue m = lb_build_expr(p, ce->args[0]); return lb_emit_matrix_flatten(p, m, tv.type); } - + // "Intrinsics" case BuiltinProc_alloca: @@ -1370,7 +1370,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_cpu_relax: if (build_context.metrics.arch == TargetArch_i386 || - build_context.metrics.arch == TargetArch_amd64) { + build_context.metrics.arch == TargetArch_amd64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}, true); GB_ASSERT(the_asm != nullptr); @@ -1538,7 +1538,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, lbValue dst = lb_build_expr(p, ce->args[0]); lbValue src = lb_build_expr(p, ce->args[1]); lbValue len = lb_build_expr(p, ce->args[2]); - + lb_mem_copy_overlapping(p, dst, src, len, false); return {}; } @@ -1547,7 +1547,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, lbValue dst = lb_build_expr(p, ce->args[0]); lbValue src = lb_build_expr(p, ce->args[1]); lbValue len = lb_build_expr(p, ce->args[2]); - + lb_mem_copy_non_overlapping(p, dst, src, len, false); return {}; } @@ -1651,7 +1651,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = type_deref(dst.type); return res; } - + case BuiltinProc_unaligned_store: { lbValue dst = lb_build_expr(p, ce->args[0]); @@ -1661,7 +1661,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false); return {}; } - + case BuiltinProc_unaligned_load: { lbValue src = lb_build_expr(p, ce->args[0]); @@ -1843,7 +1843,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = t; return lb_emit_conv(p, res, t); } - + case BuiltinProc_prefetch_read_instruction: case BuiltinProc_prefetch_read_data: case BuiltinProc_prefetch_write_instruction: @@ -1871,27 +1871,27 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, cache = 1; break; } - + char const *name = "llvm.prefetch"; - + LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)}; unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0])); LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); - + LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32); LLVMValueRef args[4] = {}; args[0] = ptr.value; args[1] = LLVMConstInt(llvm_i32, rw, false); args[2] = LLVMConstInt(llvm_i32, locality, false); args[3] = LLVMConstInt(llvm_i32, cache, false); - + lbValue res = {}; res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); res.type = nullptr; return res; } - + case BuiltinProc___entry_point: if (p->module->info->entry_point) { lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point); @@ -1909,22 +1909,22 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, arg = lb_emit_conv(p, arg, t_uintptr); args[i] = arg.value; } - + LLVMTypeRef llvm_uintptr = lb_type(p->module, t_uintptr); LLVMTypeRef *llvm_arg_types = gb_alloc_array(permanent_allocator(), LLVMTypeRef, arg_count); for (unsigned i = 0; i < arg_count; i++) { llvm_arg_types[i] = llvm_uintptr; } - + LLVMTypeRef func_type = LLVMFunctionType(llvm_uintptr, llvm_arg_types, arg_count, false); - + LLVMValueRef inline_asm = nullptr; - + switch (build_context.metrics.arch) { case TargetArch_amd64: { GB_ASSERT(arg_count <= 7); - + char asm_string[] = "syscall"; gbString constraints = gb_string_make(heap_allocator(), "={rax}"); for (unsigned i = 0; i < arg_count; i++) { @@ -1963,11 +1963,11 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case TargetArch_i386: { GB_ASSERT(arg_count <= 7); - + char asm_string_default[] = "int $0x80"; char *asm_string = asm_string_default; gbString constraints = gb_string_make(heap_allocator(), "={eax}"); - + for (unsigned i = 0; i < gb_min(arg_count, 6); i++) { constraints = gb_string_appendc(constraints, ",{"); static char const *regs[] = { @@ -1984,56 +1984,81 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, if (arg_count == 7) { char asm_string7[] = "push %[arg6]\npush %%ebp\nmov 4(%%esp), %%ebp\nint $0x80\npop %%ebp\nadd $4, %%esp"; asm_string = asm_string7; - + constraints = gb_string_appendc(constraints, ",rm"); } - + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; case TargetArch_arm64: { - GB_ASSERT(arg_count <= 7); - - if(build_context.metrics.os == TargetOs_darwin) { - char asm_string[] = "svc #0x80"; - gbString constraints = gb_string_make(heap_allocator(), "={x0}"); - for (unsigned i = 0; i < arg_count; i++) { - constraints = gb_string_appendc(constraints, ",{"); - static char const *regs[] = { - "x16", - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - }; - constraints = gb_string_appendc(constraints, regs[i]); - constraints = gb_string_appendc(constraints, "}"); - } + GB_ASSERT(arg_count <= 7); - inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); - } else { - char asm_string[] = "svc #0"; - gbString constraints = gb_string_make(heap_allocator(), "={x0}"); - for (unsigned i = 0; i < arg_count; i++) { - constraints = gb_string_appendc(constraints, ",{"); - static char const *regs[] = { - "x8", - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - }; - constraints = gb_string_appendc(constraints, regs[i]); - constraints = gb_string_appendc(constraints, "}"); - } + if(build_context.metrics.os == TargetOs_darwin) { + char asm_string[] = "svc #0x80"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x16", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } - inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); - } + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } else { + char asm_string[] = "svc #0"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x8", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } + } + break; + case TargetArch_arm32: + { + // TODO(bill): Check this is correct + GB_ASSERT(arg_count <= 7); + + char asm_string[] = "svc #0"; + gbString constraints = gb_string_make(heap_allocator(), "={r0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "r8", + "r0", + "r1", + "r2", + "r3", + "r4", + "r5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; default: From be8de4a1ffd0c555b94579351d5363f830a58272 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 1 May 2022 23:52:55 +0100 Subject: [PATCH 149/245] Update arch enum --- core/runtime/core.odin | 1 + core/runtime/core_builtin.odin | 6 ++++-- core/sys/unix/syscalls_linux.odin | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 4269450de..e2933d20a 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -415,6 +415,7 @@ Odin_OS_Type :: type_of(ODIN_OS) Unknown, amd64, i386, + arm32, arm64, wasm32, wasm64, diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 13e464a76..43b9ee1bf 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -631,13 +631,15 @@ assert :: proc(condition: bool, message := "", loc := #caller_location) { // to improve performance to make the CPU not // execute speculatively, making it about an order of // magnitude faster - proc(message: string, loc: Source_Code_Location) { + @(cold) + internal :: proc(message: string, loc: Source_Code_Location) { p := context.assertion_failure_proc if p == nil { p = default_assertion_failure_proc } p("runtime assertion", message, loc) - }(message, loc) + } + internal(message, loc) } } diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index 3d06d42d4..f50ae825b 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -1114,7 +1114,7 @@ when ODIN_ARCH == .amd64 { SYS_landlock_add_rule : uintptr : 445 SYS_landlock_restrict_self : uintptr : 446 SYS_memfd_secret : uintptr : 447 -} else when false /*ODIN_ARCH == .arm*/ { // TODO +} else when ODIN_ARCH == .arm32 { // TODO SYS_restart_syscall : uintptr : 0 SYS_exit : uintptr : 1 SYS_fork : uintptr : 2 From 8023c8abc7087c763da5e843252d3899784e57be Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 May 2022 14:10:02 +0100 Subject: [PATCH 150/245] Fix `@(disable=...)` --- src/llvm_backend_proc.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 06a74f625..a0e9a5da5 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -823,12 +823,6 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array const &args, GB_ASSERT(pt->kind == Type_Proc); Type *results = pt->Proc.results; - if (p->entity != nullptr) { - if (p->entity->flags & EntityFlag_Disabled) { - return {}; - } - } - lbAddr context_ptr = {}; if (pt->Proc.calling_convention == ProcCC_Odin) { context_ptr = lb_find_or_generate_context_ptr(p); @@ -2280,6 +2274,15 @@ lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { // NOTE(bill): Regular call lbValue value = {}; Ast *proc_expr = unparen_expr(ce->proc); + + Entity *proc_entity = entity_of_node(proc_expr); + if (proc_entity != nullptr) { + if (proc_entity->flags & EntityFlag_Disabled) { + GB_ASSERT(tv.type == nullptr); + return {}; + } + } + if (proc_expr->tav.mode == Addressing_Constant) { ExactValue v = proc_expr->tav.value; switch (v.kind) { @@ -2306,13 +2309,6 @@ lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) { } } - Entity *proc_entity = entity_of_node(proc_expr); - if (proc_entity != nullptr) { - if (proc_entity->flags & EntityFlag_Disabled) { - return {}; - } - } - if (value.value == nullptr) { value = lb_build_expr(p, proc_expr); } From 97717d65efde6f83e502f0261a3fb08a34ea3f04 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 2 May 2022 16:09:09 +0100 Subject: [PATCH 151/245] Add `vendor:openexr` No foreign library yet --- vendor/openexr/exr_attr.odin | 397 +++++++++++++++++ vendor/openexr/exr_base.odin | 170 ++++++++ vendor/openexr/exr_chunkio.odin | 143 +++++++ vendor/openexr/exr_coding.odin | 119 ++++++ vendor/openexr/exr_context.odin | 485 +++++++++++++++++++++ vendor/openexr/exr_debug.odin | 8 + vendor/openexr/exr_decode.odin | 288 +++++++++++++ vendor/openexr/exr_encode.odin | 319 ++++++++++++++ vendor/openexr/exr_errors.odin | 62 +++ vendor/openexr/exr_part.odin | 733 ++++++++++++++++++++++++++++++++ 10 files changed, 2724 insertions(+) create mode 100644 vendor/openexr/exr_attr.odin create mode 100644 vendor/openexr/exr_base.odin create mode 100644 vendor/openexr/exr_chunkio.odin create mode 100644 vendor/openexr/exr_coding.odin create mode 100644 vendor/openexr/exr_context.odin create mode 100644 vendor/openexr/exr_debug.odin create mode 100644 vendor/openexr/exr_decode.odin create mode 100644 vendor/openexr/exr_encode.odin create mode 100644 vendor/openexr/exr_errors.odin create mode 100644 vendor/openexr/exr_part.odin diff --git a/vendor/openexr/exr_attr.odin b/vendor/openexr/exr_attr.odin new file mode 100644 index 000000000..eb07142ec --- /dev/null +++ b/vendor/openexr/exr_attr.odin @@ -0,0 +1,397 @@ +package vendor_openexr + +import "core:c" + +// Enum declaring allowed values for \c u8 value stored in built-in compression type. +compression_t :: enum c.int { + NONE = 0, + RLE = 1, + ZIPS = 2, + ZIP = 3, + PIZ = 4, + PXR24 = 5, + B44 = 6, + B44A = 7, + DWAA = 8, + DWAB = 9, +} + +// Enum declaring allowed values for \c u8 value stored in built-in env map type. +envmap_t :: enum c.int { + LATLONG = 0, + CUBE = 1, +} + +// Enum declaring allowed values for \c u8 value stored in \c lineOrder type. +lineorder_t :: enum c.int { + INCREASING_Y = 0, + DECREASING_Y = 1, + RANDOM_Y = 2, +} + +// Enum declaring allowed values for part type. +storage_t :: enum c.int { + SCANLINE = 0, // Corresponds to type of \c scanlineimage. + TILED, // Corresponds to type of \c tiledimage. + DEEP_SCANLINE, // Corresponds to type of \c deepscanline. + DEEP_TILED, // Corresponds to type of \c deeptile. +} + +// @brief Enum representing what type of tile information is contained. +tile_level_mode_t :: enum c.int { + ONE_LEVEL = 0, // Single level of image data. + MIPMAP_LEVELS = 1, // Mipmapped image data. + RIPMAP_LEVELS = 2, // Ripmapped image data. +} + +/** @brief Enum representing how to scale positions between levels. */ +tile_round_mode_t :: enum c.int { + DOWN = 0, + UP = 1, +} + +/** @brief Enum capturing the underlying data type on a channel. */ +pixel_type_t :: enum c.int { + UINT = 0, + HALF = 1, + FLOAT = 2, +} + +/* /////////////////////////////////////// */ +/* First set of structs are data where we can read directly with no allocation needed... */ + +/** @brief Struct to hold color chromaticities to interpret the tristimulus color values in the image data. */ +attr_chromaticities_t :: struct #packed { + red_x: f32, + red_y: f32, + green_x: f32, + green_y: f32, + blue_x: f32, + blue_y: f32, + white_x: f32, + white_y: f32, +} + +/** @brief Struct to hold keycode information. */ +attr_keycode_t :: struct #packed { + film_mfc_code: i32, + film_type: i32, + prefix: i32, + count: i32, + perf_offset: i32, + perfs_per_frame: i32, + perfs_per_count: i32, +} + +/** @brief struct to hold a 32-bit floating-point 3x3 matrix. */ +attr_m33f_t :: struct #packed { + m: [9]f32, +} + +/** @brief struct to hold a 64-bit floating-point 3x3 matrix. */ +attr_m33d_t :: struct #packed { + m: [9]f64, +} + +/** @brief Struct to hold a 32-bit floating-point 4x4 matrix. */ +attr_m44f_t :: struct #packed { + m: [16]f32, +} + +/** @brief Struct to hold a 64-bit floating-point 4x4 matrix. */ +attr_m44d_t :: struct #packed { + m: [16]f64, +} + +/** @brief Struct to hold an integer ratio value. */ +attr_rational_t :: struct #packed { + num: i32, + denom: u32, +} + +/** @brief Struct to hold timecode information. */ +attr_timecode_t :: struct #packed { + time_and_flags: u32, + user_data: u32, +} + +/** @brief Struct to hold a 2-element integer vector. */ +attr_v2i_t :: distinct [2]i32 + +/** @brief Struct to hold a 2-element 32-bit float vector. */ +attr_v2f_t :: distinct [2]f32 + +/** @brief Struct to hold a 2-element 64-bit float vector. */ +attr_v2d_t :: distinct [2]f64 + +/** @brief Struct to hold a 3-element integer vector. */ +attr_v3i_t :: distinct [3]i32 + +/** @brief Struct to hold a 3-element 32-bit float vector. */ +attr_v3f_t :: distinct [3]f32 + +/** @brief Struct to hold a 3-element 64-bit float vector. */ +attr_v3d_t :: distinct [3]f64 + +/** @brief Struct to hold an integer box/region definition. */ +attr_box2i_t :: struct #packed { + min: attr_v2i_t, + max: attr_v2i_t, +} + +/** @brief Struct to hold a floating-point box/region definition. */ +attr_box2f_t:: struct #packed { + min: attr_v2f_t, + max: attr_v2f_t, +} + +/** @brief Struct holding base tiledesc attribute type defined in spec + * + * NB: This is in a tightly packed area so it can be read directly, be + * careful it doesn't become padded to the next \c uint32_t boundary. + */ +attr_tiledesc_t :: struct #packed { + x_size: u32, + y_size: u32, + level_and_round: u8, +} + +/** @brief Macro to access type of tiling from packed structure. */ +GET_TILE_LEVEL_MODE :: #force_inline proc "c" (tiledesc: attr_tiledesc_t) -> tile_level_mode_t { + return tile_level_mode_t(tiledesc.level_and_round & 0xf) +} +/** @brief Macro to access the rounding mode of tiling from packed structure. */ +GET_TILE_ROUND_MODE :: #force_inline proc "c" (tiledesc: attr_tiledesc_t) -> tile_round_mode_t { + return tile_round_mode_t((tiledesc.level_and_round >> 4) & 0xf) +} +/** @brief Macro to pack the tiling type and rounding mode into packed structure. */ +PACK_TILE_LEVEL_ROUND :: #force_inline proc "c" (lvl: tile_level_mode_t, mode: tile_round_mode_t) -> u8 { + return ((u8(mode) & 0xf) << 4) | (u8(lvl) & 0xf) +} + + +/* /////////////////////////////////////// */ +/* Now structs that involve heap allocation to store data. */ + +/** Storage for a string. */ +attr_string_t :: struct { + length: i32, + /** If this is non-zero, the string owns the data, if 0, is a const ref to a static string. */ + alloc_size: i32, + + str: cstring, +} + +/** Storage for a string vector. */ +attr_string_vector_t :: struct { + n_strings: i32, + /** If this is non-zero, the string vector owns the data, if 0, is a const ref. */ + alloc_size: i32, + + strings: [^]attr_string_t, +} + +/** Float vector storage struct. */ +attr_float_vector_t :: struct { + length: i32, + /** If this is non-zero, the float vector owns the data, if 0, is a const ref. */ + alloc_size: i32, + + arr: [^]f32, +} + +/** Hint for lossy compression methods about how to treat values + * (logarithmic or linear), meaning a human sees values like R, G, B, + * luminance difference between 0.1 and 0.2 as about the same as 1.0 + * to 2.0 (logarithmic), where chroma coordinates are closer to linear + * (0.1 and 0.2 is about the same difference as 1.0 and 1.1). + */ +perceptual_treatment_t :: enum c.int { + LOGARITHMIC = 0, + LINEAR = 1, +} + +/** Individual channel information. */ +attr_chlist_entry_t :: struct { + name: attr_string_t, + /** Data representation for these pixels: uint, half, float. */ + pixel_type: pixel_type_t, + /** Possible values are 0 and 1 per docs perceptual_treatment_t. */ + p_linear: u8, + reserved: [3]u8, + x_sampling: i32, + y_sampling: i32, +} + +/** List of channel information (sorted alphabetically). */ +attr_chlist_t :: struct { + num_channels: c.int, + num_alloced: c.int, + + entries: [^]attr_chlist_entry_t, +} + +/** @brief Struct to define attributes of an embedded preview image. */ +attr_preview_t :: struct { + width: u32, + height: u32, + /** If this is non-zero, the preview owns the data, if 0, is a const ref. */ + alloc_size: c.size_t, + + rgba: [^]u8, +} + +/** Custom storage structure for opaque data. + * + * Handlers for opaque types can be registered, then when a + * non-builtin type is encountered with a registered handler, the + * function pointers to unpack/pack it will be set up. + * + * @sa register_attr_type_handler + */ +attr_opaquedata_t :: struct { + size: i32, + unpacked_size: i32, + /** If this is non-zero, the struct owns the data, if 0, is a const ref. */ + packed_alloc_size: i32, + pad: [4]u8, + + packed_data: rawptr, + + /** When an application wants to have custom data, they can store + * an unpacked form here which will be requested to be destroyed + * upon destruction of the attribute. + */ + unpacked_data: rawptr, + + /** An application can register an attribute handler which then + * fills in these function pointers. This allows a user to delay + * the expansion of the custom type until access is desired, and + * similarly, to delay the packing of the data until write time. + */ + unpack_func_ptr: proc "c" ( + ctxt: context_t, + data: rawptr, + attrsize: i32, + outsize: ^i32, + outbuffer: ^rawptr) -> result_t, + pack_func_ptr: proc "c" ( + ctxt: context_t, + data: rawptr, + datasize: i32, + outsize: ^i32, + outbuffer: rawptr) -> result_t, + destroy_unpacked_func_ptr: proc "c" ( + ctxt: context_t, data: rawptr, attrsize: i32), +} + +/* /////////////////////////////////////// */ + +/** @brief Built-in/native attribute type enum. + * + * This will enable us to do a tagged type struct to generically store + * attributes. + */ +attribute_type_t :: enum c.int { + UNKNOWN = 0, // Type indicating an error or uninitialized attribute. + BOX2I, // Integer region definition. @see attr_box2i_t. + BOX2F, // Float region definition. @see attr_box2f_t. + CHLIST, // Definition of channels in file @see chlist_entry. + CHROMATICITIES, // Values to specify color space of colors in file @see attr_chromaticities_t. + COMPRESSION, // ``u8`` declaring compression present. + DOUBLE, // Double precision floating point number. + ENVMAP, // ``u8`` declaring environment map type. + FLOAT, // Normal (4 byte) precision floating point number. + FLOAT_VECTOR, // List of normal (4 byte) precision floating point numbers. + INT, // 32-bit signed integer value. + KEYCODE, // Struct recording keycode @see attr_keycode_t. + LINEORDER, // ``u8`` declaring scanline ordering. + M33F, // 9 32-bit floats representing a 3x3 matrix. + M33D, // 9 64-bit floats representing a 3x3 matrix. + M44F, // 16 32-bit floats representing a 4x4 matrix. + M44D, // 16 64-bit floats representing a 4x4 matrix. + PREVIEW, // 2 ``unsigned ints`` followed by 4 x w x h ``u8`` image. + RATIONAL, // \c int followed by ``unsigned int`` + STRING, // ``int`` (length) followed by char string data. + STRING_VECTOR, // 0 or more text strings (int + string). number is based on attribute size. + TILEDESC, // 2 ``unsigned ints`` ``xSize``, ``ySize`` followed by mode. + TIMECODE, // 2 ``unsigned ints`` time and flags, user data. + V2I, // Pair of 32-bit integers. + V2F, // Pair of 32-bit floats. + V2D, // Pair of 64-bit floats. + V3I, // Set of 3 32-bit integers. + V3F, // Set of 3 32-bit floats. + V3D, // Set of 3 64-bit floats. + OPAQUE, // User/unknown provided type. +} + +/** @brief Storage, name and type information for an attribute. + * + * Attributes (metadata) for the file cause a surprising amount of + * overhead. It is not uncommon for a production-grade EXR to have + * many attributes. As such, the attribute struct is designed in a + * slightly more complicated manner. It is optimized to have the + * storage for that attribute: the struct itself, the name, the type, + * and the data all allocated as one block. Further, the type and + * standard names may use a static string to avoid allocating space + * for those as necessary with the pointers pointing to static strings + * (not to be freed). Finally, small values are optimized for. + */ +attribute_t :: struct { + /** Name of the attribute. */ + name: cstring, + /** String type name of the attribute. */ + type_name: cstring, + /** Length of name string (short flag is 31 max, long allows 255). */ + name_length: u8, + /** Length of type string (short flag is 31 max, long allows 255). */ + type_name_length: u8, + + pad: [2]u8, + + /** Enum of the attribute type. */ + type: attribute_type_t, + + /** Union of pointers of different types that can be used to type + * pun to an appropriate type for builtins. Do note that while + * this looks like a big thing, it is only the size of a single + * pointer. These are all pointers into some other data block + * storing the value you want, with the exception of the pod types + * which are just put in place (i.e. small value optimization). + * + * The attribute type \c type should directly correlate to one + * of these entries. + */ + using _: struct #raw_union { + // NB: not pointers for POD types + uc: u8, + d: f64, + f: f32, + i: i32, + + box2i: ^attr_box2i_t, + box2f: ^attr_box2f_t, + chlist: ^attr_chlist_t, + chromaticities: ^attr_chromaticities_t, + keycode: ^attr_keycode_t, + floatvector: ^attr_float_vector_t, + m33f: ^attr_m33f_t, + m33d: ^attr_m33d_t, + m44f: ^attr_m44f_t, + m44d: ^attr_m44d_t, + preview: ^attr_preview_t, + rational: ^attr_rational_t, + string: ^attr_string_t, + stringvector: ^attr_string_vector_t, + tiledesc: ^attr_tiledesc_t, + timecode: ^attr_timecode_t, + v2i: ^attr_v2i_t, + v2f: ^attr_v2f_t, + v2d: ^attr_v2d_t, + v3i: ^attr_v3i_t, + v3f: ^attr_v3f_t, + v3d: ^attr_v3d_t, + opaque: ^attr_opaquedata_t, + rawptr: ^u8, + }, +} \ No newline at end of file diff --git a/vendor/openexr/exr_base.odin b/vendor/openexr/exr_base.odin new file mode 100644 index 000000000..0db4cc7ff --- /dev/null +++ b/vendor/openexr/exr_base.odin @@ -0,0 +1,170 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +/** @brief Function pointer used to hold a malloc-like routine. + * + * Providing these to a context will override what memory is used to + * allocate the context itself, as well as any allocations which + * happen during processing of a file or stream. This can be used by + * systems which provide rich malloc tracking routines to override the + * internal allocations performed by the library. + * + * This function is expected to allocate and return a new memory + * handle, or `NULL` if allocation failed (which the library will then + * handle and return an out-of-memory error). + * + * If one is provided, both should be provided. + * @sa exr_memory_free_func_t + */ +memory_allocation_func_t :: proc "c" (bytes: c.size_t) -> rawptr + +/** @brief Function pointer used to hold a free-like routine. + * + * Providing these to a context will override what memory is used to + * allocate the context itself, as well as any allocations which + * happen during processing of a file or stream. This can be used by + * systems which provide rich malloc tracking routines to override the + * internal allocations performed by the library. + * + * This function is expected to return memory to the system, ala free + * from the C library. + * + * If providing one, probably need to provide both routines. + * @sa exr_memory_allocation_func_t + */ +memory_free_func_t :: proc "c" (ptr: rawptr) + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** @brief Retrieve the current library version. The @p extra string is for + * custom installs, and is a static string, do not free the returned + * pointer. + */ + get_library_version :: proc(maj, min, patch: ^c.int, extra: ^cstring) --- + + /** @brief Limit the size of image allowed to be parsed or created by + * the library. + * + * This is used as a safety check against corrupt files, but can also + * serve to avoid potential issues on machines which have very + * constrained RAM. + * + * These values are among the only globals in the core layer of + * OpenEXR. The intended use is for applications to define a global + * default, which will be combined with the values provided to the + * individual context creation routine. The values are used to check + * against parsed header values. This adds some level of safety from + * memory overruns where a corrupt file given to the system may cause + * a large allocation to happen, enabling buffer overruns or other + * potential security issue. + * + * These global values are combined with the values in + * \ref exr_context_initializer_t using the following rules: + * + * 1. negative values are ignored. + * + * 2. if either value has a positive (non-zero) value, and the other + * has 0, the positive value is preferred. + * + * 3. If both are positive (non-zero), the minimum value is used. + * + * 4. If both values are 0, this disables the constrained size checks. + * + * This function does not fail. + */ + set_default_maximum_image_size :: proc(w, h: c.int) --- + + /** @brief Retrieve the global default maximum image size. + * + * This function does not fail. + */ + get_default_maximum_image_size :: proc(w, h: ^c.int) --- + + /** @brief Limit the size of an image tile allowed to be parsed or + * created by the library. + * + * Similar to image size, this places constraints on the maximum tile + * size as a safety check against bad file data + * + * This is used as a safety check against corrupt files, but can also + * serve to avoid potential issues on machines which have very + * constrained RAM + * + * These values are among the only globals in the core layer of + * OpenEXR. The intended use is for applications to define a global + * default, which will be combined with the values provided to the + * individual context creation routine. The values are used to check + * against parsed header values. This adds some level of safety from + * memory overruns where a corrupt file given to the system may cause + * a large allocation to happen, enabling buffer overruns or other + * potential security issue. + * + * These global values are combined with the values in + * \ref exr_context_initializer_t using the following rules: + * + * 1. negative values are ignored. + * + * 2. if either value has a positive (non-zero) value, and the other + * has 0, the positive value is preferred. + * + * 3. If both are positive (non-zero), the minimum value is used. + * + * 4. If both values are 0, this disables the constrained size checks. + * + * This function does not fail. + */ + set_default_maximum_tile_size :: proc(w, h: c.int) --- + + /** @brief Retrieve the global maximum tile size. + * + * This function does not fail. + */ + get_default_maximum_tile_size :: proc(w, h: ^c.int) --- + + /** @} */ + + /** + * @defgroup CompressionDefaults Provides default compression settings + * @{ + */ + + /** @brief Assigns a default zip compression level. + * + * This value may be controlled separately on each part, but this + * global control determines the initial value. + */ + set_default_zip_compression_level :: proc(l: c.int) --- + + /** @brief Retrieve the global default zip compression value + */ + get_default_zip_compression_level :: proc(l: ^c.int) --- + + /** @brief Assigns a default DWA compression quality level. + * + * This value may be controlled separately on each part, but this + * global control determines the initial value. + */ + set_default_dwa_compression_quality :: proc(q: f32) --- + + /** @brief Retrieve the global default dwa compression quality + */ + get_default_dwa_compression_quality :: proc(q: ^f32) --- + + /** @brief Allow the user to override default allocator used internal + * allocations necessary for files, attributes, and other temporary + * memory. + * + * These routines may be overridden when creating a specific context, + * however this provides global defaults such that the default can be + * applied. + * + * If either pointer is 0, the appropriate malloc/free routine will be + * substituted. + * + * This function does not fail. + */ + set_default_memory_routines :: proc(alloc_func: memory_allocation_func_t, free_func: memory_free_func_t) --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_chunkio.odin b/vendor/openexr/exr_chunkio.odin new file mode 100644 index 000000000..612db2cb3 --- /dev/null +++ b/vendor/openexr/exr_chunkio.odin @@ -0,0 +1,143 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +/** + * Struct describing raw data information about a chunk. + * + * A chunk is the generic term for a pixel data block in an EXR file, + * as described in the OpenEXR File Layout documentation. This is + * common between all different forms of data that can be stored. + */ +chunk_info_t :: struct { + idx: i32, + + /** For tiles, this is the tilex; for scans it is the x. */ + start_x: i32, + /** For tiles, this is the tiley; for scans it is the scanline y. */ + start_y: i32, + height: i32, /**< For this chunk. */ + width: i32, /**< For this chunk. */ + + level_x: u8, /**< For tiled files. */ + level_y: u8, /**< For tiled files. */ + + type: u8, + compression: u8, + + data_offset: u64, + packed_size: u64, + unpacked_size: u64, + + sample_count_data_offset: u64, + sample_count_table_size: u64, +} + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + read_scanline_chunk_info :: proc(ctxt: const_context_t, part_index: c.int, y: c.int, cinfo: ^chunk_info_t) -> result_t --- + + read_tile_chunk_info :: proc( + ctxt: const_context_t, + part_index: c.int, + tilex: c.int, + tiley: c.int, + levelx: c.int, + levely: c.int, + cinfo: ^chunk_info_t) -> result_t --- + + /** Read the packed data block for a chunk. + * + * This assumes that the buffer pointed to by @p packed_data is + * large enough to hold the chunk block info packed_size bytes. + */ + read_chunk :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + packed_data: rawptr) -> result_t --- + + /** + * Read chunk for deep data. + * + * This allows one to read the packed data, the sample count data, or both. + * \c exr_read_chunk also works to read deep data packed data, + * but this is a routine to get the sample count table and the packed + * data in one go, or if you want to pre-read the sample count data, + * you can get just that buffer. + */ + read_deep_chunk :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + packed_data: rawptr, + sample_data: rawptr) -> result_t --- + + /**************************************/ + + /** Initialize a \c chunk_info_t structure when encoding scanline + * data (similar to read but does not do anything with a chunk + * table). + */ + write_scanline_chunk_info :: proc(ctxt: context_t, part_index: c.int, y: c.int, cinfo: ^chunk_info_t) -> result_t --- + + /** Initialize a \c chunk_info_t structure when encoding tiled data + * (similar to read but does not do anything with a chunk table). + */ + write_tile_chunk_info :: proc( + ctxt: context_t, + part_index: c.int, + tilex: c.int, + tiley: c.int, + levelx: c.int, + levely: c.int, + cinfo: ^chunk_info_t) -> result_t --- + + /** + * @p y must the appropriate starting y for the specified chunk. + */ + write_scanline_chunk :: proc( + ctxt: context_t, + part_index: int, + y: int, + packed_data: rawptr, + packed_size: u64) -> result_t --- + + /** + * @p y must the appropriate starting y for the specified chunk. + */ + write_deep_scanline_chunk :: proc( + ctxt: context_t, + part_index: c.int, + y: c.int, + packed_data: rawptr, + packed_size: u64, + unpacked_size: u64, + sample_data: rawptr, + sample_data_size: u64) -> result_t --- + + write_tile_chunk :: proc( + ctxt: context_t, + part_index: c.int, + tilex: c.int, + tiley: c.int, + levelx: c.int, + levely: c.int, + packed_data: rawptr, + packed_size: u64) -> result_t --- + + write_deep_tile_chunk :: proc( + ctxt: context_t, + part_index: c.int, + tilex: c.int, + tiley: c.int, + levelx: c.int, + levely: c.int, + packed_data: rawptr, + packed_size: u64, + unpacked_size: u64, + sample_data: rawptr, + sample_data_size: u64) -> result_t --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_coding.odin b/vendor/openexr/exr_coding.odin new file mode 100644 index 000000000..337475edf --- /dev/null +++ b/vendor/openexr/exr_coding.odin @@ -0,0 +1,119 @@ +package vendor_openexr + +import "core:c" +/** + * Enum for use in a custom allocator in the encode/decode pipelines + * (that is, so the implementor knows whether to allocate on which + * device based on the buffer disposition). + */ +transcoding_pipeline_buffer_id_t :: enum c.int { + PACKED, + UNPACKED, + COMPRESSED, + SCRATCH1, + SCRATCH2, + PACKED_SAMPLES, + SAMPLES, +} + +/** @brief Struct for negotiating buffers when decoding/encoding + * chunks of data. + * + * This is generic and meant to negotiate exr data bi-directionally, + * in that the same structure is used for both decoding and encoding + * chunks for read and write, respectively. + * + * The first half of the structure will be filled by the library, and + * the caller is expected to fill the second half appropriately. + */ +coding_channel_info_t :: struct { + /************************************************** + * Elements below are populated by the library when + * decoding is initialized/updated and must be left + * untouched when using the default decoder routines. + **************************************************/ + + /** Channel name. + * + * This is provided as a convenient reference. Do not free, this + * refers to the internal data structure in the context. + */ + channel_name: cstring, + + /** Number of lines for this channel in this chunk. + * + * May be 0 or less than overall image height based on sampling + * (i.e. when in 4:2:0 type sampling) + */ + height: i32, + + /** Width in pixel count. + * + * May be 0 or less than overall image width based on sampling + * (i.e. 4:2:2 will have some channels have fewer values). + */ + width: i32, + + /** Horizontal subsampling information. */ + x_samples: i32, + /** Vertical subsampling information. */ + y_samples: i32, + + /** Linear flag from channel definition (used by b44). */ + p_linear: u8, + + /** How many bytes per pixel this channel consumes (2 for float16, + * 4 for float32/uint32). + */ + bytes_per_element: i8, + + /** Small form of exr_pixel_type_t enum (EXR_PIXEL_UINT/HALF/FLOAT). */ + data_type: u16, + + /************************************************** + * Elements below must be edited by the caller + * to control encoding/decoding. + **************************************************/ + + /** How many bytes per pixel the input is or output should be + * (2 for float16, 4 for float32/uint32). Defaults to same + * size as input. + */ + user_bytes_per_element: i16, + + /** Small form of exr_pixel_type_t enum + * (EXR_PIXEL_UINT/HALF/FLOAT). Defaults to same type as input. + */ + user_data_type: u16, + + /** Increment to get to next pixel. + * + * This is in bytes. Must be specified when the decode pointer is + * specified (and always for encode). + * + * This is useful for implementing transcoding generically of + * planar or interleaved data. For planar data, where the layout + * is RRRRRGGGGGBBBBB, you can pass in 1 * bytes per component. + */ + + user_pixel_stride: i32, + + /** When \c lines > 1 for a chunk, this is the increment used to get + * from beginning of line to beginning of next line. + * + * This is in bytes. Must be specified when the decode pointer is + * specified (and always for encode). + */ + user_line_stride: i32, + + /** This data member has different requirements reading vs + * writing. When reading, if this is left as `NULL`, the channel + * will be skipped during read and not filled in. During a write + * operation, this pointer is considered const and not + * modified. To make this more clear, a union is used here. + */ + using _: struct #raw_union { + decode_to_ptr: ^u8, + encode_from_ptr: ^u8, + }, +} diff --git a/vendor/openexr/exr_context.odin b/vendor/openexr/exr_context.odin new file mode 100644 index 000000000..958e30490 --- /dev/null +++ b/vendor/openexr/exr_context.odin @@ -0,0 +1,485 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +#assert(size_of(c.int) == size_of(b32)) + +context_t :: distinct rawptr +const_context_t :: context_t + +/** + * @defgroup ContextFunctions OpenEXR Context Stream/File Functions + * + * @brief These are a group of function interfaces used to customize + * the error handling, memory allocations, or I/O behavior of an + * OpenEXR context. + * + * @{ + */ + +/** @brief Stream error notifier + * + * This function pointer is provided to the stream functions by the + * library such that they can provide a nice error message to the + * user during stream operations. + */ +stream_error_func_ptr_t :: proc "c" (ctxt: const_context_t, code: result_t, fmt: cstring, #c_vararg args: ..any) -> result_t + +/** @brief Error callback function + * + * Because a file can be read from using many threads at once, it is + * difficult to store an error message for later retrieval. As such, + * when a file is constructed, a callback function can be provided + * which delivers an error message for the calling application to + * handle. This will then be delivered on the same thread causing the + * error. + */ +error_handler_cb_t :: proc "c" (ctxt: const_context_t, code: result_t, msg: cstring) + +/** Destroy custom stream function pointer + * + * Generic callback to clean up user data for custom streams. + * This is called when the file is closed and expected not to + * error. + * + * @param failed Indicates the write operation failed, the + * implementor may wish to cleanup temporary files + */ +destroy_stream_func_ptr_t :: proc "c" (ctxt: const_context_t, userdata: rawptr, failed: c.int) + +/** Query stream size function pointer + * + * Used to query the size of the file, or amount of data representing + * the openexr file in the data stream. + * + * This is used to validate requests against the file. If the size is + * unavailable, return -1, which will disable these validation steps + * for this file, although appropriate memory safeguards must be in + * place in the calling application. + */ +query_size_func_ptr_t :: proc "c" (ctxt: const_context_t, userdata: rawptr) -> i64 + +/** @brief Read custom function pointer + * + * Used to read data from a custom output. Expects similar semantics to + * pread or ReadFile with overlapped data under win32. + * + * It is required that this provides thread-safe concurrent access to + * the same file. If the stream/input layer you are providing does + * not have this guarantee, your are responsible for providing + * appropriate serialization of requests. + * + * A file should be expected to be accessed in the following pattern: + * - upon open, the header and part information attributes will be read + * - upon the first image read request, the offset tables will be read + * multiple threads accessing this concurrently may actually read + * these values at the same time + * - chunks can then be read in any order as preferred by the + * application + * + * While this should mean that the header will be read in 'stream' + * order (no seeks required), no guarantee is made beyond that to + * retrieve image/deep data in order. So if the backing file is + * truly a stream, it is up to the provider to implement appropriate + * caching of data to give the appearance of being able to seek/read + * atomically. + */ +read_func_ptr_t :: proc "c" ( + ctxt: const_context_t, + userdata: rawptr, + buffer: rawptr, + sz: u64, + offset: u64, + error_cb: stream_error_func_ptr_t) -> i64 + +/** Write custom function pointer + * + * Used to write data to a custom output. Expects similar semantics to + * pwrite or WriteFile with overlapped data under win32. + * + * It is required that this provides thread-safe concurrent access to + * the same file. While it is unlikely that multiple threads will + * be used to write data for compressed forms, it is possible. + * + * A file should be expected to be accessed in the following pattern: + * - upon open, the header and part information attributes is constructed. + * + * - when the write_header routine is called, the header becomes immutable + * and is written to the file. This computes the space to store the chunk + * offsets, but does not yet write the values. + * + * - Image chunks are written to the file, and appear in the order + * they are written, not in the ordering that is required by the + * chunk offset table (unless written in that order). This may vary + * slightly if the size of the chunks is not directly known and + * tight packing of data is necessary. + * + * - at file close, the chunk offset tables are written to the file. + */ +write_func_ptr_t :: proc "c" ( + ctxt: const_context_t, + userdata: rawptr, + buffer: rawptr, + sz: u64, + offset: u64, + error_cb: stream_error_func_ptr_t) -> i64 + +/** @brief Struct used to pass function pointers into the context + * initialization routines. + * + * This partly exists to avoid the chicken and egg issue around + * creating the storage needed for the context on systems which want + * to override the malloc/free routines. + * + * However, it also serves to make a tidier/simpler set of functions + * to create and start processing exr files. + * + * The size member is required for version portability. + * + * It can be initialized using \c EXR_DEFAULT_CONTEXT_INITIALIZER. + * + * \code{.c} + * exr_context_initializer_t myctxtinit = DEFAULT_CONTEXT_INITIALIZER; + * myctxtinit.error_cb = &my_super_cool_error_callback_function; + * ... + * \endcode + * + */ +context_initializer_t :: struct { + /** @brief Size member to tag initializer for version stability. + * + * This should be initialized to the size of the current + * structure. This allows EXR to add functions or other + * initializers in the future, and retain version compatibility + */ + size: c.size_t, + + /** @brief Error callback function pointer + * + * The error callback is allowed to be `NULL`, and will use a + * default print which outputs to \c stderr. + * + * @sa exr_error_handler_cb_t + */ + error_handler_fn: error_handler_cb_t, + + /** Custom allocator, if `NULL`, will use malloc. @sa memory_allocation_func_t */ + alloc_fn: memory_allocation_func_t, + + /** Custom deallocator, if `NULL`, will use free. @sa memory_free_func_t */ + free_fn: memory_free_func_t, + + /** Blind data passed to custom read, size, write, destroy + * functions below. Up to user to manage this pointer. + */ + user_data: rawptr, + + /** @brief Custom read routine. + * + * This is only used during read or update contexts. If this is + * provided, it is expected that the caller has previously made + * the stream available, and placed whatever stream/file data + * into \c user_data above. + * + * If this is `NULL`, and the context requested is for reading an + * exr file, an internal implementation is provided for reading + * from normal filesystem files, and the filename provided is + * attempted to be opened as such. + * + * Expected to be `NULL` for a write-only operation, but is ignored + * if it is provided. + * + * For update contexts, both read and write functions must be + * provided if either is. + * + * @sa exr_read_func_ptr_t + */ + read_fn: read_func_ptr_t, + + /** @brief Custom size query routine. + * + * Used to provide validation when reading header values. If this + * is not provided, but a custom read routine is provided, this + * will disable some of the validation checks when parsing the + * image header. + * + * Expected to be `NULL` for a write-only operation, but is ignored + * if it is provided. + * + * @sa exr_query_size_func_ptr_t + */ + size_fn: query_size_func_ptr_t, + + /** @brief Custom write routine. + * + * This is only used during write or update contexts. If this is + * provided, it is expected that the caller has previously made + * the stream available, and placed whatever stream/file data + * into \c user_data above. + * + * If this is `NULL`, and the context requested is for writing an + * exr file, an internal implementation is provided for reading + * from normal filesystem files, and the filename provided is + * attempted to be opened as such. + * + * For update contexts, both read and write functions must be + * provided if either is. + * + * @sa exr_write_func_ptr_t + */ + write_fn: write_func_ptr_t, + + /** @brief Optional function to destroy the user data block of a custom stream. + * + * Allows one to free any user allocated data, and close any handles. + * + * @sa exr_destroy_stream_func_ptr_t + * */ + destroy_fn: destroy_stream_func_ptr_t, + + /** Initialize a field specifying what the maximum image width + * allowed by the context is. See exr_set_default_maximum_image_size() to + * understand how this interacts with global defaults. + */ + max_image_width: c.int, + + /** Initialize a field specifying what the maximum image height + * allowed by the context is. See exr_set_default_maximum_image_size() to + * understand how this interacts with global defaults. + */ + max_image_height: c.int, + + /** Initialize a field specifying what the maximum tile width + * allowed by the context is. See exr_set_default_maximum_tile_size() to + * understand how this interacts with global defaults. + */ + max_tile_width: c.int, + + /** Initialize a field specifying what the maximum tile height + * allowed by the context is. See exr_set_default_maximum_tile_size() to + * understand how this interacts with global defaults. + */ + max_tile_height: c.int, + + /** Initialize a field specifying what the default zip compression level should be + * for this context. See exr_set_default_zip_compresion_level() to + * set it for all contexts. + */ + zip_level: c.int, + + /** Initialize the default dwa compression quality. See + * exr_set_default_dwa_compression_quality() to set the default + * for all contexts. + */ + dwa_quality: f32, + + /** Initialize with a bitwise or of the various context flags + */ + flags: c.int, +} + +/** @brief context flag which will enforce strict header validation + * checks and may prevent reading of files which could otherwise be + * processed. + */ +CONTEXT_FLAG_STRICT_HEADER :: (1 << 0) + +/** @brief Disables error messages while parsing headers + * + * The return values will remain the same, but error reporting will be + * skipped. This is only valid for reading contexts + */ +CONTEXT_FLAG_SILENT_HEADER_PARSE :: (1 << 1) + +/** @brief Disables reconstruction logic upon corrupt / missing data chunks + * + * This will disable the reconstruction logic that searches through an + * incomplete file, and will instead just return errors at read + * time. This is only valid for reading contexts + */ +CONTEXT_FLAG_DISABLE_CHUNK_RECONSTRUCTION :: (1 << 2) + +/** @brief Simple macro to initialize the context initializer with default values. */ +DEFAULT_CONTEXT_INITIALIZER :: context_initializer_t{zip_level = -2, dwa_quality = -1} + +/** @} */ /* context function pointer declarations */ + + +/** @brief Enum describing how default files are handled during write. */ +default_write_mode_t :: enum c.int { + WRITE_FILE_DIRECTLY = 0, /**< Overwrite filename provided directly, deleted upon error. */ + INTERMEDIATE_TEMP_FILE = 1, /**< Create a temporary file, renaming it upon successful write, leaving original upon error */ +} + + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** @brief Check the magic number of the file and report + * `EXR_ERR_SUCCESS` if the file appears to be a valid file (or at least + * has the correct magic number and can be read). + */ + test_file_header :: proc(filename: cstring, ctxtdata: ^context_initializer_t) -> result_t --- + + /** @brief Close and free any internally allocated memory, + * calling any provided destroy function for custom streams. + * + * If the file was opened for write, first save the chunk offsets + * or any other unwritten data. + */ + finish :: proc(ctxt: ^context_t) -> result_t --- + + /** @brief Create and initialize a read-only exr read context. + * + * If a custom read function is provided, the filename is for + * informational purposes only, the system assumes the user has + * previously opened a stream, file, or whatever and placed relevant + * data in userdata to access that. + * + * One notable attribute of the context is that once it has been + * created and returned a successful code, it has parsed all the + * header data. This is done as one step such that it is easier to + * provide a safe context for multiple threads to request data from + * the same context concurrently. + * + * Once finished reading data, use exr_finish() to clean up + * the context. + * + * If you have custom I/O requirements, see the initializer context + * documentation \ref exr_context_initializer_t. The @p ctxtdata parameter + * is optional, if `NULL`, default values will be used. + */ + start_read :: proc( + ctxt: ^context_t, + filename: cstring, + ctxtdata: ^context_initializer_t) -> result_t --- + + /** @brief Create and initialize a write-only context. + * + * If a custom write function is provided, the filename is for + * informational purposes only, and the @p default_mode parameter will be + * ignored. As such, the system assumes the user has previously opened + * a stream, file, or whatever and placed relevant data in userdata to + * access that. + * + * Multi-Threading: To avoid issues with creating multi-part EXR + * files, the library approaches writing as a multi-step process, so + * the same concurrent guarantees can not be made for writing a + * file. The steps are: + * + * 1. Context creation (this function) + * + * 2. Part definition (required attributes and additional metadata) + * + * 3. Transition to writing data (this "commits" the part definitions, + * any changes requested after will result in an error) + * + * 4. Write part data in sequential order of parts (part0 + * -> partN-1). + * + * 5. Within each part, multiple threads can be encoding and writing + * data concurrently. For some EXR part definitions, this may be able + * to write data concurrently when it can predict the chunk sizes, or + * data is allowed to be padded. For others, it may need to + * temporarily cache chunks until the data is received to flush in + * order. The concurrency around this is handled by the library + * + * 6. Once finished writing data, use exr_finish() to clean + * up the context, which will flush any unwritten data such as the + * final chunk offset tables, and handle the temporary file flags. + * + * If you have custom I/O requirements, see the initializer context + * documentation \ref exr_context_initializer_t. The @p ctxtdata + * parameter is optional, if `NULL`, default values will be used. + */ + start_write :: proc( + ctxt: ^context_t, + filename: cstring, + default_mode: default_write_mode_t, + ctxtdata: ^context_initializer_t) -> result_t --- + + /** @brief Create a new context for updating an exr file in place. + * + * This is a custom mode that allows one to modify the value of a + * metadata entry, although not to change the size of the header, or + * any of the image data. + * + * If you have custom I/O requirements, see the initializer context + * documentation \ref exr_context_initializer_t. The @p ctxtdata parameter + * is optional, if `NULL`, default values will be used. + */ + start_inplace_header_update :: proc( + ctxt: ^context_t, + filename: cstring, + ctxtdata: ^context_initializer_t) -> result_t --- + + /** @brief Retrieve the file name the context is for as provided + * during the start routine. + * + * Do not free the resulting string. + */ + + get_file_name :: proc(ctxt: const_context_t, name: ^cstring) -> result_t --- + + /** @brief Query the user data the context was constructed with. This + * is perhaps useful in the error handler callback to jump back into + * an object the user controls. + */ + + get_user_data :: proc(ctxt: const_context_t, userdata: ^rawptr) -> result_t --- + + /** Any opaque attribute data entry of the specified type is tagged + * with these functions enabling downstream users to unpack (or pack) + * the data. + * + * The library handles the memory packed data internally, but the + * handler is expected to allocate and manage memory for the + * *unpacked* buffer (the library will call the destroy function). + * + * NB: the pack function will be called twice (unless there is a + * memory failure), the first with a `NULL` buffer, requesting the + * maximum size (or exact size if known) for the packed buffer, then + * the second to fill the output packed buffer, at which point the + * size can be re-updated to have the final, precise size to put into + * the file. + */ + register_attr_type_handler :: proc( + ctxt: context_t, + type: cstring, + unpack_func_ptr: proc "c" ( + ctxt: context_t, + data: rawptr, + attrsize: i32, + outsize: ^i32, + outbuffer: ^rawptr) -> result_t, + pack_func_ptr: proc "c" ( + ctxt: context_t, + data: rawptr, + datasize: i32, + outsize: ^i32, + outbuffer: rawptr) -> result_t, + destroy_unpacked_func_ptr: proc "c" ( + ctxt: context_t, data: rawptr, datasize: i32), + ) -> result_t --- + + /** @brief Enable long name support in the output context */ + + set_longname_support :: proc(ctxt: context_t, onoff: b32) -> result_t --- + + /** @brief Write the header data. + * + * Opening a new output file has a small initialization state problem + * compared to opening for read/update: we need to enable the user + * to specify an arbitrary set of metadata across an arbitrary number + * of parts. To avoid having to create the list of parts and entire + * metadata up front, prior to calling the above exr_start_write(), + * allow the data to be set, then once this is called, it switches + * into a mode where the library assumes the data is now valid. + * + * It will recompute the number of chunks that will be written, and + * reset the chunk offsets. If you modify file attributes or part + * information after a call to this, it will error. + */ + write_header :: proc(ctxt: context_t) -> result_t --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_debug.odin b/vendor/openexr/exr_debug.odin new file mode 100644 index 000000000..f2c8e18cb --- /dev/null +++ b/vendor/openexr/exr_debug.odin @@ -0,0 +1,8 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + print_context_info :: proc(c: const_context_t, verbose: b32) -> result_t --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_decode.odin b/vendor/openexr/exr_decode.odin new file mode 100644 index 000000000..7eca819f7 --- /dev/null +++ b/vendor/openexr/exr_decode.odin @@ -0,0 +1,288 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +/** Can be bit-wise or'ed into the decode_flags in the decode pipeline. + * + * Indicates that the sample count table should be decoded to a an + * individual sample count list (n, m, o, ...), with an extra int at + * the end containing the total samples. + * + * Without this (i.e. a value of 0 in that bit), indicates the sample + * count table should be decoded to a cumulative list (n, n+m, n+m+o, + * ...), which is the on-disk representation. + */ +DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL :: u16(1 << 0) + +/** Can be bit-wise or'ed into the decode_flags in the decode pipeline. + * + * Indicates that the data in the channel pointers to decode to is not + * a direct pointer, but instead is a pointer-to-pointers. In this + * mode, the user_pixel_stride and user_line_stride are used to + * advance the pointer offsets for each pixel in the output, but the + * user_bytes_per_element and user_data_type are used to put + * (successive) entries into each destination pointer (if not `NULL`). + * + * So each channel pointer must then point to an array of + * chunk.width * chunk.height pointers. + * + * With this, you can only extract desired pixels (although all the + * pixels must be initially decompressed) to handle such operations + * like proxying where you might want to read every other pixel. + * + * If this is NOT set (0), the default unpacking routine assumes the + * data will be planar and contiguous (each channel is a separate + * memory block), ignoring user_line_stride and user_pixel_stride. + */ +DECODE_NON_IMAGE_DATA_AS_POINTERS :: u16(1 << 1) + +/** + * When reading non-image data (i.e. deep), only read the sample table. + */ +DECODE_SAMPLE_DATA_ONLY :: u16(1 << 2) + +/** + * Struct meant to be used on a per-thread basis for reading exr data + * + * As should be obvious, this structure is NOT thread safe, but rather + * meant to be used by separate threads, which can all be accessing + * the same context concurrently. + */ +decode_pipeline_t :: struct { + /** The output channel information for this chunk. + * + * User is expected to fill the channel pointers for the desired + * output channels (any that are `NULL` will be skipped) if you are + * going to use exr_decoding_choose_default_routines(). If all that is + * desired is to read and decompress the data, this can be left + * uninitialized. + * + * Describes the channel information. This information is + * allocated dynamically during exr_decoding_initialize(). + */ + channels: [^]coding_channel_info_t, + channel_count: i16, + + /** Decode flags to control the behavior. */ + decode_flags: u16, + + /** Copy of the parameters given to the initialize/update for + * convenience. + */ + part_index: c.int, + ctx: const_context_t, + chunk: chunk_info_t, + + /** Can be used by the user to pass custom context data through + * the decode pipeline. + */ + decoding_user_data: rawptr, + + /** The (compressed) buffer. + * + * If `NULL`, will be allocated during the run of the pipeline. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + packed_buffer: rawptr, + + /** Used when re-using the same decode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + */ + packed_alloc_size: c.size_t, + + /** The decompressed buffer (unpacked_size from the chunk block + * info), but still packed into storage order, only needed for + * compressed files. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + unpacked_buffer: rawptr, + + /** Used when re-using the same decode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + */ + unpacked_alloc_size: c.size_t, + + /** For deep or other non-image data: packed sample table + * (compressed, raw on disk representation). + */ + packed_sample_count_table: rawptr, + packed_sample_count_alloc_size: c.size_t, + + /** Usable, native sample count table. Depending on the flag set + * above, will be decoded to either a cumulative list (n, n+m, + * n+m+o, ...), or an individual table (n, m, o, ...). As an + * optimization, if the latter individual count table is chosen, + * an extra int32_t will be allocated at the end of the table to + * contain the total count of samples, so the table will be n+1 + * samples in size. + */ + sample_count_table: [^]i32, + sample_count_alloc_size: c.size_t, + + /** A scratch buffer of unpacked_size for intermediate results. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + scratch_buffer_1: rawptr, + + /** Used when re-using the same decode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + */ + scratch_alloc_size_1: c.size_t, + + /** Some decompression routines may need a second scratch buffer (zlib). + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + scratch_buffer_2: rawptr, + + /** Used when re-using the same decode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + */ + scratch_alloc_size_2: c.size_t, + + /** Enable a custom allocator for the different buffers (if + * decoding on a GPU). If `NULL`, will use the allocator from the + * context. + */ + alloc_fn: proc "c" (transcoding_pipeline_buffer_id_t, c.size_t) -> rawptr, + + /** Enable a custom allocator for the different buffers (if + * decoding on a GPU). If `NULL`, will use the allocator from the + * context. + */ + free_fn: proc "c" (transcoding_pipeline_buffer_id_t, rawptr), + + /** Function chosen to read chunk data from the context. + * + * Initialized to a default generic read routine, may be updated + * based on channel information when + * exr_decoding_choose_default_routines() is called. This is done such that + * if the file is uncompressed and the output channel data is + * planar and the same type, the read function can read straight + * into the output channels, getting closer to a zero-copy + * operation. Otherwise a more traditional read, decompress, then + * unpack pipeline will be used with a default reader. + * + * This is allowed to be overridden, but probably is not necessary + * in most scenarios. + */ + read_fn: proc "c" (pipeline: ^decode_pipeline_t) -> result_t, + + /** Function chosen based on the compression type of the part to + * decompress data. + * + * If the user has a custom decompression method for the + * compression on this part, this can be changed after + * initialization. + * + * If only compressed data is desired, then assign this to `NULL` + * after initialization. + */ + decompress_fn: proc "c" (pipeline: ^decode_pipeline_t) -> result_t, + + /** Function which can be provided if you have bespoke handling for + * non-image data and need to re-allocate the data to handle the + * about-to-be unpacked data. + * + * If left `NULL`, will assume the memory pointed to by the channel + * pointers is sufficient. + */ + realloc_nonimage_data_fn: proc "c" (pipeline: ^decode_pipeline_t) -> result_t, + + /** Function chosen based on the output layout of the channels of the part to + * decompress data. + * + * This will be `NULL` after initialization, until the user + * specifies a custom routine, or initializes the channel data and + * calls exr_decoding_choose_default_routines(). + * + * If only compressed data is desired, then leave or assign this + * to `NULL` after initialization. + */ + unpack_and_convert_fn: proc "c" (pipeline: ^decode_pipeline_t) -> result_t, + + /** Small stash of channel info values. This is faster than calling + * malloc when the channel count in the part is small (RGBAZ), + * which is super common, however if there are a large number of + * channels, it will allocate space for that, so do not rely on + * this being used. + */ + _quick_chan_store: [5]coding_channel_info_t, +} + +DECODE_PIPELINE_INITIALIZER :: decode_pipeline_t{} + + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** Initialize the decoding pipeline structure with the channel info + * for the specified part, and the first block to be read. + * + * NB: The decode->unpack_and_convert_fn field will be `NULL` after this. If that + * stage is desired, initialize the channel output information and + * call exr_decoding_choose_default_routines(). + */ + decoding_initialize :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + decode: ^decode_pipeline_t) -> result_t --- + + /** Given an initialized decode pipeline, find appropriate functions + * to read and shuffle/convert data into the defined channel outputs. + * + * Calling this is not required if custom routines will be used, or if + * just the raw compressed data is desired. Although in that scenario, + * it is probably easier to just read the chunk directly using + * exr_read_chunk(). + */ + decoding_choose_default_routines :: proc( + ctxt: const_context_t, part_index: c.int, decode: ^decode_pipeline_t) -> result_t --- + + /** Given a decode pipeline previously initialized, update it for the + * new chunk to be read. + * + * In this manner, memory buffers can be re-used to avoid continual + * malloc/free calls. Further, it allows the previous choices for + * the various functions to be quickly re-used. + */ + decoding_update :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + decode: ^decode_pipeline_t) -> result_t --- + + /** Execute the decoding pipeline. */ + decoding_run :: proc( + ctxt: const_context_t, part_index: c.int, decode: ^decode_pipeline_t) -> result_t --- + + /** Free any intermediate memory in the decoding pipeline. + * + * This does *not* free any pointers referred to in the channel info + * areas, but rather only the intermediate buffers and memory needed + * for the structure itself. + */ + decoding_destroy :: proc(ctxt: const_context_t, decode: ^decode_pipeline_t) -> result_t --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_encode.odin b/vendor/openexr/exr_encode.odin new file mode 100644 index 000000000..402aaba81 --- /dev/null +++ b/vendor/openexr/exr_encode.odin @@ -0,0 +1,319 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +/** Can be bit-wise or'ed into the decode_flags in the decode pipeline. + * + * Indicates that the sample count table should be encoded from an + * individual sample count list (n, m, o, ...), meaning it will have + * to compute the cumulative counts on the fly. + * + * Without this (i.e. a value of 0 in that bit), indicates the sample + * count table is already a cumulative list (n, n+m, n+m+o, ...), + * which is the on-disk representation. + */ +ENCODE_DATA_SAMPLE_COUNTS_ARE_INDIVIDUAL :: u16(1 << 0) + +/** Can be bit-wise or'ed into the decode_flags in the decode pipeline. + * + * Indicates that the data in the channel pointers to encode from is not + * a direct pointer, but instead is a pointer-to-pointers. In this + * mode, the user_pixel_stride and user_line_stride are used to + * advance the pointer offsets for each pixel in the output, but the + * user_bytes_per_element and user_data_type are used to put + * (successive) entries into each destination. + * + * So each channel pointer must then point to an array of + * chunk.width * chunk.height pointers. If an entry is + * `NULL`, 0 samples will be placed in the output. + * + * If this is NOT set (0), the default packing routine assumes the + * data will be planar and contiguous (each channel is a separate + * memory block), ignoring user_line_stride and user_pixel_stride and + * advancing only by the sample counts and bytes per element. + */ +ENCODE_NON_IMAGE_DATA_AS_POINTERS :: u16(1 << 1) + +/** Struct meant to be used on a per-thread basis for writing exr data. + * + * As should be obvious, this structure is NOT thread safe, but rather + * meant to be used by separate threads, which can all be accessing + * the same context concurrently. + */ + encode_pipeline_t :: struct { + /** The output channel information for this chunk. + * + * User is expected to fill the channel pointers for the input + * channels. For writing, all channels must be initialized prior + * to using exr_encoding_choose_default_routines(). If a custom pack routine + * is written, that is up to the implementor. + * + * Describes the channel information. This information is + * allocated dynamically during exr_encoding_initialize(). + */ + channels: [^]coding_channel_info_t, + channel_count: i16, + + /** Encode flags to control the behavior. */ + encode_flags: u16, + + /** Copy of the parameters given to the initialize/update for convenience. */ + part_index: c.int, + ctx: const_context_t, + chunk: chunk_info_t, + + /** Can be used by the user to pass custom context data through + * the encode pipeline. + */ + encoding_user_data: rawptr, + + /** The packed buffer where individual channels have been put into here. + * + * If `NULL`, will be allocated during the run of the pipeline. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + packed_buffer: rawptr, + + /** Differing from the allocation size, the number of actual bytes */ + packed_bytes: u64, + + /** Used when re-using the same encode pipeline struct to know if + * chunk is changed size whether current buffer is large enough + * + * If `NULL`, will be allocated during the run of the pipeline. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + packed_alloc_size: c.size_t, + + /** For deep data. NB: the members NOT const because we need to + * temporarily swap it to xdr order and restore it (to avoid a + * duplicate buffer allocation). + * + * Depending on the flag set above, will be treated either as a + * cumulative list (n, n+m, n+m+o, ...), or an individual table + * (n, m, o, ...). */ + sample_count_table: [^]i32, + + /** Allocated table size (to avoid re-allocations). Number of + * samples must always be width * height for the chunk. + */ + sample_count_alloc_size: c.size_t, + + /** Packed sample table (compressed, raw on disk representation) + * for deep or other non-image data. + */ + packed_sample_count_table: rawptr, + + /** Number of bytes to write (actual size) for the + * packed_sample_count_table. + */ + packed_sample_count_bytes: c.size_t, + + /** Allocated size (to avoid re-allocations) for the + * packed_sample_count_table. + */ + packed_sample_count_alloc_size: c.size_t, + + /** The compressed buffer, only needed for compressed files. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + compressed_buffer: rawptr, + + /** Must be filled in as the pipeline runs to inform the writing + * software about the compressed size of the chunk (if it is an + * uncompressed file or the compression would make the file + * larger, it is expected to be the packed_buffer) + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to zero here. Be cognizant of any + * custom allocators. + */ + compressed_bytes: c.size_t, + + /** Used when re-using the same encode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to zero here. Be cognizant of any + * custom allocators. + */ + compressed_alloc_size: c.size_t, + + /** A scratch buffer for intermediate results. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + scratch_buffer_1: rawptr, + + /** Used when re-using the same encode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + scratch_alloc_size_1: c.size_t, + + /** Some compression routines may need a second scratch buffer. + * + * If `NULL`, will be allocated during the run of the pipeline when + * needed. + * + * If the caller wishes to take control of the buffer, simple + * adopt the pointer and set it to `NULL` here. Be cognizant of any + * custom allocators. + */ + scratch_buffer_2: rawptr, + + /** Used when re-using the same encode pipeline struct to know if + * chunk is changed size whether current buffer is large enough. + */ + scratch_alloc_size_2: c.size_t, + + /** Enable a custom allocator for the different buffers (if + * encoding on a GPU). If `NULL`, will use the allocator from the + * context. + */ + alloc_fn: proc "c" (transcoding_pipeline_buffer_id_t, c.size_t) -> rawptr, + + /** Enable a custom allocator for the different buffers (if + * encoding on a GPU). If `NULL`, will use the allocator from the + * context. + */ + free_fn: proc "c" (transcoding_pipeline_buffer_id_t, rawptr), + + /** Function chosen based on the output layout of the channels of the part to + * decompress data. + * + * If the user has a custom method for the + * compression on this part, this can be changed after + * initialization. + */ + convert_and_pack_fn: proc "c" (pipeline: ^encode_pipeline_t) -> result_t, + + /** Function chosen based on the compression type of the part to + * compress data. + * + * If the user has a custom compression method for the compression + * type on this part, this can be changed after initialization. + */ + compress_fn: proc "c" (pipeline: ^encode_pipeline_t) -> result_t, + + /** This routine is used when waiting for other threads to finish + * writing previous chunks such that this thread can write this + * chunk. This is used for parts which have a specified chunk + * ordering (increasing/decreasing y) and the chunks can not be + * written randomly (as could be true for uncompressed). + * + * This enables the calling application to contribute thread time + * to other computation as needed, or just use something like + * pthread_yield(). + * + * By default, this routine will be assigned to a function which + * returns an error, failing the encode immediately. In this way, + * it assumes that there is only one thread being used for + * writing. + * + * It is up to the user to provide an appropriate routine if + * performing multi-threaded writing. + */ + yield_until_ready_fn: proc "c" (pipeline: ^encode_pipeline_t) -> result_t, + + /** Function chosen to write chunk data to the context. + * + * This is allowed to be overridden, but probably is not necessary + * in most scenarios. + */ + write_fn: proc "c" (pipeline: ^encode_pipeline_t) -> result_t, + + /** Small stash of channel info values. This is faster than calling + * malloc when the channel count in the part is small (RGBAZ), + * which is super common, however if there are a large number of + * channels, it will allocate space for that, so do not rely on + * this being used. + */ + _quick_chan_store: [5]coding_channel_info_t, +} + +ENCODE_PIPELINE_INITIALIZER :: encode_pipeline_t{} + + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** Initialize the encoding pipeline structure with the channel info + * for the specified part based on the chunk to be written. + * + * NB: The encode_pipe->pack_and_convert_fn field will be `NULL` after this. If that + * stage is desired, initialize the channel output information and + * call exr_encoding_choose_default_routines(). + */ + encoding_initialize :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + encode_pipe: ^encode_pipeline_t) -> result_t --- + + /** Given an initialized encode pipeline, find an appropriate + * function to shuffle and convert data into the defined channel + * outputs. + * + * Calling this is not required if a custom routine will be used, or + * if just the raw decompressed data is desired. + */ + encoding_choose_default_routines :: proc( + ctxt: const_context_t, + part_index: c.int, + encode_pipe: ^encode_pipeline_t) -> result_t --- + + /** Given a encode pipeline previously initialized, update it for the + * new chunk to be written. + * + * In this manner, memory buffers can be re-used to avoid continual + * malloc/free calls. Further, it allows the previous choices for + * the various functions to be quickly re-used. + */ + encoding_update :: proc( + ctxt: const_context_t, + part_index: c.int, + cinfo: ^chunk_info_t, + encode_pipe: ^encode_pipeline_t) -> result_t --- + + /** Execute the encoding pipeline. */ + encoding_run :: proc( + ctxt: const_context_t, + part_index: c.int, + encode_pipe: ^encode_pipeline_t) -> result_t --- + + /** Free any intermediate memory in the encoding pipeline. + * + * This does NOT free any pointers referred to in the channel info + * areas, but rather only the intermediate buffers and memory needed + * for the structure itself. + */ + encoding_destroy :: proc(ctxt: const_context_t, encode_pipe: ^encode_pipeline_t) -> result_t --- +} \ No newline at end of file diff --git a/vendor/openexr/exr_errors.odin b/vendor/openexr/exr_errors.odin new file mode 100644 index 000000000..cf2194756 --- /dev/null +++ b/vendor/openexr/exr_errors.odin @@ -0,0 +1,62 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" +#assert(size_of(c.int) == size_of(i32)) + +/** Error codes that may be returned by various functions. */ +error_code_t :: enum i32 { + SUCCESS = 0, + OUT_OF_MEMORY, + MISSING_CONTEXT_ARG, + INVALID_ARGUMENT, + ARGUMENT_OUT_OF_RANGE, + FILE_ACCESS, + FILE_BAD_HEADER, + NOT_OPEN_READ, + NOT_OPEN_WRITE, + HEADER_NOT_WRITTEN, + READ_IO, + WRITE_IO, + NAME_TOO_LONG, + MISSING_REQ_ATTR, + INVALID_ATTR, + NO_ATTR_BY_NAME, + ATTR_TYPE_MISMATCH, + ATTR_SIZE_MISMATCH, + SCAN_TILE_MIXEDAPI, + TILE_SCAN_MIXEDAPI, + MODIFY_SIZE_CHANGE, + ALREADY_WROTE_ATTRS, + BAD_CHUNK_LEADER, + CORRUPT_CHUNK, + INCORRECT_PART, + INCORRECT_CHUNK, + USE_SCAN_DEEP_WRITE, + USE_TILE_DEEP_WRITE, + USE_SCAN_NONDEEP_WRITE, + USE_TILE_NONDEEP_WRITE, + INVALID_SAMPLE_DATA, + FEATURE_NOT_IMPLEMENTED, + UNKNOWN, +} + +/** Return type for all functions. */ +result_t :: error_code_t + + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** @brief Return a static string corresponding to the specified error code. + * + * The string should not be freed (it is compiled into the binary). + */ + get_default_error_message :: proc(code: result_t) -> cstring --- + + /** @brief Return a static string corresponding to the specified error code. + * + * The string should not be freed (it is compiled into the binary). + */ + get_error_code_as_string :: proc(code: result_t) -> cstring --- +} diff --git a/vendor/openexr/exr_part.odin b/vendor/openexr/exr_part.odin new file mode 100644 index 000000000..24e1eb081 --- /dev/null +++ b/vendor/openexr/exr_part.odin @@ -0,0 +1,733 @@ +package vendor_openexr + +foreign import lib "exr.lib" + +import "core:c" + +attr_list_access_mode_t :: enum c.int { + FILE_ORDER, /**< Order they appear in the file */ + SORTED_ORDER, /**< Alphabetically sorted */ +} + +@(link_prefix="exr_", default_calling_convention="c") +foreign lib { + /** @brief Query how many parts are in the file. */ + get_count :: proc (ctxt: const_context_t, count: ^c.int) -> result_t --- + + /** @brief Query the part name for the specified part. + * + * NB: If this file is a single part file and name has not been set, this + * will return `NULL`. + */ + get_name :: proc(ctxt: const_context_t, part_index: c.int, out: ^cstring) -> result_t --- + + /** @brief Query the storage type for the specified part. */ + get_storage :: proc(ctxt: const_context_t, part_index: c.int, out: ^storage_t) -> result_t --- + + /** @brief Define a new part in the file. */ + add_part :: proc( + ctxt: context_t, + partname: rawptr, + type: storage_t, + new_index: ^c.int) -> result_t --- + + /** @brief Query how many levels are in the specified part. + * + * If the part is a tiled part, fill in how many tile levels are present. + * + * Return `ERR_SUCCESS` on success, an error otherwise (i.e. if the part + * is not tiled). + * + * It is valid to pass `NULL` to either of the @p levelsx or @p levelsy + * arguments, which enables testing if this part is a tiled part, or + * if you don't need both (i.e. in the case of a mip-level tiled + * image) + */ + get_tile_levels :: proc( + ctxt: const_context_t, + part_index: c.int, + levelsx: ^i32, + levelsy: ^i32) -> result_t --- + + /** @brief Query the tile size for a particular level in the specified part. + * + * If the part is a tiled part, fill in the tile size for the + * specified part/level. + * + * Return `ERR_SUCCESS` on success, an error otherwise (i.e. if the + * part is not tiled). + * + * It is valid to pass `NULL` to either of the @p tilew or @p tileh + * arguments, which enables testing if this part is a tiled part, or + * if you don't need both (i.e. in the case of a mip-level tiled + * image) + */ + get_tile_sizes :: proc( + ctxt: const_context_t, + part_index: c.int, + levelx: c.int, + levely: c.int, + tilew: ^i32, + tileh: ^i32) -> result_t --- + + /** @brief Query the data sizes for a particular level in the specified part. + * + * If the part is a tiled part, fill in the width/height for the + * specified levels. + * + * Return `ERR_SUCCESS` on success, an error otherwise (i.e. if the part + * is not tiled). + * + * It is valid to pass `NULL` to either of the @p levw or @p levh + * arguments, which enables testing if this part is a tiled part, or + * if you don't need both for some reason. + */ + get_level_sizes :: proc( + ctxt: const_context_t, + part_index: c.int, + levelx: c.int, + levely: c.int, + levw: ^i32, + levh: ^i32) -> result_t --- + + /** Return the number of chunks contained in this part of the file. + * + * As in the technical documentation for OpenEXR, the chunk is the + * generic term for a pixel data block. This is the atomic unit that + * this library uses to negotiate data to and from a context. + * + * This should be used as a basis for splitting up how a file is + * processed. Depending on the compression, a different number of + * scanlines are encoded in each chunk, and since those need to be + * encoded/decoded as a block, the chunk should be the basis for I/O + * as well. + */ + get_chunk_count :: proc(ctxt: const_context_t, part_index: c.int, out: ^i32) -> result_t --- + + /** Return the number of scanlines chunks for this file part. + * + * When iterating over a scanline file, this may be an easier metric + * for multi-threading or other access than only negotiating chunk + * counts, and so is provided as a utility. + */ + get_scanlines_per_chunk :: proc(ctxt: const_context_t, part_index: c.int, out: ^i32) -> result_t --- + + /** Return the maximum unpacked size of a chunk for the file part. + * + * This may be used ahead of any actual reading of data, so can be + * used to pre-allocate buffers for multiple threads in one block or + * whatever your application may require. + */ + get_chunk_unpacked_size :: proc(ctxt: const_context_t, part_index: c.int, out: ^u64) -> result_t --- + + /** @brief Retrieve the zip compression level used for the specified part. + * + * This only applies when the compression method involves using zip + * compression (zip, zips, some modes of DWAA/DWAB). + * + * This value is NOT persisted in the file, and only exists for the + * lifetime of the context, so will be at the default value when just + * reading a file. + */ + get_zip_compression_level :: proc(ctxt: const_context_t, part_index: c.int, level: ^c.int) -> result_t --- + + /** @brief Set the zip compression method used for the specified part. + * + * This only applies when the compression method involves using zip + * compression (zip, zips, some modes of DWAA/DWAB). + * + * This value is NOT persisted in the file, and only exists for the + * lifetime of the context, so this value will be ignored when + * reading a file. + */ + set_zip_compression_level :: proc(ctxt: context_t, part_index: c.int, level: c.int) -> result_t --- + + /** @brief Retrieve the dwa compression level used for the specified part. + * + * This only applies when the compression method is DWAA/DWAB. + * + * This value is NOT persisted in the file, and only exists for the + * lifetime of the context, so will be at the default value when just + * reading a file. + */ + get_dwa_compression_level :: proc(ctxt: const_context_t, part_index: c.int, level: ^f32) -> result_t --- + + /** @brief Set the dwa compression method used for the specified part. + * + * This only applies when the compression method is DWAA/DWAB. + * + * This value is NOT persisted in the file, and only exists for the + * lifetime of the context, so this value will be ignored when + * reading a file. + */ + set_dwa_compression_level :: proc(ctxt: context_t, part_index: c.int, level: f32) -> result_t --- + + /**************************************/ + + /** @defgroup PartMetadata Functions to get and set metadata for a particular part. + * @{ + * + */ + + /** @brief Query the count of attributes in a part. */ + get_attribute_count :: proc(ctxt: const_context_t, part_index: c.int, count: ^i32) -> result_t --- + + /** @brief Query a particular attribute by index. */ + get_attribute_by_index :: proc( + ctxt: const_context_t, + part_index: c.int, + mode: attr_list_access_mode_t, + idx: i32, + outattr: ^^attribute_t) -> result_t --- + + /** @brief Query a particular attribute by name. */ + get_attribute_by_name :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + outattr: ^^attribute_t) -> result_t --- + + /** @brief Query the list of attributes in a part. + * + * This retrieves a list of attributes currently defined in a part. + * + * If outlist is `NULL`, this function still succeeds, filling only the + * count. In this manner, the user can allocate memory for the list of + * attributes, then re-call this function to get the full list. + */ + get_attribute_list :: proc( + ctxt: const_context_t, + part_index: c.int, + mode: attr_list_access_mode_t, + count: ^i32, + outlist: ^[^]attribute_t) -> result_t --- + + /** Declare an attribute within the specified part. + * + * Only valid when a file is opened for write. + */ + attr_declare_by_type :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + type: cstring, + newattr: ^^attribute_t) -> result_t --- + + /** @brief Declare an attribute within the specified part. + * + * Only valid when a file is opened for write. + */ + attr_declare :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + type: attribute_type_t, + newattr: ^^attribute_t) -> result_t --- + + /** + * @defgroup RequiredAttributeHelpers Required Attribute Utililities + * + * @brief These are a group of functions for attributes that are + * required to be in every part of every file. + * + * @{ + */ + + /** @brief Initialize all required attributes for all files. + * + * NB: other file types do require other attributes, such as the tile + * description for a tiled file. + */ + initialize_required_attr :: proc( + ctxt: context_t, + part_index: c.int, + displayWindow: ^attr_box2i_t, + dataWindow: ^attr_box2i_t, + pixelaspectratio: f32, + screenWindowCenter: attr_v2f_t, + screenWindowWidth: f32, + lineorder: lineorder_t, + ctype: compression_t) -> result_t --- + + /** @brief Initialize all required attributes to default values: + * + * - `displayWindow` is set to (0, 0 -> @p width - 1, @p height - 1) + * - `dataWindow` is set to (0, 0 -> @p width - 1, @p height - 1) + * - `pixelAspectRatio` is set to 1.0 + * - `screenWindowCenter` is set to 0.f, 0.f + * - `screenWindowWidth` is set to 1.f + * - `lineorder` is set to `INCREASING_Y` + * - `compression` is set to @p ctype + */ + initialize_required_attr_simple :: proc( + ctxt: context_t, + part_index: c.int, + width: i32, + height: i32, + ctype: compression_t) -> result_t --- + + /** @brief Copy the attributes from one part to another. + * + * This allows one to quickly unassigned attributes from one source to another. + * + * If an attribute in the source part has not been yet set in the + * destination part, the item will be copied over. + * + * For example, when you add a part, the storage type and name + * attributes are required arguments to the definition of a new part, + * but channels has not yet been assigned. So by calling this with an + * input file as the source, you can copy the channel definitions (and + * any other unassigned attributes from the source). + */ + copy_unset_attributes :: proc( + ctxt: context_t, + part_index: c.int, + source: const_context_t, + src_part_index: c.int) -> result_t --- + + /** @brief Retrieve the list of channels. */ + get_channels :: proc(ctxt: const_context_t, part_index: c.int, chlist: ^^attr_chlist_t) -> result_t --- + + /** @brief Define a new channel to the output file part. + * + * The @p percept parameter is used for lossy compression techniques + * to indicate that the value represented is closer to linear (1) or + * closer to logarithmic (0). For r, g, b, luminance, this is normally + * 0. + */ + add_channel :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + ptype: pixel_type_t, + percept: perceptual_treatment_t, + xsamp: i32, + ysamp: i32) -> c.int --- + + /** @brief Copy the channels from another source. + * + * Useful if you are manually constructing the list or simply copying + * from an input file. + */ + set_channels :: proc(ctxt: context_t, part_index: c.int, channels: ^attr_chlist_t) -> result_t --- + + /** @brief Retrieve the compression method used for the specified part. */ + get_compression :: proc(ctxt: const_context_t, part_index: c.int, compression: ^compression_t) -> result_t --- + /** @brief Set the compression method used for the specified part. */ + set_compression :: proc(ctxt: context_t, part_index: c.int, ctype: compression_t) -> result_t --- + + /** @brief Retrieve the data window for the specified part. */ + get_data_window :: proc(ctxt: const_context_t, part_index: c.int, out: ^attr_box2i_t) -> result_t --- + /** @brief Set the data window for the specified part. */ + set_data_window :: proc(ctxt: context_t, part_index: c.int, dw: ^attr_box2i_t) -> c.int --- + + /** @brief Retrieve the display window for the specified part. */ + get_display_window :: proc(ctxt: const_context_t, part_index: c.int, out: ^attr_box2i_t) -> result_t --- + /** @brief Set the display window for the specified part. */ + set_display_window :: proc(ctxt: context_t, part_index: c.int, dw: ^attr_box2i_t) -> c.int --- + + /** @brief Retrieve the line order for storing data in the specified part (use 0 for single part images). */ + get_lineorder :: proc(ctxt: const_context_t, part_index: c.int, out: ^lineorder_t) -> result_t --- + /** @brief Set the line order for storing data in the specified part (use 0 for single part images). */ + set_lineorder :: proc(ctxt: context_t, part_index: c.int, lo: lineorder_t) -> result_t --- + + /** @brief Retrieve the pixel aspect ratio for the specified part (use 0 for single part images). */ + get_pixel_aspect_ratio :: proc(ctxt: const_context_t, part_index: c.int, par: ^f32) -> result_t --- + /** @brief Set the pixel aspect ratio for the specified part (use 0 for single part images). */ + set_pixel_aspect_ratio :: proc(ctxt: context_t, part_index: c.int, par: f32) -> result_t --- + + /** @brief Retrieve the screen oriented window center for the specified part (use 0 for single part images). */ + get_screen_window_center :: proc(ctxt: const_context_t, part_index: c.int, wc: ^attr_v2f_t) -> result_t --- + /** @brief Set the screen oriented window center for the specified part (use 0 for single part images). */ + set_screen_window_center :: proc(ctxt: context_t, part_index: c.int, wc: ^attr_v2f_t) -> c.int --- + + /** @brief Retrieve the screen oriented window width for the specified part (use 0 for single part images). */ + get_screen_window_width :: proc(ctxt: const_context_t, part_index: c.int, out: ^f32) -> result_t --- + /** @brief Set the screen oriented window width for the specified part (use 0 for single part images). */ + set_screen_window_width :: proc(ctxt: context_t, part_index: c.int, ssw: f32) -> result_t --- + + /** @brief Retrieve the tiling info for a tiled part (use 0 for single part images). */ + get_tile_descriptor :: proc( + ctxt: const_context_t, + part_index: c.int, + xsize: ^u32, + ysize: ^u32, + level: ^tile_level_mode_t, + round: ^tile_round_mode_t) -> result_t --- + + /** @brief Set the tiling info for a tiled part (use 0 for single part images). */ + set_tile_descriptor :: proc( + ctxt: context_t, + part_index: c.int, + x_size: u32, + y_size: u32, + level_mode: tile_level_mode_t, + round_mode: tile_round_mode_t) -> result_t --- + + set_name :: proc(ctxt: context_t, part_index: c.int, val: cstring) -> result_t --- + + get_version :: proc(ctxt: const_context_t, part_index: c.int, out: ^i32) -> result_t --- + + set_version :: proc(ctxt: context_t, part_index: c.int, val: i32) -> result_t --- + + set_chunk_count :: proc(ctxt: context_t, part_index: c.int, val: i32) -> result_t --- + + /** @} */ /* required attr group. */ + + /** + * @defgroup BuiltinAttributeHelpers Attribute utilities for builtin types + * + * @brief These are a group of functions for attributes that use the builtin types. + * + * @{ + */ + + attr_get_box2i :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + outval: ^attr_box2i_t) -> result_t --- + + attr_set_box2i :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + val: ^attr_box2i_t) -> result_t --- + + attr_get_box2f :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + outval: ^attr_box2f_t) -> result_t --- + + attr_set_box2f :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + val: ^attr_box2f_t) -> result_t --- + + /** @brief Zero-copy query of channel data. + * + * Do not free or manipulate the @p chlist data, or use + * after the lifetime of the context. + */ + attr_get_channels :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + chlist: ^^attr_chlist_t) -> result_t --- + + /** @brief This allows one to quickly copy the channels from one file + * to another. + */ + attr_set_channels :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + channels: ^attr_chlist_t) -> result_t --- + + attr_get_chromaticities :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + chroma: ^attr_chromaticities_t) -> result_t --- + + attr_set_chromaticities :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + chroma: ^attr_chromaticities_t) -> result_t --- + + attr_get_compression :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^compression_t) -> result_t --- + + attr_set_compression :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + comp: compression_t) -> result_t --- + + attr_get_double :: proc(ctxt: const_context_t, part_index: c.int, name: cstring, out: f64) -> result_t --- + + attr_set_double :: proc(ctxt: context_t, part_index: c.int, name: cstring, val: f64) -> result_t --- + + attr_get_envmap :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^envmap_t) -> result_t --- + + attr_set_envmap :: proc(ctxt: context_t, part_index: c.int, name: cstring, emap: envmap_t) -> result_t --- + + attr_get_float :: proc(ctxt: const_context_t, part_index: c.int, name: cstring, out: ^f32) -> result_t --- + + attr_set_float :: proc(ctxt: context_t, part_index: c.int, name: cstring, val: f32) -> result_t --- + + /** @brief Zero-copy query of float data. + * + * Do not free or manipulate the @p out data, or use after the + * lifetime of the context. + */ + attr_get_float_vector :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + sz: ^i32, + out: ^[^]f32) -> result_t --- + + attr_set_float_vector :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + sz: i32, + vals: [^]f32) -> result_t --- + + attr_get_int :: proc(ctxt: const_context_t, part_index: c.int, name: cstring, out: ^i32) -> result_t --- + + attr_set_int :: proc(ctxt: context_t, part_index: c.int, name: cstring, val: i32) -> result_t --- + + attr_get_keycode :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_keycode_t) -> result_t --- + + attr_set_keycode :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + kc: ^attr_keycode_t) -> result_t --- + + attr_get_lineorder :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^lineorder_t) -> result_t --- + + attr_set_lineorder :: proc(ctxt: context_t, part_index: c.int, name: cstring, lo: lineorder_t) -> result_t --- + + attr_get_m33f :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_m33f_t) -> result_t --- + + attr_set_m33f :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + m: ^attr_m33f_t) -> result_t --- + + attr_get_m33d :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_m33d_t) -> result_t --- + + attr_set_m33d :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + m: ^attr_m33d_t) -> result_t --- + + attr_get_m44f :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_m44f_t) -> result_t --- + + attr_set_m44f :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + m: ^attr_m44f_t) -> result_t --- + + attr_get_m44d :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_m44d_t) -> result_t --- + + attr_set_m44d :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + m: ^attr_m44d_t) -> result_t --- + + attr_get_preview :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_preview_t) -> result_t --- + + attr_set_preview :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + p: ^attr_preview_t) -> result_t --- + + attr_get_rational :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_rational_t) -> result_t --- + + attr_set_rational :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + r: ^attr_rational_t) -> result_t --- + + /** @brief Zero-copy query of string value. + * + * Do not modify the string pointed to by @p out, and do not use + * after the lifetime of the context. + */ + attr_get_string :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + length: ^i32, + out: ^cstring) -> result_t --- + + attr_set_string :: proc(ctxt: context_t, part_index: c.int, name: cstring, s: cstring) -> result_t --- + + /** @brief Zero-copy query of string data. + * + * Do not free the strings pointed to by the array. + * + * Must provide @p size. + * + * \p out must be a ``^cstring`` array large enough to hold + * the string pointers for the string vector when provided. + */ + attr_get_string_vector :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + size: ^i32, + out: ^cstring) -> result_t --- + + attr_set_string_vector :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + size: i32, + sv: ^cstring) -> result_t --- + + attr_get_tiledesc :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_tiledesc_t) -> result_t --- + + attr_set_tiledesc :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + td: ^attr_tiledesc_t) -> result_t --- + + attr_get_timecode :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_timecode_t) -> result_t --- + + attr_set_timecode :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + tc: ^attr_timecode_t) -> result_t --- + + attr_get_v2i :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v2i_t) -> result_t --- + + attr_set_v2i :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v2i_t) -> result_t --- + + attr_get_v2f :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v2f_t) -> result_t --- + + attr_set_v2f :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v2f_t) -> result_t --- + + attr_get_v2d :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v2d_t) -> result_t --- + + attr_set_v2d :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v2d_t) -> result_t --- + + attr_get_v3i :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v3i_t) -> result_t --- + + attr_set_v3i :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v3i_t) -> result_t --- + + attr_get_v3f :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v3f_t) -> result_t --- + + attr_set_v3f :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v3f_t) -> result_t --- + + attr_get_v3d :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + out: ^attr_v3d_t) -> result_t --- + + attr_set_v3d :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + v: ^attr_v3d_t) -> result_t --- + + attr_get_user :: proc( + ctxt: const_context_t, + part_index: c.int, + name: cstring, + type: ^cstring, + size: ^i32, + out: ^rawptr) -> result_t --- + + attr_set_user :: proc( + ctxt: context_t, + part_index: c.int, + name: cstring, + type: cstring, + size: i32, + out: rawptr) -> result_t --- + +} \ No newline at end of file From 6985181961ec2ed8910ea4650d1b6898952084c8 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 2 May 2022 17:51:39 +0200 Subject: [PATCH 152/245] [xxhash] Add tests for large inputs Test XXH32, XXH64, XXH3-64 and XXH3-128 for large inputs, with both all-at-once and streaming APIs. XXH32_create_state and XXH64_create_state now implicitly call their "reset state" variants to simplify the streaming API to 3 steps: - create state / defer destroy - update - digest (finalize) These are tested with an array of 1, 2, 4, 8 and 16 megabytes worth of zeroes. All return the same hashes as do both the one-shot version, as well as that of the official xxhsum tool. 3778/3778 tests successful. --- core/hash/xxhash/xxhash_32.odin | 3 +- core/hash/xxhash/xxhash_64.odin | 1 + tests/core/hash/test_core_hash.odin | 86 +++++++++++++++++++++++- tests/core/hash/test_vectors_xxhash.odin | 72 +++++++++++++++++++- 4 files changed, 158 insertions(+), 4 deletions(-) diff --git a/core/hash/xxhash/xxhash_32.odin b/core/hash/xxhash/xxhash_32.odin index e63d998dd..5bc87c2c0 100644 --- a/core/hash/xxhash/xxhash_32.odin +++ b/core/hash/xxhash/xxhash_32.odin @@ -197,6 +197,7 @@ XXH32 :: proc(input: []u8, seed := XXH32_DEFAULT_SEED) -> (digest: XXH32_hash) { */ XXH32_create_state :: proc(allocator := context.allocator) -> (res: ^XXH32_state, err: Error) { state := new(XXH32_state, allocator) + XXH32_reset_state(state) return state, .None if state != nil else .Error } @@ -258,7 +259,7 @@ XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) { v3 := state.v3 v4 := state.v4 - for len(buf) >= 15 { + for len(buf) >= 16 { #no_bounds_check v1 = XXH32_round(v1, XXH32_read32(buf, .Unaligned)); buf = buf[4:] #no_bounds_check v2 = XXH32_round(v2, XXH32_read32(buf, .Unaligned)); buf = buf[4:] #no_bounds_check v3 = XXH32_round(v3, XXH32_read32(buf, .Unaligned)); buf = buf[4:] diff --git a/core/hash/xxhash/xxhash_64.odin b/core/hash/xxhash/xxhash_64.odin index e95842168..9280e9c59 100644 --- a/core/hash/xxhash/xxhash_64.odin +++ b/core/hash/xxhash/xxhash_64.odin @@ -163,6 +163,7 @@ XXH64 :: proc(input: []u8, seed := XXH64_DEFAULT_SEED) -> (digest: XXH64_hash) { */ XXH64_create_state :: proc(allocator := context.allocator) -> (res: ^XXH64_state, err: Error) { state := new(XXH64_state, allocator) + XXH64_reset_state(state) return state, .None if state != nil else .Error } diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index 607642339..86c05fd44 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -31,8 +31,10 @@ when ODIN_TEST { main :: proc() { t := testing.T{} test_benchmark_runner(&t) - test_xxhash_vectors(&t) test_crc64_vectors(&t) + test_xxhash_vectors(&t) + test_xxhash_large(&t) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) if TEST_fail > 0 { os.exit(1) @@ -191,6 +193,88 @@ test_benchmark_runner :: proc(t: ^testing.T) { benchmark_print(name, options) } +@test +test_xxhash_large :: proc(t: ^testing.T) { + many_zeroes := make([]u8, 16 * 1024 * 1024) + defer delete(many_zeroes) + + // All at once. + for i, v in ZERO_VECTORS { + b := many_zeroes[:i] + + xxh32 := xxhash.XXH32(b) + xxh64 := xxhash.XXH64(b) + xxh3_64 := xxhash.XXH3_64(b) + xxh3_128 := xxhash.XXH3_128(b) + + xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32) + xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64) + xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64) + xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128) + + expect(t, xxh32 == v.xxh_32, xxh32_error) + expect(t, xxh64 == v.xxh_64, xxh64_error) + expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) + expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) + } + + // Streamed + for i, v in ZERO_VECTORS { + b := many_zeroes[:i] + + bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47} + update_size_idx: int + + xxh_32_state, xxh_32_err := xxhash.XXH32_create_state() + defer xxhash.XXH32_destroy_state(xxh_32_state) + expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state.") + + xxh_64_state, xxh_64_err := xxhash.XXH64_create_state() + defer xxhash.XXH64_destroy_state(xxh_64_state) + expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state.") + + xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state() + defer xxhash.XXH3_destroy_state(xxh3_64_state) + expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state.") + + xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state() + defer xxhash.XXH3_destroy_state(xxh3_128_state) + expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state.") + + // XXH3_128_update + + for len(b) > 0 { + update_size := min(len(b), bytes_per_update[update_size_idx % len(bytes_per_update)]) + update_size_idx += 1 + + xxhash.XXH32_update (xxh_32_state, b[:update_size]) + xxhash.XXH64_update (xxh_64_state, b[:update_size]) + + xxhash.XXH3_64_update (xxh3_64_state, b[:update_size]) + xxhash.XXH3_128_update(xxh3_128_state, b[:update_size]) + + b = b[update_size:] + } + + // Now finalize + xxh32 := xxhash.XXH32_digest(xxh_32_state) + xxh64 := xxhash.XXH64_digest(xxh_64_state) + + xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state) + xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state) + + xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32) + xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64) + xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64) + xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128) + + expect(t, xxh32 == v.xxh_32, xxh32_error) + expect(t, xxh64 == v.xxh_64, xxh64_error) + expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) + expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) + } +} + @test test_xxhash_vectors :: proc(t: ^testing.T) { fmt.println("Verifying against XXHASH_TEST_VECTOR_SEEDED:") diff --git a/tests/core/hash/test_vectors_xxhash.odin b/tests/core/hash/test_vectors_xxhash.odin index dccda5e53..6a37aef30 100644 --- a/tests/core/hash/test_vectors_xxhash.odin +++ b/tests/core/hash/test_vectors_xxhash.odin @@ -3,7 +3,7 @@ */ package test_core_hash -XXHASH_Test_Vectors_With_Seed :: struct #packed { +XXHASH_Test_Vectors :: struct #packed { /* Old hashes */ @@ -17,7 +17,75 @@ XXHASH_Test_Vectors_With_Seed :: struct #packed { xxh3_128: u128, } -XXHASH_TEST_VECTOR_SEEDED := map[u64][257]XXHASH_Test_Vectors_With_Seed{ +ZERO_VECTORS := map[int]XXHASH_Test_Vectors{ + 1024 * 1024 = { + /* + Old hashes + */ + xxh_32 = 0x9430f97f, // xxhsum -H0 + xxh_64 = 0x87d2a1b6e1163ef1, // xxhsum -H1 + + /* + XXH3 hashes + */ + xxh3_128 = 0xb6ef17a3448492b6918780b90550bf34, // xxhsum -H2 + xxh3_64 = 0x918780b90550bf34, // xxhsum -H3 + }, + 1024 * 2048 = { + /* + Old hashes + */ + xxh_32 = 0xeeb74ca1, // xxhsum -H0 + xxh_64 = 0xeb8a7322f88e23db, // xxhsum -H1 + + /* + XXH3 hashes + */ + xxh3_128 = 0x7b3e6abe1456fd0094e26d8e04364852, // xxhsum -H2 + xxh3_64 = 0x94e26d8e04364852, // xxhsum -H3 + }, + 1024 * 4096 = { + /* + Old hashes + */ + xxh_32 = 0xa59010b8, // xxhsum -H0 + xxh_64 = 0x639f9e1a7cbc9d28, // xxhsum -H1 + + /* + XXH3 hashes + */ + xxh3_128 = 0x34001ae2f947e773165f453a5f35c459, // xxhsum -H2 + xxh3_64 = 0x165f453a5f35c459, // xxhsum -H3 + }, + 1024 * 8192 = { + /* + Old hashes + */ + xxh_32 = 0xfed1d084, // xxhsum -H0 + xxh_64 = 0x86823cbc61f6df0f, // xxhsum -H1 + + /* + XXH3 hashes + */ + xxh3_128 = 0x9d6bf1a4e92df02ce881a25e37e37b19, // xxhsum -H2 + xxh3_64 = 0xe881a25e37e37b19, // xxhsum -H3 + }, + 1024 * 16384 = { + /* + Old hashes + */ + xxh_32 = 0x0ee4ebf9, // xxhsum -H0 + xxh_64 = 0x412f1e415ee2d80b, // xxhsum -H1 + + /* + XXH3 hashes + */ + xxh3_128 = 0x14d914cac1f4c1b1c4979470a1b529a1, // xxhsum -H2 + xxh3_64 = 0xc4979470a1b529a1, // xxhsum -H3 + }, +} + +XXHASH_TEST_VECTOR_SEEDED := map[u64][257]XXHASH_Test_Vectors{ 0 = { { // Length: 000 /* XXH32 with seed */ 0x02cc5d05, From b99940f33a50cf2ed5eaa39ffcdb00950f15ad27 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 2 May 2022 19:20:25 +0200 Subject: [PATCH 153/245] [xxhash] For the streaming tests, randomly select the size to use. Randomize size used with `update`. It'll print "Using user-selected seed {18109872483301276539,2000259725719371} for update size randomness." If a streaming test then fails, you can repeat it using: `odin run . -define:RAND_STATE=18109872483301276539 -define:RAND_INC=2000259725719371` --- core/hash/xxhash/streaming.odin | 4 +++- tests/core/hash/test_core_hash.odin | 28 +++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index 68a4920a5..6f630b042 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -211,7 +211,9 @@ XXH3_update :: #force_inline proc( length := len(input) secret := state.custom_secret[:] if len(state.external_secret) == 0 else state.external_secret[:] - assert(len(input) > 0) + if len(input) == 0 { + return + } state.total_length += u64(length) assert(state.buffered_size <= XXH3_INTERNAL_BUFFER_SIZE) diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index 86c05fd44..e69490143 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -6,6 +6,8 @@ import "core:time" import "core:testing" import "core:fmt" import "core:os" +import "core:math/rand" +import "core:intrinsics" TEST_count := 0 TEST_fail := 0 @@ -202,6 +204,8 @@ test_xxhash_large :: proc(t: ^testing.T) { for i, v in ZERO_VECTORS { b := many_zeroes[:i] + fmt.printf("[test_xxhash_large] All at once. Size: %v\n", i) + xxh32 := xxhash.XXH32(b) xxh64 := xxhash.XXH64(b) xxh3_64 := xxhash.XXH3_64(b) @@ -218,12 +222,25 @@ test_xxhash_large :: proc(t: ^testing.T) { expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) } + when #config(RAND_STATE, -1) >= 0 && #config(RAND_INC, -1) >= 0 { + random_seed := rand.Rand{ + state = u64(#config(RAND_STATE, -1)), + inc = u64(#config(RAND_INC, -1)), + } + fmt.printf("Using user-selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc) + } else { + random_seed := rand.create(u64(intrinsics.read_cycle_counter())) + fmt.printf("Randonly selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc) + } + // Streamed for i, v in ZERO_VECTORS { b := many_zeroes[:i] - bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47} - update_size_idx: int + fmt.printf("[test_xxhash_large] Streamed. Size: %v\n", i) + + // bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47} + // update_size_idx: int xxh_32_state, xxh_32_err := xxhash.XXH32_create_state() defer xxhash.XXH32_destroy_state(xxh_32_state) @@ -244,9 +261,10 @@ test_xxhash_large :: proc(t: ^testing.T) { // XXH3_128_update for len(b) > 0 { - update_size := min(len(b), bytes_per_update[update_size_idx % len(bytes_per_update)]) - update_size_idx += 1 - + update_size := min(len(b), rand.int_max(8192, &random_seed)) + if update_size > 4096 { + update_size %= 73 + } xxhash.XXH32_update (xxh_32_state, b[:update_size]) xxhash.XXH64_update (xxh_64_state, b[:update_size]) From 8bac82320fbba53a440bf42b117c702e726db093 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 3 May 2022 11:44:55 +0200 Subject: [PATCH 154/245] Fix -opt: parsing. --- src/main.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 818a783e1..86c1544a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -961,7 +961,26 @@ bool parse_build_flags(Array args) { bad_flags = true; break; } - build_context.optimization_level = cast(i32)big_int_to_i64(&value.value_integer); + // NOTE(Jeroen): We can't rely on `value.value_integer` here, because words will be returned as `0`. + // Meaning that -opt:speed will coerce to opt:0. That's not what the user intended. + // Instead we'll just compare 0..3 directly. + if (param == "0") { + build_context.optimization_level = 0; + } else if (param == "1") { + build_context.optimization_level = 1; + } else if (param == "2") { + build_context.optimization_level = 2; + } else if (param == "3") { + build_context.optimization_level = 3; + } else { + gb_printf_err("Invalid optimization level for -o:, got %.*s\n", LIT(param)); + gb_printf_err("Valid optimization levels:\n"); + gb_printf_err("\t0\n"); + gb_printf_err("\t1\n"); + gb_printf_err("\t2\n"); + gb_printf_err("\t3\n"); + bad_flags = true; + } break; } case BuildFlag_OptimizationMode: { From 59f55a21193ec7461205f4bb95303b69f3f7ce1c Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 3 May 2022 13:15:49 +0200 Subject: [PATCH 155/245] Make `big_int_from_string` return an error if not an integer. --- src/big_int.cpp | 30 +++++++++++++++++++++++++++--- src/exact_value.cpp | 6 +++++- src/main.cpp | 17 ++++------------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/big_int.cpp b/src/big_int.cpp index 20f940e8e..8203f0522 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -40,7 +40,7 @@ typedef mp_int BigInt; void big_int_from_u64(BigInt *dst, u64 x); void big_int_from_i64(BigInt *dst, i64 x); void big_int_init (BigInt *dst, BigInt const *src); -void big_int_from_string(BigInt *dst, String const &s); +void big_int_from_string(BigInt *dst, String const &s, bool &success); void big_int_dealloc(BigInt *dst) { mp_clear(dst); @@ -84,7 +84,7 @@ void big_int_quo_eq(BigInt *dst, BigInt const *x); void big_int_rem_eq(BigInt *dst, BigInt const *x); bool big_int_is_neg(BigInt const *x); - +void big_int_neg(BigInt *dst, BigInt const *x); void big_int_add_eq(BigInt *dst, BigInt const *x) { BigInt res = {}; @@ -169,7 +169,11 @@ BigInt big_int_make_i64(i64 x) { } -void big_int_from_string(BigInt *dst, String const &s) { +void big_int_from_string(BigInt *dst, String const &s, bool *success) { + *success = true; + + bool is_negative = false; + u64 base = 10; bool has_prefix = false; if (s.len > 2 && s[0] == '0') { @@ -197,11 +201,26 @@ void big_int_from_string(BigInt *dst, String const &s) { isize i = 0; for (; i < len; i++) { Rune r = cast(Rune)text[i]; + + if (r == '-') { + if (is_negative) { + // NOTE(Jeroen): Can't have a doubly negative number. + *success = false; + return; + } + is_negative = true; + continue; + } + if (r == '_') { continue; } u64 v = u64_digit_value(r); if (v >= base) { + // NOTE(Jeroen): Can still be a valid integer if the next character is an `e` or `E`. + if (r != 'e' && r != 'E') { + *success = false; + } break; } BigInt val = big_int_make_u64(v); @@ -225,6 +244,7 @@ void big_int_from_string(BigInt *dst, String const &s) { if (gb_char_is_digit(r)) { v = u64_digit_value(r); } else { + *success = false; break; } exp *= 10; @@ -234,6 +254,10 @@ void big_int_from_string(BigInt *dst, String const &s) { big_int_mul_eq(dst, &b); } } + + if (is_negative) { + big_int_neg(dst, dst); + } } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index cedef48c4..175cb61f6 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -177,7 +177,11 @@ ExactValue exact_value_typeid(Type *type) { ExactValue exact_value_integer_from_string(String const &string) { ExactValue result = {ExactValue_Integer}; - big_int_from_string(&result.value_integer, string); + bool success; + big_int_from_string(&result.value_integer, string, &success); + if (!success) { + result = {ExactValue_Invalid}; + } return result; } diff --git a/src/main.cpp b/src/main.cpp index 86c1544a4..8bd6fc618 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -961,19 +961,10 @@ bool parse_build_flags(Array args) { bad_flags = true; break; } - // NOTE(Jeroen): We can't rely on `value.value_integer` here, because words will be returned as `0`. - // Meaning that -opt:speed will coerce to opt:0. That's not what the user intended. - // Instead we'll just compare 0..3 directly. - if (param == "0") { - build_context.optimization_level = 0; - } else if (param == "1") { - build_context.optimization_level = 1; - } else if (param == "2") { - build_context.optimization_level = 2; - } else if (param == "3") { - build_context.optimization_level = 3; - } else { - gb_printf_err("Invalid optimization level for -o:, got %.*s\n", LIT(param)); + + build_context.optimization_level = cast(i32)big_int_to_i64(&value.value_integer); + if (build_context.optimization_level < 0 || build_context.optimization_level > 3) { + gb_printf_err("Invalid optimization level for -o:, got %d\n", build_context.optimization_level); gb_printf_err("Valid optimization levels:\n"); gb_printf_err("\t0\n"); gb_printf_err("\t1\n"); From 47f637d23bf44b637041383b739780d9959331db Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 3 May 2022 13:37:07 +0200 Subject: [PATCH 156/245] Add deprecation warnings for -opt and flag=value insted of flag:value. --- src/main.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8bd6fc618..2633f8e55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -825,11 +825,19 @@ bool parse_build_flags(Array args) { String name = substring(flag, 1, flag.len); isize end = 0; + bool have_equals = false; for (; end < name.len; end++) { if (name[end] == ':') break; - if (name[end] == '=') break; // IMPORTANT TODO(bill): DEPRECATE THIS!!!! + if (name[end] == '=') { + have_equals = true; + break; + } } name = substring(name, 0, end); + if (have_equals && name != "opt") { + gb_printf_err("`flag=value` has been deprecated and will be removed next release. Use `%.*s:` instead.\n", LIT(name), LIT(name)); + } + String param = {}; if (end < flag.len-1) param = substring(flag, 2+end, flag.len); @@ -903,35 +911,35 @@ bool parse_build_flags(Array args) { switch (bf.param_kind) { case BuildFlagParam_None: if (value.kind != ExactValue_Invalid) { - gb_printf_err("%.*s expected no value, got %.*s", LIT(name), LIT(param)); + gb_printf_err("%.*s expected no value, got %.*s\n", LIT(name), LIT(param)); bad_flags = true; ok = false; } break; case BuildFlagParam_Boolean: if (value.kind != ExactValue_Bool) { - gb_printf_err("%.*s expected a boolean, got %.*s", LIT(name), LIT(param)); + gb_printf_err("%.*s expected a boolean, got %.*s\n", LIT(name), LIT(param)); bad_flags = true; ok = false; } break; case BuildFlagParam_Integer: if (value.kind != ExactValue_Integer) { - gb_printf_err("%.*s expected an integer, got %.*s", LIT(name), LIT(param)); + gb_printf_err("%.*s expected an integer, got %.*s\n", LIT(name), LIT(param)); bad_flags = true; ok = false; } break; case BuildFlagParam_Float: if (value.kind != ExactValue_Float) { - gb_printf_err("%.*s expected a floating pointer number, got %.*s", LIT(name), LIT(param)); + gb_printf_err("%.*s expected a floating pointer number, got %.*s\n", LIT(name), LIT(param)); bad_flags = true; ok = false; } break; case BuildFlagParam_String: if (value.kind != ExactValue_String) { - gb_printf_err("%.*s expected a string, got %.*s", LIT(name), LIT(param)); + gb_printf_err("%.*s expected a string, got %.*s\n", LIT(name), LIT(param)); bad_flags = true; ok = false; } @@ -972,6 +980,9 @@ bool parse_build_flags(Array args) { gb_printf_err("\t3\n"); bad_flags = true; } + + // Deprecation warning. + gb_printf_err("`-opt` has been deprecated and will be removed next release. Use `-o:minimal`, etc.\n"); break; } case BuildFlag_OptimizationMode: { From d9b0c05acf72206d00068e708c1e2ebd872b2586 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 3 May 2022 13:47:13 +0200 Subject: [PATCH 157/245] Typo. --- src/big_int.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/big_int.cpp b/src/big_int.cpp index 8203f0522..5509545ca 100644 --- a/src/big_int.cpp +++ b/src/big_int.cpp @@ -40,7 +40,7 @@ typedef mp_int BigInt; void big_int_from_u64(BigInt *dst, u64 x); void big_int_from_i64(BigInt *dst, i64 x); void big_int_init (BigInt *dst, BigInt const *src); -void big_int_from_string(BigInt *dst, String const &s, bool &success); +void big_int_from_string(BigInt *dst, String const &s, bool *success); void big_int_dealloc(BigInt *dst) { mp_clear(dst); From 6e7a50c02f10a2a031687138f74172c95f3280c2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 May 2022 14:11:26 +0100 Subject: [PATCH 158/245] Add .lib for `vendor:openexr` --- vendor/openexr/OpenEXRCore-3_1.lib | Bin 0 -> 1064780 bytes vendor/openexr/exr_base.odin | 2 +- vendor/openexr/exr_chunkio.odin | 2 +- vendor/openexr/exr_context.odin | 2 +- vendor/openexr/exr_debug.odin | 2 +- vendor/openexr/exr_decode.odin | 2 +- vendor/openexr/exr_encode.odin | 2 +- vendor/openexr/exr_errors.odin | 8 ++++---- vendor/openexr/exr_part.odin | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 vendor/openexr/OpenEXRCore-3_1.lib diff --git a/vendor/openexr/OpenEXRCore-3_1.lib b/vendor/openexr/OpenEXRCore-3_1.lib new file mode 100644 index 0000000000000000000000000000000000000000..f70938101ea9c0adaf29e80352fe296ccc15bdbe GIT binary patch literal 1064780 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

G``@TR=#m62jACG50INZ<>lE09 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® zz$?Jp#{sGuF5}|p;N|b{?Ca)*>I_0H5*L35PY(}AFJE6*k|My_+rh`%*VEg@-48XW z!Q+bHqZLs?8{tqd2PYRtXD?8(gR?aTJDt(q0gwt3fKUTBGr+;m&(qh}+sg;p51?F*q{PGBGr-Z?A4Lf$6~mRdcsls`xj6=a zf)HLJfsa=N^|V1p(jj-i;o4k%96a59T)iAUJrIe2ur?Q82WJ;|zW^^cS1jobsi1^( ztq|3-bAW?~M}VW7iyLYWn@|dIc60Fc_4RRd_HakI6BGcThBGLw7Ta6co2KO#AvJm7 zo^BedLd~A zjhQ9p*_$FA-DqzLwiIEfmqUQNqnEFz7tGF##A1kjD7wINYoJ05uG87c!Nc3j)y>7z z!vTC=qrEBQz(%M8P2mX=jHC{!~nKzcr8I4Uo-q69o7R$^}o zKC{t*AwJ#{bds-AVsR?U)FEWjkW1g#%uE3Z7@Cl&=206OLYbWRm$O%L8Dto4mN39+-^}Eq z{Nnty5(SMQO$GmglFZ!9D$sQS&iT0onK`LN3=GQbX`<><`=xyJSxVM2IfFLkfISQD zmy>*28z>UM+TjFp@Pk&3Ff)Q804@z?AO}5YcOqoZF<1&tfWnbW-^9Qenkc{&p)_P< zU}9nc)&WXGq0FE(GC=NjRS*bBKt6g7q;4W31B2Kc28QLJHI&f9mawUN0y_F* z9s>h2X#FDt=s+e023+dw=QA)UL&F-hQ3RX1PDTcX_yr6MFF<;paamb$1f;coVPJBoB*x+!eibhMg|6l9SjVgKx?+} zsGG^iz>u|zfq{7setSw7#Q{*V_>*=0-_GIxe1%P z$&3sPu_qZAKAeK6!{rZ<`!Y^5FnoYs!-PxSIz|SDjI#_3V&@^|;c_1+zg3-QU|_xo zQHRSskiFFx85o#BSJUB%U$DB%3=GUy@tX&VkLs%o4E)#es{`fV_UjA`lF;)8ak&qq zZsJV_2IbrM&AY(Jz%ctZ14H&*h&o*HVaUY5@ck|WgT@1hI?!GrZ1HBx#K7?30Rw~X zV~9G?9!qTMt}`+)oPEr|ump6;9RmXcE_;QT7#IwmF)%oRuft_v04;XLX5K7NdVayc zQ1l97FK7WaHgyje85kbCVqiG%2BHpE_^~oEFj%~0V6c4;Q3u+wh|RoBObiUq-!m}G z`~*=4+BJkt9S0KwL-uC|hT^Xfb-2RiJ|hEz@HYmAPoOK`@Pvyn69Yrt4+e&bzaZw} z3YRa83=HbO85pGhLe$|3=evvy49ovAFtq%~ua1j}fkA+QkwJ0*O-}sVI3DE!$V$(I?!GR zZ02oYW?;C@$H>qx1W^at1%ORmC=&z2WMM{z7odyv7(jlRWqL>;bp1LezPX+{QPS%^AZ<}oobFzlCQWH=}fQHLv?g4~y_z{p^w1W|{} zyqk;+49Aoh8Ro0tR|m?!+Nz8UOrY!S@T60ax;}MAhEz@b=7A0g{;0{wa7P=W4z$$> zTYOl7+Alhc3^PEN@G&qjfHt0CQ}>yHf#IGmBf~}L39Go;VW8@TSD%sLx<15SP-7RH zc_NGq4FB~R8H5cX>TsFo!N|biZ^+0n-3X!%S2+Yy$7;;T;A?_kohPV1H(_L8F(a(5 z$c&L;w>f@wAbT|}7#RvdR|YaLfR7Tz=3kKXeM?3L32TUXpsnWE)VVV;bh0kzjYx-v5C1UUdt{zzhEU~u(dWLOT0 zXgu)|%gDeW>cz-V1PVwz>Ol99KJaE_XoH?3j4L03+BqD4j0_X~A^yNs5B4!KFmMJi zGE5J|ug;%|fq_4Wks&Swq7GO4AcB#BK`oS#p)L%f4p)3EVPs%<6UN9e0i*#>_<^Kl zA{iM>yy^fPB;_NDLINHt~!M9#FNQPBvH_7W2}eYC!rx7_1JwnhnH*V32uL@r(>@P__8X zTLM)B(aFGo%e)=&j0{JhYVn!(D4vnw8@f6y?h{F1WKaNIbq(5P!T_}w&A*`bk6i*I zgCDv&Eav4TFfvr2t3xvn6d%)|Y6$svRRSZ!HmF*B{=EWKL&&@r35*P1plb1%CzQy@ zpq2nAxS+WY6( z!5|eaT(Fqum&(Wxg{}_GJW%*mq%tyepsT}T-m+9ihE3?|(98p+mkX(k3{TM2VKI*> zjgf&b4b2}|%+rCYAr!w3X^ad$P_?+?7v$e8s2W1%Ri!a9v_aM4G7se6C25QdJJ8i( z@$a=XMutb|>ah5iA)S#y1bTY|++Hl^8KpBa*rBUKGY{n7m~=*l9CUS9%LWSEAo z4$VAJdft-G$Z!T-9TxLmr86>oLsy4p9w_`oG8h>&GSJci7W3RP7#V`l)uEXODqjkq zY6!(|O$H-F2UIOQoYBk!`FB|cBf~y)by(bYCxemU1-d#c=CNfmGRS2T_ODGQBZCLJ zIyCb@@tc;($WVr^4vYJyWHK@=Kv#!m9_Se8eVL35_t4d0G4D?%BLhbknm^FY1I4de z79)cdx;iZ8MPxBDq@b(AVqOze4Wam*mc_`h2&xuW{DQ*o08|Yj^DbmDGTecx#bqAI zzrV5=8Thi%!Uc5EYQ_q@o!i*BSRLtIxOaOWHT~ML05-n9>~9&vKbi;p{v7U z-h*sLhBxTy(98qn53U?W2BjRr{&mP(hh`oq{IYTw8S2p0VR7G_97cu}=<2YT zcMPhAQ2gG?VPtp)Rf{WrLFEfeF2t{d%oE6EWRQWX#bq8S{H$^r8G_K&VexN4E+az? zx;iZWot4YTunt`v7W2;JGBVsiSBGXED7}2kWn^H>gZLTl4=m=Xkt=5^#TGE6~Nhh`oqy==;3WH^Sd4vTqD@)#LDpsT}T9$!AhuY}@PDW8!+ z52_X(E@?z1akWC%i6hsC^t0!D@!baiO%1Es%N1&j=<(A8lv??eG3 z!xeOOXy$>^-=_jb2EIZxe_%0Br;w4s0$m-Nd7$tMD`aHILsy5zyq-cvh8gJU(98qH z?>49!Lh0pHAtS>zs9Id{0Sdn_P&I_iV<}=}5C9EiA@{qnxKFQ$k--UF9Txv46frX7 zpsT}TURMz#!#s3#Sj^i~#K>?0T^*WvApbrqVr2M+t`3WNBE^gh3ZMl_c>D{BU%O&P zhA?z>Sj;OaW@KnUSBK_4Q2fp-W@Olet`3WN7m67f?x3r~V%{&P8ba~QSHj33Rf3l8 zv6yE8RYS-;pAtrf2&h_I=?~=JvJysyE_8KR{JWxrkzotEIyCoz;`dSsBf}$fby&<} zC}m{e0WC1V6Tcw$X+hNx@~>SfBZC)IEiV6p+?N4WL&&^}QbvXrs9Id+f!w#Kl#yW@ zx;iZWy;91^@Bm#MTKIv?`&Y`yAXJ8y4zQSKP{zn$gRTzEJdl5*$`~24(A8lvucM5S zVG6oBH1k0DZBrQ|!zpxiSj>A-#>nsmT^*WvApZ)LGcu@^6ZWr5IU_>=x;iZ8TU ziOW2Ye=RB*89dO{VKFbQl98bZT^*W#LFP?>sv+dx1(l2pYoKazxepY6rz#m4?xCy0 z;=VtXj0_xA_~RFp-_)uY8SK#2VKFbJijg4$T^$zxwpB4QOhZ?P#k?(5j0^|R)uEXO zYOmd^Vr2M*t`3WN64i_hD%JS?3kpA{YDR`IbahzFE2(B=Xh2to<~~sT&V#BU6u;}L z85wp#)#8ia8`X>qZ_w3YaUWL=BZF8CVgH)cFfw?ctHWYmS`8yZ5xP1w|ANAALJcFs z5_EM~%sW)W$Z!r_9h!Nd@Ox9k$nXbU9TxMXY8e^SYVrFQWS&bcBSQ$fIxOZD)iN^F zp{ql4A1M9Jsbyr?fvygVdDm(g86KglLo*K)ehhVt3?g-C{=j0MQ5_?L9lAO!=EXqO z5K4aqb&L!(P_?+yA1M50LDdj4Z&e*5!#1c|T;_rNd!>$%;RU)nEdFJyXJinnM++A$ z{xzs)WN<-OhsC_4dPaskbaiOvf&AN3&&V(bT^$zlcGWX7979)!W*(?KeNxZJ@CRKT z7W1SU7#Y+W@cS3!K9>eYh7fdhSj;PGU}UI6SBK_4ka=^UY6!*eng&LO9Zr;@{p;4m$Pk6D4vTpeO^ggJ=<3ki2MWJMP&I_& zcUu!9!y%|zT=5G^FAtz<2$}bxiIL$CR4p#^K<<-jW@ON7Mhh1#{`F~QWQaglhsD2T z&5R6P=<2YTx1yPmVGFuCH1k0Iz0}Oe@CaQU7V{Wd7#Vm#8wK$6FG1-=tA&xl30)l) z^AcJZ8FJ9op}7wfeqAk$4D-;{VKHw{3nRk`bahzFdj?fQD1LvnFfy=#HZtJxFDU#} zplS%2XVS{Z-~d&NFTKRIGBOmQtHa{o39XC_bI{dc@$aryMuv0f>advirj?Q52f8{m z^FaO;Yhz?kYa^VVUD_BK0?^f=nFmTQd2NggZRqN-xNk`tBf|!Cb!g^+(#yFvMutb| z>adu{(9X!f(~jm3EaquJ)ewqbyLLtfFQ{5v@e2yS45%7H=2f&aGPFR|;xZ59-$m_= z4BODvVe#*kc1DH==<2Ze_g_0BgAiy#26DQ`VxB<!PpFfTK@GIflYoC+IvE)P(A8lv zFAu7QQ2aJ^GBWf*)#8d@Q24EZsv%_Fo=!%F6Hv9d%mexNStldIFLZTS!cU@$kwK-4 zaQ<-WVq^$ISBJ&Ck}gJu26T03;Ro{Xye>wDb?EA_n0Ka&k>LiqIyCb@>E&A&BLiPI znm@3Zr_;^IV1cd<%{)-}g>^GBWTC6WVqQl#Bf}JQby&>X1XV*QevfrCGF*bH#TCDx z@cRH&L&!Xa9!3V99<*@5;y$e&Mg}`{by)lx)5FM+fvygVd2Kz6471SHVKHw<4Kz*pzy1Jsv%@v#{@=(DNwbz%mcY^(*#C_W9aIz`1i>K zMurdQ>ac_#-$X_RCD4X-3T=5GEzdcYjgv>iLiIL$3R4p#^K>qzUiIIT|wDB1^T(J08V=^Oy3A#Eg z{tcSU$dHDv4vTp$lNlK%psPbO59Hr(JFc>d?#s`S;sYMh3QN5I@8HfyF$PX^ad8=<3kS1C8JNO=D!pLRW{yypCy%3{%k6 zp_vB?zfIE^8BU?A!(!fxX^aeC(AA-t2TFfJ(-|4mrW5wB%XCJD0CaU&%*%tSA(UR4 zrZY11LDj;;8O=OUe5`@0A!Od3>5L2~plWfM2lDT;>5L4&(A8lHKZzNP3@S6w!UfHJ zAoHANFfxRptHWYm$qYt@26T03=7Ib>Zw4d7I&^hd%sVrKk>LiqIyCb@>E+uDMg~66 zfgJ?OE1j8)3>N6>(98q*H*6*&Ll(L^Ebi-=$;dDTT^$zlHbK=8ir-^185u4?)#8d@ zQ22d-sv%?^!z@My9?$^{$l-#;eOj{^8SK#2VexOwEJlV5bahzFYn#Q$FbiEB7V~z@ zVq`dit`5ySkbfV|Vr2M)t`3WN0<#$zWIzYT;PEdgy;#j=WC%i6hsC^t*^CS|=<3ki z2TCuqW-~IZLsy5zyfd>I8E&Af!(!eys2W1?%Qc6QL2M5G{0j;{6Q~+O=DEyaWC(z& z#g+a*{>_`i$k2qY4vT*m%wc3$gRTyXe^1R}WVnZ}4vTqz<}fmF%q8q!wYiK8X6Wj$ zm=`jaks$$H9h&<<>7{NiBf~Uwby&>XGMACz0J=If^FZNuZ!ROlCv?(t7`i$v{(Ul! zk>LZnIxOMGH=mI~X+B!GU@^~OJ|lwp2|&&W`Pt`3WNGv+fgEJ0U?W*#WL z9GcI_a0^`>7W010XJlYmfaVW0^FZOJw1APp3|$=-^FkIdG9;j@!(v_?R1Kl{owR_F zVIEX1uJ{Fo-yWzMLgt-Wz{qd|suq`dApd?_z{tS05G`D=_*Y{gBZCRLIxPMTTFA(d zhOQ2ac`XYW8782sLo*NL-*pQa8TO&8!(!f@g^Ua@(AA-t2TCt&ix?T?77_NZ%_2qy z4|H{C=7GX5Z4o0w6}mbs?whfQkzonCIxOZLf~p}DztxnFk8L4yYPJ=FM2n$gl*e7MFP- z{~lV-$Z!o^9Txw70jXJm7A|P+1DPkcf|0=pT^$zl0#-0G#GtD~GY{n7suhe3UFhnt zn73jDBf}PSb!g^+(#xe4j0~^P)nPG@V!bx^gq;ujQtXP{~bnRjO;Bf|@*T3qIV+{dSBGXED7}cS zW@OM?P1wIas~H(0(AA-t2MWKk)r<^X=<2YzZ^ddxhArsou$XrVs)kVfK3mPm@Cm9G zSNwv)PhbtiuY}A~Si{Jm167O5JW%*~tzl$HLRW{yzYS{`8G6vwVe#*(HH-}V(A8lv z@6H-Vh8O7S(98q*mu)R0gVmv2*t0_Iz|RNs9Jcqpt%neelbur zgv`rX$H-6tRg23!ko%^sV`Nx`t`3WTPpo5PxPq<@&3z#AKCNS9U|UZ(epS{pG8mw% z!(yJ_dPasMbahzV*RY~9wHZn3SLsy5zzehGQ zGF(7chsD3|HZn3Wfe!jc&gWRnQ`p4Fpo6Xs%{-8Qy*4p2M4_w0VqV22Murx2b!g^+ z%KJr|7#Vhk+z4J}--_}6C}BSQqbIxPMz+s4Syg{}^Zc`LRt zGHgLthh`qgzn8W#GCV?8hs8XG?TidO+tK`iW*#WLXl-X?a6(sy#k_>=j0`#G>d?#s zgadu%XFDUq33PQ>%zFk^LnwZKZD(X)+kxM|pzu?Hsv%^a$qq&a2dG+n z=_PIlBSR6oIxPO3u!E6d4!Sxl{@t~Mk>MP=IxObB*}=&016>`Oc_9Ca?PO$7+ldw~ zSj=}F)JL05-n9>~8@yBQg>(A8lvuVXhO!xVINXy$>^ z%ck9o45!f5VKMK;ZbpVL=<3kS1BIW^9!3VWJ%s)1vWJl&09_px^YWl-2*q#H9!7>f zs9Id{3kttAP&I_i+p~v};RIAIF7rVCeYS^@;TO6(Ea4}ymytnbFIu=@@vqZfMusqS zby&L_lEw1}O=)*^d@3Slp+zpOL{1T^$zx#_VTg$Us+z#k{utj105T)nPGj$9_hJBk1bT%mexN z(SAmTPw48fm?v<6kwNAFe*c2fi`4-}h9GoxSj;Opz{pU8t`5z8p!72903*XXbahzF zJ9B`M;Rd=oEarWKsv#7=Tn8B$#17*3FDU#>plS%2=W>vdApoitSNa3_H}4=LLle3> zEdE_^kda{xx;iZWJ#~~3 zBWU4*#XN^2j0`^L>d?#s`8VqbBSRIsIxObRIKs%V1YI4Pd7$)i=m;ajEp&BQ%=>YK zk%8qXnm^FY1BIW`QAP$cbahzF3pvWjkbtfZ%{-9%>Y!=}#qYGEj0}sQYT@x)1iC^O zrjvm|mVtrc08|Z3)Iq?(K@UwG=)RP@M5yCoU|@JgggVgu9G{3(_m>EDpnE|$jzQuA zpFcqN$B7Z4jumt-A%;2wjBo+n+oX!24m12f_hXq6p-zZ_fx(jqb!-d_4AB_sFx?08 zMa*R42OtN2Qu#_5$d!V7#KJ~mlnYiJ$OA0X1p0Q zFff=9q0W_ofgv43T>wV9S7%^gSc9Ps(_RM#28PQR>M+d%rDx%j=<$J>o1P04F(2=jTq`M-RH=_z;F{o9j3jYbRcyKJzOx&1F7>O zLY*fA149*tI!t>(_uC!DP={$Rs64ntggQ`u`$mL18wLgj8Rf$UYoP>1Ocki9-cr~}#C zjiC;^y%R9hVYhc15$Ztpe#KCS-QHgq>ag3Z0J@|TCHyeef$WXPP={$RDE*~isKYc5 zls|eg)M2JSP&s}cLmj4hRtyXb|A|lsD(@{XqUR4xd$kxC7@9EDVcP2qs`oL}VVVc( zFTBT4hiM+Dy!t_eI#7M7aEY)#K?S zi=htFeeMhl4AmIwFvA&S-XRQinC5}X(+@*zK*uP={%+Dgy&UI}z$Y_5Kag3p2SXipdmj>^4rH(V4fJ${-Cku3b=d9o zAVM9;-Zl(%*zN7YP>0>#^+c!x+4~kl9j3jY`r{*pI!t>(^@k+rl5CW8g_(~)l&=2pzj(H;2#uXm0D30pPpJ0pO=`MiXoU-Qc{$e zR9cc6pPXNsSAs`AsWLt@FD11CzY+qLA ztj^5KEXhpF$*f9^FG?*e%`8eyi3cerN>O}qW^O?as!hrH1(orodBv$EU~|BsQjB66 zC=`=367%v>b5JD`Q&Qrg5-1u#WtW>lkzK!GEw{omI9?o98w^^fuz!K z>%t-h(uFmV!>z+D3(;GYpPN{cnVeaYnTncCkW9d@25b(FJcBRkf zSS3I@vQsOQ^HWeuOt>zbk|3Sf%Llk#JklWDxyHs=(i|v=u**R8q+pMYTw`M_GGIL> zCb;auDg)Jn#Wb+nOiZxIfb@foYW!)kIons4v)?d6@k#OaK{kGP{%OG zaF6CU4!+%n#@~FCGevy5A9{3dQJKNOz~Ir#3u>BscK`J4{^7{KkFEK@+~yy`{Oxm? z85lffbWdpnNqaC~{Qt}n&?JQAI@a#SVHqoP7xch@g=M=ERS`YBIaxgP6@NaXM zaO`Z~z`(%p(iNK({H-6E7#KWz=Ql7gFhC7{xsVCuHFWpJdG^K|kms0EevfW<34Q?v zM}EQf37~-MZc$mlz`$^v0n`V58H>$A{?;(C)8Z}2vy{J;4P-3BVvvO|?LlJb0nOj~ znh_KV@ebr#1v*0s8rWMvfeq?IdUT(IhG<$^8ozuCDBc+y`M0s~dHg@LLJfO@3VcG$PX!`RbYBH$3)k+mAje?M56%A+N*z2}FY&kTV`5-1{^rr!0?sF3Pr0Zd z@|JJ+F^qf#$x_`PTEFqP)-y3MI5z*4<8Sw5f@c`#?w%E($n|7C@&6$xrF(RHfl@oa zAmd9vkg{%f3D52`9^F9_;GlY`07``2?h*)f`~n^V{DPhWFXfmZxwgYe;-wHwS*Mf4 zOI9WZhHiHW5c3x!1A`C3OxJD>-);vEh|!?MEvQcT1Ty;*$nb6liB3m}m!LJ$s7gR8 zAPN*Z9Ti@J4nM=LfM38tfnU&3fnUJGfM3wl;1j=qgTp6&K}Uy|si35b)lcY}URn{Y z6l6TebbbMk0DeKw0Db|71b#us1bzXJ0)9cyf|u{XDa>C26t*7Sjsh;-o-8iijG)l& zbWu@&gvmy*B1mw1bTfE#GQQjnD(-LuVH2tx*o@Z&umJhQFTn7LUyzZ1n*&FOBL}8L zw*yC~Bgg9qmEh-%h3=F$K3y(ayPy7$C=>E`pphVcG z8Oj}6K->a4!~!A)+HwR@_neV|!33=C zJ={EDCYYEK6U@9oCI$v`u)0u}juaIv3E3=Ga-SyN`1z2VFZ3~petMrH;EPcZ8!T$Y!Gfk6-KUjr5f21tBZurM%y zsyk+e1QrGc8L;eb76t}6FzY-k1A_{f^^cW-K@H3jW@BK`1hWd*7#I}5ta)q<3j4`B_^@4O zh9_{b7iCt+!RH)aH$)h_) zr2tmc#U1wOtWnAE=-v4PT#20j4{oNme&g=|r7P>rM;I6w_kh{Q2+yf6&qbLq<^1TE@V@ zU<76@hqErhi`z#Gu%bbpk%2)9tWJv&ro#cw@?wM)+JTG=3_;)m2Gr_>m<+mKQ3)&t zN(cfTojEEJpcqzg3)oIfP#e==&FIk$NdVm>P92&7~Ms;T1+gQl+`VVeREQBXe; zQp7HXi-G!Uknq{Xz`%e%d_3tFK0X5#KDyx4ML2vULc_r6#=s-_m2dY)Pk6c!gq9-- z9?eG#9OL3*4>wpcg3?(8v?M9zglCP`xBMMUj0_Cct3fG=zxNxc_1OB2zvVOo14Dxy z1AogQkO(Ak`Skjz1o(hD4W~W2MP7I`AA+>QyI-^(C=qS2W<)Z$`{>KFV4W^10nHU6 zOeJO@c|N$spu`y9(d_^$M0~o>fs&=dF3_$7Xb$aRU|{fV{Z^_9(u#1i4+@HM}SRwZ7`XvaxWnbVlS1 zGNcj!<7fh4C<8|)DG8t$tb^tW;2#5`1o#BXwV)EXqrv+Nid7&^c@BH?1mw8{OTP9UuK2XzfS zK#_k17WtrhfV{}Rh7|cM|(v7?=gt zLGxmO9+A&R`^X0s1B12>SO$(tQX+pbSjVu4e0JJL{%FnzjU$oT|ND#7`UA~YgBt+H zU=4u1;A$K^xIkj-?*v#Ur1i%^PUN?f(g29<9>k^odT=(zmhnNu$B-%?G^`F`*)lRP ztO4tYfLHlRxT^e5;J*J0=olhNasQ3K;~gmOq2q|4K`xKhxBM-j`J#qe1_u6?wcsd3 zj{Kt@-Js6@2Sn!|G?ZM&M$pJDIF)lz}`wlj3jWVc( zr=Q;q@8{2l_vH7(S?3uT7`B3=P81$>pm}ac#Da#tHi2b5;j+QFB9^j29eQMHu92Oo zkAq{9luUgDtb>S5OfzC}%+=E8O zi0;mpfSPj99vx&t8QiA>7xQis)X4hOAL2U;j$mv_0x_@$THgXG4ni0i7*2t8{2&aIv7^D24`5%wgZ>1WjX8RyU z;Nipc9xt20MG$zPpI;C>&;uIhfh@XlgRa!^gRj(ab3iqdoECyBVzzx6H0?G83LA%w#nI4oUA!49H8Zr|Q1TP3u;H+#$28R1!9c^$i(AC+9sWPg~1PCEb z1+jtC$v6I%+pw+xXg(A*nH+<(1_@3Dfhr&Hj8Aig2ruD8f;km5hm@{B5mL<_5t<2WV~^ zUUY!g27!BrpactUOn?WBF=hveD>*=hz!HT3If()^L*dc-7PI7lx9O2ej#en5u6(hom5>1PSZ^47P+%`aC$3l)Ar+=*v!CXUzOsK%B! zT;WL~9L|bkWMFs!)&XjYLJ~(a_QHkIg$KMywGAUIX@I7Uz(osW`2c#-AZFpg4N$y7 znxA@Kg~&+@pz$7}`>ctewBXUr;n~SIIOCrO zyvi6`{A<8t9kgN{lJ6ZE85lUhI%43mpjk*P6@^Fg5EzIQ9$5pCqTr~*H4rHTmL*~! zlCp^H1r_qp5oS=s13bbU#>l_`>3aHr%6*ia4eEM&Aa^~%Jx|OLW>A&o(G3}47QxKf z1V@-(iZNneUItlRx(nWRba?p&yh*}ErNFoK0DlW;?LBA^+O?ano5RKWWUW0YuM5JL zwz+omf!zgC16xD}GOU}U(?>-Ev{JUyM@7M>`z&ao>O=+x23O;gttacWT)Qu(@yoj~ zFo2fD`Su10IQ~EA+v~vL)$Jqj!?V-l2gpDdYmS=xAO?6;9Axp}8vs`ar>tM_wkoJ> z*8+`@2{bb6f%SoQ_H;Q2(GiiZc3KB220!CTEh70*>z z#RI86$Z3RJN2+*4F_WhYXaWT9>c?rMG(vJf6%Tl~4yYLd+OFf+;YOAD5$X?;x`HDX zTO9=IUqTW9qGbvyAe_KDK&u}ivW2us3ZQgK>o$lOIZ0u7wL$#Av577IakW9b!8&N( z1_4df!A41?LG==7GV}weC;(4}J_F}yZ20STqz=pnE-r1Wq~7XG88nV z2Av88&x?X;3D6iRXg-wPquY_gvy;uE+ff2k#}s%pS7!5l3(_@HIhMf2xzC)BP;F!gh7H|zwHiC7~ ze29`B8zrR4NeiTJlz{gXyB#G6Aoppc=TYDULQAq$DCgRzRzQ(2kycr*~i59ej z7VBPo(0V>tw-Gd20b3%`S))?m(`^IYi!TWuA4J-e{c?-PW9+@QAu#z$pq@G zg0|a(H6C|S0iE{C;L{E2vL1I)Q2_ZCYM4j2i%J5hGf@UN2)4r>bQ+h73hdx6$KEhz zu+uzzx@%MlK-*z6K-*yvVbuDq)B$W9c+2l010n|M`?rFpxd@i9e~mV76TnL0TBb;9uHxG?i)o+ ziJ+w|NRk4rT#kXCVs!!>@~sC-rG2}Pbzg(UD{5FmReN-wB}(;i7nK4~qh!{}fP4MX54LL#pdME^FX&9cwn?aStTR>{!EpPauHe7he) zPB;PO03B$W_Uwk|07>8OBS<-*`AC3cJm`R@=)<6d%nwS)NMb&nTfj$0`SflErDRXo zITxUm3_9orRt$H6=9iET#W49$A_-TFT>gUg+4{CVDOHBc`ofR7aO@3HftGjRxgww5 z9q3>>>11VD$SL8qNSgNksoOQSvhANOcJrr>G) zzhmC#U%*Ah!K2$lf?tpk9!j8k1QH59-H<5pK#C@?!(gS_ z>r-%DSPSvjdqEdEK#sZsT_pv{1kMZ$44~l2{ntz%zz869WT840K2p#AF?K;s%}8 zf?TS5cE5zT7!b#`z_#9?7P?ql4Dp~jC+M6gX#WQ(Erw0_S`46`0Jz2A+kFgNcA~Zz z`mnVaQlKpc@ak4jiUn(gwHQDr#B`s=)?xsyyeoy*&(IcwFZ37>XmQya3e7-x8Vnw= z1_MjU8ia934F=!ta~KTInb>g56qZ(uo^>NF^wJAfM(Au5PM7}PW_O=>`I7B2=RatFtqpaW>3Eent?SV&@R z7q=b&ooC~s;^5LzApv)A_pz73|NsAQ{Z{%0lyDuID@0gJ?!u+PV$cXdYw1Fo&M!p? zA5HcB-~a!h@LvEB=R;f+<3IT9ibHTH=&Y&$e$5gU2Y!vu9-yrW zFF>Usr11$k$xNWvk%?cUM8yG=qT*ts!RMG&Ku;fn2NkH&Rz^xL;-D!v=u(i*E#NBF zr`rUYV)WqJP*My;87R?Ipje0{!JGjl7)WarsnW)gUY3H=OM&A~@Udc$LNSa3M@dT93m=eu zSQ67IP-1fM?LO|=3o1vDt640i&mvH2a&X+qj_8zwbiqm=P*V}3jzubcP*YP7QfdN~ zKI}M3AK&it$kisa^bsLk`h5HM|3B!?pOxU!2h?VOlrM-S=b%%|9`8hD7<8A9bt_f1guAqrZNA$1?5_%*H}Dl(KJ0IC?N z*2AaxIOH5cSPxpD*BP?}E5KIafqW0^c7RT0gjaYapb8IGd}(7(b0yFU55?hFlG}Mu z-ve|GF1Wr!FTOG`s=KA2UI<9N<4*9wk3^SXyr5P;NaJVpLd+kY>>wf4Tp_|yauefMZr2; zu;V?&;GvIHkiE{dVJ=0IL5wH9_6MEz2Rbv=v+@7`|Nrax+d*A^c%Qm^3%Cym8ceZ+ zo9x?t1{$TvqkoVtpHDZ$Md0ceJWdMr8mMqA@a;b0*&B-1GV{bps+&M%BSWl=9V9F@N>!UHSQzT$K`KBcdiOQ3eQ?vdkGJ&k@J8sUT=%h;v%z|xe9$(4 z&J_3{EMi@%$IEI|b?|LZ;I16#uvZU^sPTn26F^7wL((&7TQ-D+$TJ{U?FQ#EP{9r= zFKn43guny2kw5H&`_CvUiZ*Ue969dCRusS^^1_sbD6$^ta6YNOk z04CU}stIsbJ`)4O4zP|6xY#6|y>s{(s-P+(-}of79zeO2fWzbeK`R%o|D}rHGxp!O zbRR|3BB-N+Q0+)}SxDnkjmYsN4a0&?mWJhd@GdD>JGe##X&6=qp8Sw9Jg94pZ8#H4 zHF6G`F)_ymN)tfI8)YV8IXGiF?gaHap?NbL(FBI1U$k+7)&r#+;Ed6kfzkkugx4J| zDxkc|RdNsR6R>({5rfv#hvrmia88Bi1}v%k<==n*|AVf_h8*b)O5>m%r!1g*QJ}}4 zXTj?V(0CFkowG22j<$i+6`%!rkQ|^0Pp6>N4oUZ*vwR`4t?;G|V&@#_h5?A|aYhCP z$e|Fg;HH2&QHUlpRY#FP>)>E%CK|c#M8v!k%|?;9L1iGMxq&~mcy#-yBy@kE)+kZ{ z*u3US5$+P=N0FpGx;-Tzqe!4T3w#A2H%GXFZjOK_(C%Ze+uLVU7(ksoNSTP}MZ%B9VD_qBal!QvvG7&UZ0V@+h)3@-p^FWq~;CoJp zDHB1hKo^w+YL$sept?1oxk7}GgfdYVR33sy*AXM@`~t2D{DKY&`~toP{DK~!^EF&S zH{m!qzzfFiV=s#c*V7?XEhwLY(=)Du@)1}TkrF{SXhTxx1KOoO(8WNo^amP28x-je zbZ;9`EjVx;O1(PS4{Tm@r3fzx=}!`=PKM0vcnWm8g05;pN^7q>;T-HWayC^H+8uCG z!j;eBgY1VFbSG(-&?X@boP&mC2Sq{ypWQzI1ziQKpc5b=p*a&#(D4hnI`9iR zIPeSj2Jj1d1n>*ECh!Y7B=8IP7Vryt6u?tq_pz5Tgo{5rs;0{CcvB_hNRT`5w1}AO z26e@0)FlBO4gf3uKx^*?MXKaSG}7>QNvK@?M!-@fKMAQ)nTS-0oa$-_r@A<*rn+}{ zQyt{25zvA-NL70Vp8i19FVRv!D zL&7o+3pmjkZpz#&N5``V0MESZAG{lnN zxD#|SEKwCSWK|F&BLldd1r_y2>8in_tQ z?}55(V;6ix)QttSFsYjjR5^4zf;bu|qogHZms~_1B~1X00(ZL!xODrmxOB6DhDt$U z1i9uAv`!Z~BGi5Kr5RW^ln)v&g>K80eA)$k-?7OkRjs9_W%ausYD<4pZ>hCt`Z*Iy@6RW@KPs1FMr~VqgHB z_|C%Mzy!NQ&Ko|u84YKp;vDDnManjiwIaxeKNGPE33Px0tgr?hE{2wEpcC&%OOwG< zNuXh63)-z)76K(_P%1%Lg@mO;4Q^X@e*n!^P-We+J=nnJN)e$F)TN)WOoZ0`2CrM@ z0yS1WyV*QC8R2=L``GIla1Qp?X%$sVWPWghLbOgn{a#421oeg?C%%AYeIR0>n+72) z(7+|6M0NnJ-UKZ@^6*Ih<=g$!18FuCa&{bOEZq=3mJYht7e0h81-{nyP4{(p=50RW z;TRtu2U)_&3!1`5h;-(t6nONm2Cd%o=spX%W~}u;e+THUS;%!}{Jq8Ct6(7;tvex8 z_dh&Zzm?b+UxHpj&A*LB%;WzdD;L54rD`6{zgSD(!cBvgdC2o5pex-Vm4GB%8PW*) zOVB~%kXbXRi*_N+n&rahUOP)v9DG0v>p){Y&?$cxP!jxK6610FIA~4{dVt6O;IA> z(Bzv>_i@ke>oA)U);@;TGnTk)>8w%F0NDhuZjdM7mj3(yALcdqG@J{ltp^Q7kk1;x zH3(Dy$4z%AaiYTjyTa6qfq?;ZL?-e|RZy)0xo8x01rj8?fmW(YfU_#-NCAi#VrCjt zt3YZW(A*kC7Bn+04c37e?gd?}3aNcWm|$0qf^Jxb=x~SE8=&jN<-mITm>3u!HPUpr z>{>W$4-*4}B3Ru!CI$x3TptU=FSsl>Gi)|alo_$q8+2KGDCovQi}y z7arXoL3I!xY^FOl9yHPI)42z_XdAp@#}jrZB`DiFFf%Y%?}OYuX9Bvjy}J!Gd*}np z_Waw}S`L(o!Sz6M?YaM97O(3-Sr#D!$+BRXl-9SEs&E-lgP=19eFF8||1gi&)}YC6 z&~gXRDrV4PXHa!w2iNI~eg-W_6G$mU3%F>4_zgV!4fSrXk4k|rXvYpH3wECar|0e; z;4BQV;H&Af25tpjqXk9^L0UV_-|hf3zL|&FzP% z6u5v^V1uvKgqq*_zf=c&dXV+qT4m@g^I_j^J`c#{n_yM{4|_HrK8u>0L6<{@dAxiH&OJ^NmKyx6poWrV1Pgy3 zsAy@hW8`lEO|$uQKeoPG+wI%U=i7Rczhx4r*nyOo6Fk6$r6s7a><*If=yu}pO6F1U zu>M)9<Bkgs2p}UX0bboi!>3zTIa%k}rEOUjnUQ z2c4b)y55rI0=U=(-FyiO+y7x6FV#TpLs-g0#QRI;fB*km-{tQ;`|tmM-)=sa?!%zc z5!FQy*Q^Ey0?0MzK~Zdh-AUl30%s8oV@6Q?x~M3C+_32H|Nm(dK(@sbw9OV_8{8s{ zatoAPUq=4@{~vKpA!y+!q^y_>UnU4Dtsr817#J8p3yoPAp2KB9bEC%K5&|?Y04bwD z_nbm>fXXOHc{GucfdRDel!XCwAv9>E4GROJ`}Z2&2L2AZ8X9a~8508o=xAydhFS0u zXBiU%gAG{rK3wc269a=KSd4?2fdOK&F1%#2WM*Kn2g{bhWv9Vq7r@IcP&uUlTe1k* z`1cdi-2^pmid_+n3wcoXW^m@;#vW^aDTfA9skn*&;-4R0BB$EZLW=3q^rUN2GUASmkuz&j2L9Cw1t zUr_M{x*8bdHSkhdkU?l`8$k{20&ugbv>e`0#=d{Ru{RvLfdJ`xS=2yk{Z{G)HnF)< zM6_fT!a&f4A<$L`+PZ?*Yg)gRih`Q%pB(uG*g+TEJMwRH2iyrXMKaR3JU|M2!v!4(3K1j7HBsXBokpuJOfYIDf}EoTS}g`K*&Lo>97kBEQ4Ca_fRf&TbsEKnTBk7(oV0Lt8vVes_&bf@ z@-#FIviK3akNPJl*Mo=gaE(XAgBB4$N;Pm>5T3(8djW6`9+!ajQNvc!;uyv&!Pt)s zvJ2-h9=3I~{H>r3*BIp+cWz}*}y9mB! z5V6A=(Plu5n<2IqfR=?r?y&|PCJWjV#KHios6eZ$SQrrFW{7R5pkqQOfKwf4fC99T zpM`;>VPw!Lr3BO8(A&o^No>&u>d?|;AHO6CMcd%m$DadEN4Uy1$XR0)?Bmyiu7EzksMehQQh&w}8!j;Ci~sDYP=ppzLP%`eb-^$-@Q z#{_BOalxB&ppE8`eiCTIFGL+^4OKEYt!6SZFhH7ki{U!fGcqth&P7AaA3TA}zQeh+ zV0g|8h?A1=639t-*rowt2`{0!QbZgr;SKtEfhcg&!c`1Hj$9+Ii3i&93F9|6xSZXcL^8z>Cnkz(PN{C;wEDBzl2if@k3A8@y6Z+QoUU&-+ zd$%>8s*_LcXo(DU>pSEuw{`GR3pC{fDf>Vhjv~84t=NCNngIt- zb3x`gL6c#iiF?=_IOzI6=&-I&XAWrIS?33+;!*bK?FMOu=<0Q4^63W4f@Y1Ik3dcD zZ3QXuuzp=4;L&{oqSON-2pVVsT|sEQ6*B1tzC*3M6*TE){NJauM8yI$XkY+3`pfv6 ztMNBS>vE3TXwPnU0nlbn*i^Vj_i4{=8#d&10zTdB;1LGUVkddI=yhaz3EITbV95wNfXV=R{s!n!6X=i+C^4)- zx&eFvs04xRJOqtQ1$cDxeDG+!R4UhC&4{E8Jb4D*oM-V8G$qjbw!+UklcUztvH2fk zDI2Krc+KhB`mIzJw1&*1o989AQ|2Ra8v5D}O$xq_%i^^%sub3U1#NmY08P+XfMyLG zJi1F%JUp6@C^*I)c7eweXd56T)ImoCLRg?FdI;+^JZ9P8@dVnJiDCmhWy7vY&1uYNqB`-==M+)@U z@u1t+L3=qt=ik7y$p^^xOCJ>n==D>m26P{Lt&V9d&H(fP1t7u?PVj&O%~(MK33PW2 zq@Rm8XarQAKx8j6z*Y=^T6hAWlqvy9so)U%0NNklda_gmR4#VMs91oa33Ol#D4L)l zW`G%D4$u&@Xh1sNP2@v&5l1PicR|6(1K+c5@mkNZ)6Dn)NkIThLy&`PK<+}!qZYyw z$ZR-kDY}nyRFE?$*xMf+K}#2Jf|f~uGbkv@;q)zkM=Lyc*4Dz)hzV%bTZv!uUvOp% zlX%V1`W7@m0yB$3p@(OQ3M2&?fP)e} z1$lr{5GchOIL5*9oCEekZ#O(x`FqzR7kc2JE!6=92I5{NpI*=o8U}E9K*!p_rJo1* zgjSDkHwBN@10|u&6(Y=#LwgbPqaaD2ZVwLVx;5~LrwAim_i zrPLsBl?1vt8lsm4UO0kI*@K9I#_kctBvQT~Y_X;Ri#1j(v8F*xtnqJikbq{WfrvH8 zpGJyK=mZJg<7&my8Spm;Zpj85T z;7kO%zyp%mK*0jZI-t$B5LwXquaL|JTHgrMvSqzP6 zgB-+*E7~BkWJlXzt=Swv5eKT-c(9a_4n#y;-~gAAke%+h%1DST*<~aw))cU|N3gbN zvA0KXcETX-5mnTZ3fh1Gw@0825zr}Z9^Gykpy=`iFUi&d=|L$TGeFS=(+g^OK=i%_ z7m1+t*U)YQ^@>DTOAyh3#?=5x0hfvE;N>J}&1gDU>@i#nalR#DS`Dsm5(5@h$r19jyg9Yp?K&=EJ}M%qkp zpTI2u6loF76(Z0px=^xH01=TE0%~pGxDT36O?${BHm-<+$RZ*Rk;mBK(FHo23KE%W zj5xaVgDtm3fFcf8Zi^ry;s!XkIe?2kT#*KmMMN6uxeYYXs{mfP2dTQCXSafiO7N%z z=xA7I@rXGF!`}fqm>rhQKv@ncoB4G6C4iUsgBfe&Kj4R4co_k@ z;SwwaT6E0>vI})E$oRl(2TV~&Zs7NB?E^635v9(!v&P@3b@eGD`aavmlS?bCe}MZgQBDFa2w{4>8m zh)Mv8n6gi|i%JBFkN{X&0zwQl_G19*rX!l6@rOan)z5$zshcq{Fo1e1EDY}O3q_*f zr$FT~Ffd#Js{@S=LDoEh8Zw}r(JTz0@mvm&PaTX8fRFB1aI^JsM6a_n{Z@6r7e zmk>#6kuJ28b+Z z{1Or-4#AL>(4e!h;TN8iibI>*;C&3>3o_!OJ^m*;fX>zD0d4qzis3#W-47$+rNs6Rrbv<#=zYf=BB&{#H;Gfj<9m)#z7HsMPWC-YJf>J%u22#*XCNLSWsDwv%7-&5-I1PAoyGekr z6hXP_=_n|r7J#69KJ%hUf*I5ddLlqmsAj3TK;LWWSD2*)8G!rDNy#=4L z{sTH~A_yIcD**321g&)k&G98byO(fJgJ$?ZBS^5?8WaWaBvb-ATa@6sdc=ZEgk9Ly z)qD1C1MQpg=w|b1Jy7Zin(u+EmIob=>(cAN1&t=qR!o%S!ROJ<=F(Xq;o7+m=xA;N`pV7^Z`A9Sw})I3n)R6vXNm(Jj=fzWAA%$NtQiC6vq|Gzyvj*HT9%G>4IEXq>&ju2opogjsR@{SDMdB>(9YDnvT5%5+ z0~hyLZw3M-C0JhNM=X#8mCy+u1j>5Q?iJ9MXn6P{pJGts(d}yB(OYT&D$ol+IkXlW zr{K+cppCFDy&jCPICW7`faOr|IRT}*pnY;4-E5Gx86Kdu8Q}Y%Ji1SVWcUTaTLVFb z3j=s(Jv8Gvb{_*R>L>se?g^lhHUnB(MIQza;je@{m8hifdJ|kdW|oE(=5Q;Zg?R)x z10xD^#Ie_)Y8(>(ptE!!2nHr+b2c8nbK!;v}O$J>-4oN4V(>5UL zKnJoxvOFlAfTmF(=>#-m>Dzh$saX)l3=WYvXtMycfz$XcsC6LN>&gTPHqepraiGIA zaP6D=hg2Sbrsm+~0m_+|IQC5;?s3dfNr1WKFxK+D+ug#mw;VK-Um6NdJK)`R(9#{A zc5)DD2VD6}fv$A~RSJ+B#6Ubpe!+IgQWI!8={^cRJQAEHF2LiMs5J2svI!h&5N5If zmGqzkq(SvMBq_we%Y4w<6-a~~fS37iL9*b81r-mFG9QruK$|xqI-D387$9T*ph5wX z01%6NO5p_ssI3et^TCP0_?t)aE6^gH?wgLyKbUK@UAs?!_L6}P8%A#3zWuycm|LHq(nu-rPqT8>WR)0q(lH(mcr-R&F<1sAmP%v zbqm-r(D(wC4>c<2Eew!%n=3?kN>0Mlf^RoJ;aVT1d^ihr3*?Yv(5Xcpucw1f?T7}) zE@%}Cs6EZXFdrWGJK-!)>kcwE@E2YnNWn9|Gn@swE(fA61m2P>hRfEXqymMoaPWwW zgDdEQ#9xqebwDF7u%;ZS8R`H!IOi~=xbIyFTJHuw^8~a)5Oi`WY=z(zMD+k#A(-LQ zt@8ulAvd5MdyuXG^q3Q*>H)lr%d@vO16(`!besEvdH|qx8lYCC0jTK@ifj$nUO!=I zxVnJ$7Q$)?-|o^3mu}D@J^U@87I1?d1AhysISf4($K(I;1{*tu((lmoaEglH-tvLp zw}>>K0j@PbD;qN)Wgue9cYNGo$L2Z_;gZQnCJ>W0*0{F*FD>%yb_1O}qvm2+!BVFH zn)LALKJEd(@c|k#j@`#!g07YY?FH3_+XK=I^*s3e2511dbb~q?FFpT*kC_1n7QCA06L!*A_h87z#J@=1y9C{7-7f8tcE9O#9G8Nj0_9~U>%?X?jgs< zFu?bp3&L3vObiTJV0DIYF>93F>5z4dpyDyW_$@!^S}~90Py8C6p#2>1a3sj}poEB7 z(tYFa0Nv{gYcib%7cS6}P6Y1>W}tCPNOpjhMabC!)HLwucJlD(Edov4lsbTlWdoO9 z5AaZr1~leCtMD+|zZ@RjY-pF~9DNNLihc?&&WNhoUL%eb#9FU`8dTsbY{8kN0C9)V zVOvlo25#emhBP2?+zC%9pv6y+2^&ywL8>^=L3a>!h#3ITg_;m`pp^%ZDh}7UCDJ-K zL{kS;xWQ)L5V-=gWZ@ zZY-USEO0Hx2VSy*OAKfd#+poCKL7XsKj=DDNQqGnPY0l@l0X5@!T`Ed2Qm|cX#f6z zs{>t^4N(W07J#S&74nc2fv5~Yhr&RbSY_}M1Jn|R=$(L484l)LAK}qk1e!n^ez_hp zaYQ)RL(~z@^$KCI%dfy=Q$Jn1A3%$3A?WZFv`ym}1IhGQ`@EpdudqxH>P^8iJ^b!R z>_eL%Z{RGzK{NK>-B|wq|No!A1+a9w4m@OW=~MuTyL48t@Na`$k*31Wbpj;j(S5DM z191`73wZtoo#BJmdSsU{xK=#f_SVDk{iJ%A4FhxDJp-6v4ttN>m*?f{-%Nd5%rLxGOJ1)ZA*iq`;8 zxA|l#Yp)~I>kv>|0c-sN>IuP;8tAYdcv6G46>wB7H7XI%`Xxq%h^ob@!lSncG+$O~ z4{|%G;lKrQB;JMtJ9ror`L4&KuUo-`pU>ctMpV1ur4QjcK@+SbMkQefWN$@@3aoAh zO$R}0iZXZ&uoBJ!4T(ag%0Mj!NbKXPDIn?)H3eu3JS5IN;B^6`6$gV=2^)hz3I~IL z2|I&;5f5nnH-jZ;4-n`wMo?Q8bhs`9$ep0bW@Z3&S3w6NGBe=P4Vs^ZYGwd+*_pw* zAuN#YU0@R#ML8HmQ#ct!LpT^jP1qSkjRe7V8^W|QFo4|w(G7AD#O?!N-HNPC46G%f zWmF6dFdZPXA?kSGdO>I6Lv(;tsUZ0aq7vjU2n(bel=7JwK!*>290Ae+qEXdARD*1Q zmKIR}Gz2`2-u2^Rye5$6N;1UAsX7{h0fHYf&}1o1J1 z1#%VW5*KC$V#3QB95x`kAuNz?(B3j;23+9c21y~Wz+zw@r+}_cV_<;k0J#UE4&)vP3*=*n4v;F)q$JFEh&-y6BqW7ESRgxKsrFGQPn_HgKU793o;Yg#}Ii`JseKiM2rMLV?zv}76iy15C)Z85FbNWAXo80baSyVaG7v1a22tEb%EAg zfOLQ`Xx;##3&H~F0v+1Q%)rRW%D~ygTELRP9Kd7%Qp>;qnwo~N7#KjcC`2cO1=1-6 zwog%;g+coY2LtO7&;jxYT_B%B)Plkm!UCNq3eg2Jy9Z`C19tO4hsc6LnT3Jj3I_uN zN#=vhK1#rRHHiB`;q`@$f%OSH1F|k$?uY0CnGNb)z^s7y4-}ga7ASmlAm%eLpqPuQ z2BI2d7sOnUnc&@~P=g`zsCtZ`<}zV~3CLE64v>iu7AW)~VGc4EbY36SXsmH+0X7>_ zi*Yarq;N3^m~b)(1VQRRP%R15?Fi0aAeTW{AiM1#y7|}`_)Pd1_=>nba6DiGAHN1F zIbk|M1J#hU1Yv=6x`1_p%cm0X)+Ur145AL?CkPAVCx{M^xrs1?85kHK@*r11SRk{# z5N3z)fX#*J0Lensp_&cR0a688Jq0r!q7v0?(B+_@GzzJ4K{`OHQPn{7foy=73o;XQ z!6`^32t(vi^?(jb2ARvkzyJ!55Rh(&9UvVb9z+)?Bp@tM-hzY)$ZXKmK1d}9L*!A- zkAZ{Y+nY0E7jKhYYYTMGF=Niz@;QtR;}r1f~n*7KmDqk0C6Ok0H81sz3+D;xj)F zVm>bm1Md?-2G$Th24r2h%!lX#nGG6P$7g;C#C!$@6mvnL4sk8Wj}R8fE{M4xGeIMr z_{^<>n#;k!@I;V-;feqQ11M}lKv%dy>;mZqg$2ZP(0N!87U&ciNce#4n2FTRgUF-0 ztpREe6U2O|KR{-qx*Vbx6blfuLFS$yV0IhWY+_0k&>{s$%7CyycK1MZ^RhAUn(#63 z7IA)nwGv@9FUXakivS@yAuNzi(3QNfb{;6yQCmF_bs%vF3*;w=4v@KVAVZ-TA`c2L z2n%HP46v)fCDs#OaBB*t10)MkhiW!N2S^oY`3}@*28c>jv*$s~22J!ZFff30fK;QZ zf#?I-05KP2CTQ#cq!NT7@~C>2K+R=gV0gmIz)%9xjR+GE526bc5)c+BT|vSGWHzY% z4Kf>qA@Zo^uY#HnN<$#i5N6{F6NuR$b3x-QAag+&o7o${W;0rFFj$muFz|w>UAxpxPXy5`-c0sCv#p&1GX?c*2KL zJAr%*(uEot5Hmof5+qze=7Wyt2B`#Lh&-wtSDY zAP+$?=nzkcP6!L6Qw*#VoK~Ur155`<7NQR1I|vIDju0InRiHjD)My5XJjhQF7D%@Y z!t5`+49Ge_vJiEsW^U-57=B>c@7l9AbUUzDnuveIOek=7P)wEoK0z1Yw9gs-7&UxuCL@n}Hz&GGYnxEl3B*EQl^pNI+PiJO>FA zklCO^yg@2K7$T2qegV{cP@W?tyg}xI&cOni3&PmU23`3)*R!UBaJLDZitUDXFee6K<SrD_KNzV3-*g!J}mSkWsP&n4@H%LzyA*3t@q5TLy6vXiOX07lFA7Bnwdo zatnk7@-0LMNEPTz50HyM7$OgH6@&%Sy#``7Xf*T*9|J3NqztAD)l`TsP@aS60;vL} zVUXD%43S4Qe-p%f=tvVt2S_EV8i+oST@Z6YW`d3#1gQjJh&-yE9Z+*I`y(Jo5P6WRAS{sX3kb8X@G>Cl0Lensp_&cR0WudfHw!Wsgdr+X&Ax^( z`w1VowFc9H%WQ}akSfr;KFC}U#%A^%h}qCqAV>#DC93@peIVCE%mtYV8i4?*1Yw9g zs-8!1bCJUWRSiTR$XrNRfXoE7GC*d6Fhm|z&kLxz(A0Z{mw^E-E$!mLtB^7)&WchNEV_F6cZ2@C=4MwK&n6+ zP4St{#scoyflFC#24o$$%!cRynF|`*$7ePV#B9(3XABGsARQppp!kBg6x9ZZxgaw^ zn-f4PK^USERgVzVT+|j5$n78Gh{Zv@r8zc)+ z2XYI91xf)B9UxV(5mk_@Ao3trL0BN&S_reTjO{|yp_&cR0Wudf4hu3Dgdr+X%{G9T zjb&^Xq8emBgaxtzVlK!`(D*CJOb~|1qnc|5H5d2TE<_h7Bp@tM3V?(O$ZXJzFvx5W zhRCCuZv!Nut2sz%m$eYx?TrlE(k;9QO$M&n+;hD!p*>I!o$ED zgjfrLJW>K`O+r!vgaryM4~T9=4GJIY0G)UMvJ-?stulyC2n(ds53Cb84Z(DPWFhK6 zeuA(-euC%#sRCW23NjajA@U$UL0BN&Aqca-@G>Cl0Lensp_&cR0WxhvbjVnwbW`oQHt=0#b3&PmU&HWG-k-5o9h1LsX)g-2yS2fdR!_R5cKNAR8d&g3JV!>L4>g7$T3V zrweK>C=Ef!UZHk?bb!o)=mLcVgat}NkT3z6y%s5rLgZ1+p8z!r0NaSTo4732Za}e1=76&VRncB*j$(nkSs(U zs@V`7AXUGRd<;>EYW6ya*--a_bbwress^GDWCO%pkeQ(T3{nZg5P4KRTcGBG>M}tF zh7gdC5n%!{3!)1o4q<`P5F|`MX3HYAS|ReN=7V|@bS75Vor6J^UC;^^^AS_U9eSqi&ry&6b-bsk{ z5}@M`Kz4#K=;9+t8iKGuI=_K+LedaqeF;nlNEV_F z@&wG~fSSt!S!q{-8YUpKAf|#s0>T2NAxM~j%zjV6d_Ji8pfrSPHm)#%m<=*l2&o)` z*p2F65wO|Bq#;o29Fh_sERfw&5Z$0Ol)=KlF$u9Q)EpYeAPTgu2%;0h0_ju$>x85s z$Qmw~4v;KF9Vp}=EKtZnbbwTW>NAkJAPkWQ`3b@T=~jc74X!5z7?5>+P<*&Rbc4sa1sM1yAy$KeE^P(b3BsxH5)8ru>GT5Ygrp%zzJTcf$wJhD zLJqvl$pr%tciL(Fd{tVlK$cw;%(d7$T3VCkARRYB>aQJ4h4AEQl^pNI+PiGz19~ zklCQV8Av4vL*!A-PlB2cN<*ZCH^^Mj0RSL#K^U9a8DO(|@bNno>ar6JJKCLlk6a0WajKv*EVXFzm=`ejAnei?j^1L)o)kS-7g z?fHbHJ_rk>a~@bH`kG{zE>M_3)Pj5iVS&O7q6?%7bX5h&Y!HUXgZu?yfy`e5F&|u? z2{It-0Lensq1pn`0Wue~X9#322t!n&n!O5QHfTQ(0|Ns{2S_EV8i+oS4G?odW`a&O z0I39Fh&-yE4N!AIGZskek)ig0bfJa@#0=1k1teTR=0_vNH$)!Qj%`poKs!GWbtWi$ zK<0zo3(+Sdq#Nh)PtmZ$Zpv zfVdZ=1LO)+H4uFu8zAO_%mf|Y4N?ih5P4KR51{6P`hSRZTOi+pbb!o)=mLcVgayjG zkT3z6{gi;apFzzBr6G`M5ch-3#uX+Ivq9#9_IZI+f-uBxRJXqYn~f_C%|>!r4!pdB zut0Wyg6PJQhCqFNkewi$3)cx@fpq==>x85s%&|3yI*?x>EKtZnbb!o-_1tlp{SRR_ zmN5i~iKu2nbb!nS_4h&Mf-poSD7+vnkh@vfVEsR2m!PVFs0P^pF&AVesGkoq6NDl1 zsCu}d=7Q1?_OVQeE>K87SfDfn2@{anp#9?@vq2alk7~XE)O=7HA|<>*=H5q21=!3M z1DlO24Iz&qfL0PhN)reR6rwT^-QYBYI)(tcSPkSK5C-k2hv40B?v?0QO&o4nh#1tq=YxfTw$cT44c^wV6$h2B#s^x(t*{LApS=5MB;JSRkD~V4aXOgqbfO>Odg}VSz#pq61_usJsA~3&Ie2 zP|@LIH7Rc-xgxOfq5JVlS*$^G*X$Ybc)$AsS*;vvLL^a5M2n%Eb#9Z_=1d&HI zw*zV}?lc6^1qulW3zUW+VFF4+7m;ELB9Cf*AJly8X$YbNkh!1}+dyd( zgdy^%W={c|jVlc;MRHjQyflHZK%q4YqMJY(0`(#xX$Zms>0AKTi7O33)Pej2VS)Sv z(Se?ZAo3tTL0BNOmm$o?l7=AaP|b$uKu<#um8fQ~ftZaY4M9|c?1!*GHbBfpPeTxS zRC6~$&BdLDAi6*y0bzmC5F|`MY3MjoOhM#P&EEkvAA1^t=m5DG!UEX>F&ktq=v)a< z`T=2xJgV9Iz-Hr0L&!T=L1%?QQUZhp3auj$-2~DQXiOEN6T$-NJO$Q?D-A)^f&2tv zf&2u~fu4pS@*qD!SRk`6Ak4;+h9K%t&4%bePeTxusAgY-n2jY3K~#h6hp<34K+Hu? zLlAjXbMHXS#hr#Ax52(+dM6b~Q_QHg4{ z7Q}2UeWbSzaX4`SfJ2yg6QUA zW#DRJ`+!)b#K4dR(gMYxqoN@?AuNzi53o+~e)uE&;4?Hpieb7yzJaI(`3AxQg&9N_ zNEPS+Rgex4hRB1$48j7L?*}m-wDS512iP?*9UxhVI#gRAIzXzrk-`k364mSwh}jGf zUxIXiT!E?vq7P&P#9WY>pmPC1DnS?`kE$mMYA$Fz9C}I-^lT20k3qUnLjz(4XgnMe zE+F&SKnE^^l!9gs;dvLL66Es)s2!jc{E$9A%xsV>L>jR}~Y1~wa4 zS^}L81$7uh9o%IQ7Rc@#h;D8+2JRyE3&`h3!FI@ibb~IHfutn}3#79MtP{NE?Ta8t z5qz%~NEV_FMX=qFbPqKYIYsOZ19|o00XiPTxLUbfXwAUN~74!Zh@H1z<^>ds{IgsAlF081)0f9 zz}zmlxyYf1%UnoUfXoDqKY;^+fq?;HFRGpiP;){1>;)MZo(MqJ$w2pbfpmi64WbiN z5v=50(kogml(kDb7)sAUUJD3<4NJ=LlbGHyMdk)xaTxowYQmBH?35BF!2n!U~ ziy*qe>l>i^_@JjQK#w=m42}7|F*Fm8fQKftby}fMPDH8i+oS z4G?odW+Jb5gUF-m*#$Khw0i}y0}AAJkS{@IL3Dva0>T2NCP>I3NbNanW*-BajVlcyx96JRY>>Ig?Ky}%s@WgFW)qW! zK=a3t(geZ++5HWon?M=@&GkAYlSB8x+?dvq2alk7~XM)O_q|2%-bzVh9Ul z3&d=YxyWe}ZP2n(cJ2VwRXUa+|^9UxhVI#jbEIzXyG z{T-0GAPiB7YPJ!?YzByXK{`MxQPn{7foy=73o^4Gsg8umqw2AMnhQ!ph;;`b--65s znFY}W3JC}cl!hQ-0x}zUUKb*dYQ7!Rd{7z!nFet`$ZT9;0x=t8F6i7^kV+87X0{91 zY+Pvwc^@9AUW23|2n%Gl7eqIfGz2OyKz4#K$P|c92n(b$0IU;|hA`)!AnHJVg|I*& z2hjmC7gSz=%mrbHJSe;%ERfk@2(z)2LlAYSWLjW|zgdy^% z=4U|72c;oW!W(2R@*XN|X6J#;#+8PU_rG+(OA`nS6j~(^-2~DQs9z3ALl727XBAi{ zt~3Nu2Z{v<3lwq?9q4HYA`c2L2n%F(1Hx=9X$YbY)oh3kP#OY_iG$(+gdr+X&2EF3 zjU^31RD|@rNl^2#ry+>zVN7$T2q_6)Gu#H67fcp8GRK%q4cqMJY( z>V@lsus}MOfOX|@LZBTP@ry+^fUyKM>YEp*lb*B2zjmsbc!0JG=Z={p>+bHn?M=@)z=W65Ee-1 zIj~M#X$YbYY=M{!GWR9{v)_Qt#+8QFA?XI)B?USsnYCiTf1knL({{U|RPXagiu9FUSkh>t*1YRpaSfCJ-0h(Ug8~UN^ zQH7M$;^d;tf|C3qh5S5);^f3Uu11k@XPg(BuqcJ(%t&O(xFn(q!W714TblIe=8QLed0AIgF(=fF~8C zWT=2A`KFNNwA8$^+{6Nq^{5pCNCd5Tf;))FbW3EK#mE|IIr)htWvR)aq6|@n~x&$tePfEdDY{3p;pf$WEV}o&ua*FMJKWj;sO|4&lMyVCFZ7OKoMNyPJk5Y@1h;ZP z{WFO1$dwtQYK6&xdRVw?Scob}DB-ALQIz1#m(ci6PR%S!O;G@Mjv$&9GV|b`0=GXP zVF8s?O~H@{^$JolL1C1dSE2y%G$>?LQxx)2%R!wx9R);gE-gq&EJ`WfM`U*g)D;Bv1c^&YFxAARBA9A;B*U8kC7HRY#J2%ps)@A~Vm79& zWyE&u%8ZC?+msn)VzY+G%C*dh$hx)62usykW<+GoT4qFK#ad>BrL9nAOk{Jg%$V3f zGsYHZ#I~}^jEN02V{Cy&Y!j=@nAkuw#u8}x1&M{FM7D4tYKcqR(1NJ26uD`kT1=c~ z28ITEk;ezURvkCJ_wL0cg~;$*Egs!}i&Njsp0Qx_HA|V>+|Op~WXB$hF$|1hS;Y2U zxL}6yk1Kz^avu(P<`g7)=)!epCdZ(u0uz4JR^Q)wfPF2SwdP*?8UG`?r{+vx^c>5WtQml zoH>=r94%o-_D4>e)9W$kz?DU9JPm4fUe-5fW}Q$yCKWIHoNdd5e6HUX7IsFW`xN$^ zc5df7?W_JemZ_j=qABa@RoO!fZYw5jPAHSO)-COu<-phx& zmb{1BUT+L~9QJ1C-o>{Pc@D_j)|$GJlgW6Ao%%m#+BmY__yA%dfSf$I1jBqHraJ~^gcjrEV z6)Vm8KQEiDTxdKcK*G<;PGwcX#(jQ#{U;~x7JVkX=|^hT8MdPm`8ux!yFQhQudv~N znK?gMS;vm)Pv94+xE<3ce%1OHC34#+E!~w@=)m%rijTn=uMHP~QzZXYGlad#N+UN#jx4 zt?&%VZMn8`@mGz$-P6~vP=5I+z;XF~zF!81)P(jub_`ks`aC1@1)1n&Z%;ROR)Ngr!0x4tGp`> zcBnE~_lo>E6YlqMYh-gmbN=ZGa*XS5dL{39O{)6c!q1MaY(AiK<)22p1&hT(rlRF{ z^J>@F7XCiJDEMLcr1xU(dmFU&9xVF1si|Z&ZH#gr``^vFy*PRce{0?w8D7&6A%j{wb&a(T=~~+Uwsnwi^^Zd6{E9 zFYL(T`^oO>oN}6`EwmS$pS@lB#WnEtEe9`cCO^eujFxFT5P=iP|hgpIt1 zO|H1=o_Zt}_t;=km7=OojN(x#_Loc9g9}zEEX~Rfuzx>ARN}^#3Dd5B-*Bkn_}j+c zQ|dPFRLo7|=XYr^osfp^ACbqu?iw?%mxsk4!}%Gj(4K-%x@u+6=Y>~G7FH@DL z$J+E!;)Uw@)|IO7*OaEXonxMOWE$I(yfdDk82TI)d0_qvYMwD|qnnWu-_NzLO%6YM zsjXc%*|*oGp!vXN-6_gTnrkM7?AExu#`VU$NRv$^4u#)8 z1@L=Ue-;o35WI0LAYY^j-M$RPI|eg&_L{)_mm~ja?RSr4PsK9J?E$sC;h7E3O}HmC z)j!#G-`u7<^{8{|x2CAoo%UbJ-ZT!RCI}NwamR7j< zC}x{^(wT`2rw)a8oh~l=7$N>``le;`E?h(pUp2>NCw6ye85;_#Rh|fRNRiH4qas^6sNpeUg6R1qCFvZ zd|lFZw{3h9(NW2y*}re;ClQwKF;QYpS7G)|J#2OF!Gw@EzxQVvnPlgr*1TIdQSRia zd4BJjvJx&I)eqwpn4x`L{@j+pUAGzzKfjmhU0r_ef8=VI{_onCR{Ub~oc!@(>Mu{- z6U&Wt>i3!yzP{Q0{Q9N0m8~D&&X+%IzGUv=buXm9K2m?RFa6(r3$D+?cU?RmU(k#a z|MGn0-bi7wR`GfFegw>8ubmzfKfB{r!=!5#V$yzZXWy6JK3(?Ep)JXKVfK;h-l<;P z7aO*-*TC{0tb9A!pWAW5R{1Hcd@}j%<+MY`V%Zt7On&ZKj~tkKSbjaRk2NpsX7nGk z@LzK7w#6n_oPTbtnywgAbk6CMinNmR6eq?j!nHq67uV#wt@xs!-?Ybe8ylnZM_7JM z5?aJ-8W23aE$U{D>yPqxZ(ij!Z2Mi+)BUnUq%&^kVsBxIIDsAKCv&*m-@e#((un`_PI~dno-}^*yHQp$P>jWxN+U(E&r?vs~R4b`kwh_ zX?MEHvd3n}Dn&l8UdM#QEp12od)|JKdZo4G!-}-KYL9Ntk9~a-jjG!_2Ly7fizpM2EBHulAw)G9C9@4W9md`PzgR$ge?DE=;r z$~ZEUp;|rql$yyomV2Iw(r-5lX5IejHo5S!Gz-h2sR5_CZu;BZd(8W#+Tzu{&_tOt zZyQB_ofZ_ibT*@WQU9B|eSbS2s?a=G>8t*?!{_zyJ8Zc#XTP1s zAill+*L1efvxZMDZi)*`?mCz&ZQo;)aYQP;F1B7M{>!nMVj0^zcC_gG%{UNhWPj|_ zgLh_ktzKHE!|dCjkp1bY>hV*1`%lcM+!O!e#QkZudg+fiN)=9go*<#|!EN=1>FKJU z)|;>dPIRizP+8qNjq8%ZfvJ1nZ*`P2ZPS@&@_msBvq4SJPM-78)=%QvR9;Wbo#gUP zS>m#m{OKPKn=Zb0TEEV770f9L%lqnDW^WQ&x+jLZAa^uEDv+te$vY6fB z8Q0>gi4{KeQ+^+DzE@gx?v>l?su2B{R`K$&R1%QH)Fo}jQf8jtnto1SYHpYxCvbLK^8OXe z7TmEpv+?;)KbcQQTz*v>b{{xazU(TxeHZ?J^{?!F**kI8_D$X`J8s)GIZsqi_Ds~D zz3VyuGw+MDOM~ACvNCyYT>7w8`H*at()5BYwf9mR4D4^Ex-;(FsM~)%7#%MZ);PiJ$LI6^nCCAz&SeI(Z$d(Eq|u3aTrmH^@ULP&oxbpSmg;zE#kl|m>m-M7#c9)=JaG9Yj+X

OH!J@*rtE!ti0bx+<^pI_(6u^NBh#IJ=1xEH5AuuIeZ zv8KtmbK$aW%X<$_cyo%m_HVm0o980#7?^)^J*KRjVbIFX9{-S4k*5N%b#Xt0% z^wWFP_9V(l{Eb$FQS|1CEAW(Hwe#k>NG<;zU9ySm;BJ-*nE!0vciX=;UAPTqUv&RAHkM3rTWZ^*nZa5q}WOKKDJd zG$tr^ucMZIdYOG$+?VZgVD|mmb;qX4#pNi>zSqahm!`e?bd6a1rkE<)^5(mqhLzvC z_djMY)}OK*R(`*>OOo-rmA?vR-`R}`?uIJ;Dlq%bZAsaBOYe>_vGx(F53lGL$=x$m z*#Wcf^S8Ipoz#-y{)3e_G0*E)&$)de|GIZ(*~R7>g{6Yq>z5q8r?t5)d!2uB_@#h- z>T!`qi`jpR{c%|!74$2sRA9p4aKBR>{Cxuqc(v+41nZSBqT ziUn8gediW3X(e~9$tIZpw*5b77!{EqrkG}9bM*dc16cbo@vzCMvIc{%nVuC~I%2Os zFAzy~bTXNlxn*f?y_lt~+;xZl0<)ip@RxmX;rR9SDCgZR&WTqy{3$MJJ_9~(JgHV1U)PAIQdyd}rky_pnYOnsf{g8d<^^Y51<GliG@JRmmX6J!?tw*}C1SZmT#vl1xN?MbGfMvPxO(D4)Q;4e!h@TtAd}TE#u$!yZPL zn?GWGWS17*nxS#^)G2NW32vcv56jzGd6^1I_qA#7jo$ERa<;IiveF7N&B z^~f*gRqBCDJ2X^gMlNmL96dulAk#SE*uLj-lcQFye6urMaJN-f!}Xre^4;cP(KlKM9dI<)IlFF7gM_sR92RzrKp!}E(zJ1`eb==)c*=blsS{1q$L3GSI%rh6*n z@+Y}dd5hXSR@|w(`p_ycqU4)i_o9{zgIimF+M55mk-J$d(%Dj9e)G&fPj1fnsd~ow z)XFuDIoIC=-0;{fXcGR#X(6)hu@&*M9UpSEd=n%f_TBeSGP}y1GI|epBz^9If;XcQ3K( z)Vech*yp7Dd%j;sM7HN<{hk9-JQ>Ol!#ebh)`Xqa*4^{#;5{yeAC+-RzmDH3_`RPi zTh8d$be7h|GqzTJ?tZ`*x6{S3=`&<$Is=0PXa%HRX3EVH7RLYoK}-D|(oz#k^b8Cp zFfukkMD$XMQj<%{QbBq^`y-ecS3z!XXD~0m1X?){y7)3BHK{aRB^aazbh-jFBj^fJ z5D$U%N>VFIRC4n`BA`<|m>EIKzX~uC(HDX{jpd(2^YE-h{`C_UO2dkL^ zHD|xl%N9&EphI$)89|$?LFRn7OU9x`5^N4EoL_DLZAwAU7gAs~pktgsF=uimR1DKD zX|Nj5aW^2l7+D4XVyck=tAV-an%G1>Of|A#HK1)#pm^u_bKVbAjT~4FEbq))_PG~R zjXYQl%&sH<%^zW^Q9x1SclToyrW!@C8dx}gmiSPGsYVH`2A01v?sP84RHKZd=Km8h z4@@;GU^Sr4(V%dCwf~AMrW(+7%*>3Si%dbOZAo=OE~XkausNVh20=Mw`u^WSm}=C) zYCxN4L3SO@+PN50jRsf^=#nr{Ze%_G%NwB`)Q-i?I$$-R%QHZ^Xcz0n=a}Z`g4KX7M*#W#Vw%81Of{hE zo0%CwhZ%tUZmXtu5>t&n*c{N|<{-a2g(S|zRAT^E13GvZWX|(Vy-k>EK!;^9GlCAd z2C3m|OJ9ho#t3W<=-^P0nvLP-USO&*2CD&W6a%Try^?~(?B5(5p?JqsB|!!c{CW)9MHvS%#5JJu|TDRC5QYwOf{gb zgv^Yf!;e65vAjUe0aJ}7ihH)c3huyEV+B?N@;fLlOvHaCV5+eOtAXX6SqUzSFx7xA zXklgq9bf@UV+nQM|1s6rg3W=2kM-QI6_{%5z-mAnKS5!5GC$=2rW$*&8d&~X3pVXAQft2xEM0J?jfLC=(*1yhYHSd9oHr2R8tX)Bic%MGjsw6PadCe)V)KEX7{ z9Yu{&Xt)BV8V|4<&|w!KbH3~p#!@ePqNthFz`O<1951jMn0qd&t6*s-c!SkgGBPlL zT2${`q^4t<;{#UX&d9(3a?fdDe^X2~zF;-pP&JyC)3MZFeqc2)a}w>YNMoAg4^{)Z zq#D#xj4(A|!c+s=`N_-(Ge@i%b;oA zFy8ANrkZfD8dw`3Dre?zOf?Z;HJ}aopnAue%XBiPnnVj8mwjsv|L@~Ab_RpjRC8HnNwP^KLgX8Sg@K~P;=H4RbXjL#DUd- zE;s0-WUB9sE7w#1azev$ht7N25U!V1kiT5u6bs0bfiLQ&`iWtB}OrauT za1nQ?h%sCw5-K7J7s-Z-7{Ntqp(5gN5ztkPpp;+&7g-KfBLNrL3l%Yii(H0^NWw*) zLq*KsBEO*`Qg9K_6;>d-%;6%2pau{F1A{bN#2qSP0T+pdipao4ilHKwaFI@^hyq+> z7F5I*F0vXbA`chY0~N7>i=2gu$iYSKK}D?LBJZIh%5V{IQ;&gx!2vEJ2x=%WFfb^= zMU=wpa@V2C7Qh%{k{EW{Ami6L?cL*y%lh$yJZh~h#+3=v-pktz(4 z*%%_*Fhnk3h&;j&VE_%CptwgAF2Vq96&PTMc*8|t;amt6VP;TZU}nfo%}p+-1RKi$ ziPPeeqU78HWDyk~KVwi26C?&|QL{0q`1l!t`pF;>P%8s0Vhrl_fkZ$(7qEyCsLu%! z0rgYBBE~QgP>%yFVhHMUg4BRA1F8rp+e1WPc7fWx5D`%C8l(%<$_0ydQbxU@io;av>rx zb3lC=hzMxZ0Av@al?xGpsR8w6z#?$FK&@P`2;44EKLspe1Pd`x3l=N_R|D#&KtwaN9vW7l;VVr=a#G zSOo4bP;UY(VggeG%6JeFSQvsv!yqCsHK5`HEMg2AeE|6jG^z#`ftv%$FsLG+5i?W~ zP|^pBz|8@Tn1My$=73t?U=g?)(1;mW1g-|u^8ky$(=({`4Hki`0rl*`BF3=z0*#n~ zMc`^cy)Li_+%C|F8L9|qbObD70?Rv~5i^JgEPOyCF<=pR9t4e;fkohUfqD#J5x8BT z5i_s|Tn%W<94rD?0~#>{i@?=@dQ@N$xEhcvz#?!ppph!D2wV*)ZowjOHK6fuun1fY zD9wUJ;A%i4f?yH28c;3=i@?=@#>^oiAUROl0Oe_j2*_n15zv@9SOjhkC^w*rfJVi@ zBBmgBfOLVv8zKTS5hMZ{6$6V{!b%cQ+=4~m?g5RNql$piEUE}-%p5ENcMr%sun627 z&^R_&1g-`&iUk&ds{xINgGJ!+4jK&ui@?=@#?`?haC1PTYG4t#8qhd4SOl&HG>Qcl zfvW+Hhl54nYCxl5U=g?)(6~BS1g-`&ss&Wk6BD04fVXB49O!px6OjZGaE~h20bI@mQeoD^T48N(tUfpm|7`2q*@dP((mR zuS6Cx2Bp!@C?X(TpuP&+E_0AB$R$7^(?K;O$aY5-5D#h>I5a{~L_qGzL=ge`0@Pc8 zn`{EIYXXWIkX>_8L_n!+1&RpB_9Mt5rl2r?0&>r56cJEbX9r+xp}LP=y1Gmu?IC?X(}y--9zCPOZtgqmXpG8u9) zAXLO0WX>~YSjg*DfX?m$r7#ADc<@*XsH6h%AD`a($(sSxngH>tL6ralR1Je3XwP;c zNSuKo0jvvDwu55jk@Hs@gsurtU0^i~$aaA=GczLFbe!OJJ%;K6t3j~~G&j!72=mwD;B-%fE;dkg2fbE=8O1Kp zL_Ne`pwRg7U6L80O9QG4tOmudG_VU{b`{GW4?*bif$9RQL9r_xtP50&f$ZYnY48D| zs{pDCtOms{(7}TUf4Nm3&Oqpz0@VdpgJM@E*e+NYzBDZ;f&LK=@0zCN~wKD*~zutOmude6U@}@rBS;0o4Uo zgJKt`Q-QE6pVR6yLe~taF0dLDy9&W}f&2vuLlOV%dNz0%?ttn7t3k1=2&@Yv4GN8v zf7@wLYFO67g!C7U1cbCO;zCEhtL%d)dg0AVplm>7sy|* zFl2>?VIx!*SPhC@6<}R3e}Tdfp=%aY7g!C7U7*e+B+Y|D0~Ce`U7Mh~z-mzJszR{~ z6ov?0XP~;kYEbN|2J1o&LxiqpP+ed(D0bC=b;0}v3PXf0@B}IY0|QtMie0r}U9d20 zcTWBi2oFOkP(vPcMHfg7id}Ue5qR0V@9XjX2wnD2U0^jRcGbgmf#Pdk1EW$9+^%G( zF0dLDyBgrSKp~%h%FG?1s~@ThtOmudMzAhW7=r9t)53S$5pLHms4lP?6uX+hx?o`_ z8LN91q3aG*7g!C7UCm%!pw>9Zg}H~HuR`eh3)KZygJM?;SQpH$#*1stc?J#jbX+E|^_KHkCmL zU7b)}U^OUqb%1rj?3!4mdkvv$4OACc4T@czU|pd20)^qd#yjs2y3Rv&fz_bc)dkiC zv+KLtz8wf%pP;(HYEbOz2I~T)d5~Q#?BCuabcuqTz`(!&R)buE;|RPa||$ zKy`uDpxD(5)&;T)ln(ixu=%^e(_u7J7g!C7U7*=2M4j^H5`PRrR|!-XSPhC@{b0MG z(hR@b|EaLR?dpLFgVmteH36&(<}XmajL@|Nstc?J#V*h>#)$Gz^o*hpLf3AnF0dLD zyC$L7<#+4sWQ49OP+ed(D0WQ->jH%#D82$_IW{A7y@l!mt3k1A3RoA+U!^;F3K6>4 zK*I(M3=Cj3D0WQ+>jD`HvTKpSEG>jCd8jV18Wg*xfpx*`a#H-Y0inwRstc?J#jfdK zU9kN1S3^S$p(_xo3#KOt3Ck819_&i36dl8LA7c z2F0#fU|le~c<*m;Md+FX)dg0AVi)Lg8A$2{rTGPs`8R^$>2NDl7g!C7U2{-_qq3an`7g!C7UGu=YVE&q$_2fB17XxUxh=G9ttOms{ z(2OxNBh0Qn2ZCA=x}>1Gz-mzJ0N2fz_bcwG?a@EFG$OiTy$7+6L7HR)b>KGO#X~zp4$+*dugZfa(IP zL9uH&SQp4HP&x#az3%XI_zJ2EtOmud6<}R3yFg_xLKhoo2#|q+0jvhau9aY2p!fpW zz`9^|f!d-7UA9nNU^OUqtp@7?`3n?ZPx!W$Aaq4Qb%E8O z*tG_%3uc$l%QYJjx=NwCz-mzJS_{?%vr9mde;-2EB&aU18Wg)gYj_Z8<09*p9)zy- zP+ed(D0Zy}+XV_kkiY&h|K>pGIs?@OR)b>K2Cy!ezryt7S0Qx0gz5sTL9uHiSQjiW z@4KejgwVwX@-71d16U1;U7NtVV0P8$O)^2~QikdRt3k1AGguc$8ssmJxHJQVE(ee> z0|NtC4T@b`z`9^|vAsDGj?fhg)dg0AV%Ju%E~qralKwYOJ>coE3Mvd%gJRbN1^{{Q^#Ft}YCp}N3oQ0&?P*98gQjE|8%h7arc` z8HCWK1l0vrgJKtG^$^0Y&{IKI5W4K4y1;5s?Ai;q3zp`;b>5kQ&=mvK1y+M%*FLZ= zSbRN{J6DX*RSDGvR)b>Key}dkC_TtuuHJ?B5xS;9b%E8O*mVG`3uaf+_ElL3U7Ml0 zz-mzJItbPU3&ZZd3R#4%3s7BPH7Ir+0_%d=#S+9BjnMTLstc?J#je9(T_C$a=@69W zJ>lt)3p63az`y`jgJRbaur8Qgpfr!rr3uvqR)b>KQMfLUU8WiOyTjpjxkGh<)u7mQ z46X|l@}P1ap(_ol3#H@1lvFij_7tCL=*S@zRbS;7E z0;@r>>m*ngEPp9Y5Hm*TIs(-NR)b;}X#FiB&0EYny#b-?2~-zY4T@c-!FIv?weCuG zJ3qU0^jRcAW?7g5|G0e}wW7x>}&Rz-mzJx&YP%^VegcR-`ao0@Vdp zgJRc3ur649RdH`_M%Z-(stc?J#jZ( zu2!fnuo@J*Zi02e>@xk&l!ef>0ICbD2F0#hU|le~I&wH@1lvFkQi7bpxt z{+d!XWd=gmHK;DI8Wg+kfOWy_3Ndirh|u*Bstc?J#jd+xT_9U0^jRcHIZ-f`y^m`8fdyT~1J4U^OUqf!6RM%BZeC z+7A%AVxhXgYEbNY2)7HA4nb+&2c8Zqpt`_nQ0xL-Dvq$r;edWCLf34lF0dLDyB?$1 z6}3^`BMNTUUZ^gx8Wg)g`#KSJNtWMShtTx^stc?J#jdAtyFl?ZlXHR@LKhQgApipd z16U1;UC+R}VDWW0B2EUOOAV?EtOmud=U`p1bog~{pEyF77gQHm4T@baz`9^|u}2PNl#g{KU3@1T#fz_bc^$M&DW*7g}hD!)t+o8I^YEbNY4b}zn z7s#%t4@<+N;db4I>H@1lvFi<37tAh(kQc`hx)?yqD;O9Uz-mzJdJEPC@)sz+92#=0 z5V};Ly1;5s?0N^*1+y!b|4tS{mlsqQSPhC@@4>oYc70`;)P&Gg0M!LngJRbQur8Qg z(%BZL5W1#8b%E8O*!2;t3lxSRe{Fo)eHo!^4^$Ue4T@c#z`9^|{n6P}j?nc8stc?J z#V*iJBE-0j?hVN}gf0$HbH@1lvFj^X7c30lT-aZS z&=msJ1y+M%*Eg^(n7?}E=4?Xfs)FhQt3k2rJ6IRUE>JoIl~I21bhrSj3#9)^dYy1;5s>;i55M}#40d>*0e5mXmg z4T@cipp`@5^&6lt1kIZxbTNV!PcbksfYqSb#RS#`^Vh{KFZ&R>l%Tr6YEbNA2J3=_ zA!wZgLYFgC7g!C7T`XW-FuP_(=4K&ur9gFo)u7nL3f2X(3zX(nR~3Gag@<7)R2Ntc zid}4AT`;>qVTjPR6silX2E{IRur5%1fx-|p$AQpw1gZtR)b=fFjyDN zUr!8f86b3-Lv?}Gpx6c4_li_*EM5Ezq01Ml3#RS_48AN^Md(U~>H@1lu}ciB z3+As|mT!L}bX7uifz_bcB@WgF^B40Q{SJh#eyA?68Wg)Ez`9^|soY@gL+Dxx)dg0A zVwWUX7bw0!>Co)*E+>Sp-B4X%H7IsTfpx*`x_YbbKSI|Yyem~g=n94E0;@r> zOA)LKWEZHM2eoYi;Q1>Xstc?J#V#eVE|^`Qwhcm8GgKE?4T@dLU|pcJ0kR9!o{xju zH4CZ>tOms{6|gRtT}C<6HX?Lwg6aaRL9t5}tPA8XP&%BIej^g0>m*bcSPhC@YG7S3 zyM(?O97gDR1l0vrgJPFDSQpH$Af+vK2wlISy1;5s?9u@1g4y+r>%ApHmk4ONGy?+z zSPhC@nqXa^Fa-JQpGAaqqgb%E8O*rf}$3+AtTZ3j6Jx+X$(fz_bcr3cmp z^Os2I-wg;|tDw5TYEbOb2kQda1xkmYIm8fnIy?;31y+M%mjPH8%r4N_GD6pVs4lP? z6uS(;x?pJoG>3@L^$V&CtOms{Bd{)*U7$Hcgf4N=a(e~_2Cy0wyNtoQV0MA#5D~ge zpt`_nQ0xL<2n}!BfaVYpx&ooPz-mzJG6mZO3PW%@Wd6;8(3J<(1y+M%ml;?W%wM26 zM1-zxs4lP?6uZp9x?t%LG>3@LwF0UOtOms{3$QMjT@ngKH3(ftp}N3oQ0xMo_JCM# z1DZob=z0Xz1y+M%7wDV~M4CT-t7|es*MF!kuo@J*tidh>#TO_YK0CWfj02tyWk6e$ z7#JA9YEbO50qcVK%XKRAD}*j{s4lP?6uWG}xE>>L^vXU4c+tU^OUq*@1Pz z?7Fr7ya7U24pbLd4T@d%U|k@8fzn3Q#kLg)U2RZZU^OUqfp+R6!f@h~`BMH@1lvC9pt z3uf2FmRlw?)eXaBAf2whX4y1;5s>D;lf|`p=&Et7g!C7U7*u}Ams+gt_fZ8uMoPfKy`uDpx70M zVpqJcb1OpEXQ(c)8Wg+Y!Mb2+-ZlP_AwriBXge=x{})INid_jH5qLXl-7Uqp2wjFy zU0^jRb|r#!!P5NJo%&7)T>(&CU^OUqfzDGxqz#_k`A}V8H7Ir^gYAOFm+unE zy9ixs7)u7mw2G#|$ z%VNi+(+FK3pt`_nQ0z(v>jK3W$SzPhuMW3M7__yTfq?<62E{JWsXvG?1eNm$UFJ|- zU^OUqWrFPj`3sZ|LFGI`R}@qiSPhC@Szui-e}T$*gsyt1F0dLDyRyN$V0MAZd4#Sd zP+ed(D0bz5b;0bCIuTfe&~*~33#s{pJEW|#J-H5CY5u~1!LH7Ir! zf_1^d5LC`1bTvVBfz_bc1v*Cykv3kPJSl_FwH&GotOmudVz^zPbO}i<=4Jl zL+H|j>H@1lv8x=c3l@f5ITzO>booJbfz_bcRRPuo^H*z)-FJkp0;n#q8Wg)K!Mb2} zZ7DOGh|o0&stc?J#jYx_E|^{A!fQVwbZvp^0;@r>s~W5emgY03W%?m>U4!ZZt3j~~ zbT$|wZ6uvN9gooU1F8$G2F0#guwAe;@4iy73ZY91bR+|4{})INid}Ue5qO_V8oj^6hAh0wJSstc?J#jb9!E?AnM=C#8Cp=%#h z7g!C7T|Ho3FuQICO4K2A-G=G{t3k1=7pw~whLZz7>mzjifa(IPL9q*T4kRKB%|x<0 z5xPV{2b?f4Fo4yd*wqiW3zQB)H@1lu?uwa zJS4tAc5Rt{_zLUn=Fpx6aE;}DVNbL@)z5V{sX zb%E8O*abQV8)27w(b{f=uDwuQU^OUqO$CPrEWXMrmcB*kx&_q*R)b>KG_WpM80MbR zRzv9e4%G!#gJRcour5%!0ZQ|$XZ$ik=n?@PQNzH%09J!y*9@>Om|c4ogsevBGKA^^ zt3j~~bkaLw4a~ydn`R?)`9XDo)u7k~Ix8CyhDT2Avqk92hUx;VL9q*Tf;}R>4&*K5 zLg?y%>H@1lv1<;BzvNeD@F8?9h3W#UL9uHtSQjY1KE>ss-4T@d!!MZ^41+oiN&TGT%`VQ3vR)b>K0g+f$9RQL9uHQSQpGL&{!oxmj_fASPhC@i@~~JcG+DB zszT^Wf$9RQL9q*Tek>wwZ2Rb3fY8+d)dg0AVi)M907$t3@)u~V5}|7jR2Ntcid~@d zbrE(QE$!|?=-L6*1y+M%*K)AGVCB5tvNgL9x~@QVfz_bcwF0aQ7KY+yxt1byeSqo$ zt3k1AC0G|M45MAGc@esJK!?{bFff4Cpx6aEs}F4TbP0;@r>YcMcjLv?}Gpx6bv z69M5bBe$eW2wf|oy1;5s>{<`D3l?9?l$y*Cx=ulLfz_bcwE?UP<}VMU^Y0P5-a>VO z)u7n55v&UqU%7j|CLweQfQ}Xd?f(L)L9q*Trv}1b;!mA-B6Jx;b%E8O*tHpC4*X1v zB{yb-A#{a7b%E8O*tG?$3+AsLzOA(gU6oK>U^OUqZ3XLstp^CTShW$MYYtQwSPhC@ z+rYYDc5$iRRYU0757h-$gJRcqur649-IEs4KKF0d|`T}nqPeGt05p}N3oQ0&?b)&;T) zmcInxX+96C3#5uXE4pRD`YzP+ed(D0UqH>w?*JYL=f4Lf0#( zF0dLDyAFbN!R%`P+MkZl#R59wih+RvtOmudLttGnyY|*9Zb#^ngX#jSL9y#FSQjV^ zLH<%JkerIpWdYR%R)b>K5wI?pUB5b60uZ`_pt`_nQ0zJi)&)!R!ugdA2wgc)U0^jR zb{zxjg4tD^a(5X*R~u9pSPhC@$HBT_Vfg+|g(5=N0;n#q8Wg)g=iVdI;gW@iLJ_)l zL3M%EpxAX1ZWk=g3&PXk6{s$-8Wg)ufpx+BCA@g<6@;#jP+ed(D0ZC&>jK3W$SzQt z*Mr-|3p$_;wEqjF2F0#3AQAYO187_np-T&@3#U9dC{8W%K6|gRtUGrXgu14sR03D6Tz`y`jgJRcJur649fyPAcNeu8B}xU^OUqfo@=d zw0l8zfyPDk;dZTu>H@1lu?uv!0wQf#UW<`J=sE}01y+M%*KM#1VPPneQ=N>^^#-a7 ztOmudJ78U~Ff1`JT!7HU13I{nfq?<62F0$sU|le~T&*mRA#~|Lb%E8O*mV!A3uf2v zi1sH4T|Q7 z>mk^Murz;jfY8MQI#!Z_fdQ-r#jdAtyFlp>l;%a?=}-r%3#Jm-&~*Z; z3#BXmiE zjxJ?jU;wK@vFklp7c9+#%6Wt?6R0k*8Wg)efOWy_l6;_+i_ql{)dg0AV%JBoE?Ale zmGcN)Sx{YIH7Is{0_%d=Wy5BXg3#3p)dg0AV%KM|E|6WIbO=iG!tivs0ICbD2E{JW zU1^B4k#}o}5kl84s4lP?6uZ8H?E=LY$SzQtH-Ou98LA7c2F0##U|leOfzmue*ITGA zuo@J*zJqmv`~^xIpfr!r#RfWln1O)-tOmudA7EWDyFh6kp-T~}3#qX&#{~9I6Yf2F0%5U|pav1o;b;<`KGzpt`_nQ0)2x)&;W* zl;#n-dZD_&YEbO@3)Y34<`KG9Ky`uDpxE^ftP5t>mzd=b5V{USb%E8O*!3T*3l@f; zG>_1A52_2S2E{JWB?yRg=)V2nZG^6$P+ed(D0VS|PJ9OM{{p2$P?{Hmr$Z6YQQ4sV zUm!Ioc7g7jL)aDb=#~pYmmX9XSPhC@%ph~X;~OBmKxy6>ZkIb$7g!C7U7-7g5O#sm zJVI9@R2Ntcid~>v7ZGJID9s~uRY7%u)u7nL26iDlzJ6;9B6LlK>H@1lv5Ot73l?9X zG>_1=0jdkE2E{JWeU1o!fzmue*J-FOuo@J*IKg%yr+I{~XHZ>WH7Is*fpx+B1xoV> zU5ubZ(-{~Tz-mzJ;s)zNPV)#|GEiM$H7IuRfOWy_ibyGrLg+Gw>H@1lv5Ob13l@f; zG>^~~1l0vrgJKsSSQpGLr#n{z5xR1ry1;5s?BWOO0@(#hhoCes3Qva}P+ed(D0T^e zb;0a13pe3M=voBT1y+M%mmpXdD84{;fzrGY+^*eFU0^jRc7g6EMWhW-nn&om3e^Qx zgJKuxW>3^KkI?lFstc?J#V*htxCpyIxw?(@O7jR^K~P;_ zH7It0?wUhQ^9WseP+ed(D0V5K*ab@S2wgo;U0^jRb}55(fx-}!4nb)ip=%XX7g!C7 zT`FK*Fn`TlS8^7i>jYF6SPhC@s$gB9Fa+5JO7jR^&!D=%YEbM_1M7m>#j0L=6QPR* zbYTSp0|QtMie2hpUC3!3p-Ty>3#40^? z?7BU5r5Zxl4yZ1$8Wg*9!MZ^41+oj2=1t*tU4`lbt3k0#53CDj7bwjmbbW^E0;@r> zOCPKY7AiF^65R~R6;pxx~stc?J#V#wb zE|^`QIbVdXB&aU18Wg*%!MZ^41+q(ValtDyxLvhSU0^jRcG-Y+!R#vDqwR>$H4~}} ztOms{(9Q3NbtyYfMT8-AZGq|nt3j~~bnhr4&GS6rjz;LZ2-O8vgJPFG*oB}l1f|2| zD((viUGJc}z-mzJascas`Rjr4l6eSS+@MS0KsOtL)S%eq2oeGJi9mKe;EQ>L(4_&@ z1y+M%mlIeQ%&y}*c^VM9T%o$aYEbNQ2J3>&`LbWr{*BO;1l0vrgJPEpSQpH$?H8Ri z5W4E2y1;5s>~aO`f`wsDhSV2?t~pR$U^OUqxq)@T?0VE&>Vwd=6RHcW2E{ISur82Y zpmYdI^HT71cnzuxtOms{53nwnT|e~l@)5dzLUn=FpxEUJ)&)!R2Lq?1n#1jq23_>W zz`y`jgJPE#SQpGL(77TAU3O4iU^OUqf$wkv_sv0Rqtm&e0HG@Zstc?J#V#KdyR@$8 z-bUzZf$9RQL9xphtP2!|AiJdRsqRJSS^?DsR)b=fA6OU6UlUospF-$51JwmqgJKux zW@<#8awxl23!&=+R2Ntcid_LHcKts&b2mbl2H@1lu`2|u3uf1u z?FtMCT}z<4z-mzJ3I*$e<>fuwt>++goq*~Bt3k0V46F-g*Qr&t+z4H7pt`_nQ0xi^ z>w={X=YvLE2wei8t1KB97{F>!?1}*Eg4wkx>kKbKmkCrCSPhC@kzidQyI^@)8lJx* zpt`_nQ0xNTCXFcPm+h!vN9Zbp>H@1lu`3#E7bw0!b{&0VbJ_xK*JP+Juo@J*V!*m! z{D-Ns+W>@-Cg-C?1w@_VR zH7It)gLT2|s$9Cp6QPR-bR8&Y{})INid_jH5k{C@;@3WWL+H|m>H@1lu`3a*3lxSR ze|7VhKS1d6g6aaRL9r_dtP5t>#D&s62wj;_U0^jRb|r&#!P;y`R?Yd1(A5Fe1y+M% zR|;4c%&soCyE_rOmP2)c)u7mw3f2V+!v;CGs|a1kpt`_nQ0z(r>w?*J@vpiTLf2EM zF0dLDyVAkBKz4!BA*lY6fu}Zc%dDM59C)u7mw3DyOQ zFOXfJeu^dBE_w?(@>Zc%d?SSe6t3k0V53CDj7pR|t&~+WE3#s{pJEW*4ZRg3u)jx=NRUfdQ-r#jZlIE?Ale&9xzP znLu@c)u7l_1l9$!3)D|R=n97F0;@r>s~D^c7KWgH3PM*AR2Ntcid`jOT`;>q{S<_* ziBMf&H7ItKf^~uH0;NMxnpc3Q!wpbfU^OUqm4S7^>;k2EgsziNU0^jRc9ny5f#M5f z7bwl!!tHtp)dg0AVpj!N7tAhDnn&pR1=R&sgJM@DSQp4&ptJ!>^9Wr+pv#aM7#P56 zQ0%G#>w?(@O7jR^I#69;H7IsfgLT2|0;PF`E;pzyuo@J*YQVZ+c7f77LRSJ*7g!C7 zUA16cpfCja3zX&&x~ibMz-mzJssrnS*#%1T2whX4y1;5s?5YRrLQeAtUF)E_z-mzJ zY5?nk*#%1T2wf+jy1;5s>}mw-f`uU{%_DR@g6aaRL9q*bmnyvM1*Lg}u0K#+U^OUq zHN))!r9)7fmxrfAG0-L03=9llH7ItqfOWzA1xoV>UHVX6U^OUqwSskl;tOOKD9ziz z?Q)0e0;@r>s|~CRX4l(2jlBq62~b^NH7ItqgLT2eF!#_2QG~7vs4lP?6uUaWx?pxK zOwiIs=$Zu81y+M%S0`8(%&s^5uM-fu)w=|uTSci42wfte zYv&ml7{F>!?CJySg4q@7Fntw5mmX9XSPhC@{a{_NFg!R(IuN1D1F8$G2F0!kU|le~ zIFn_p5W13}y1;5s?3xJH1+oj24nb*N4xSEcpt`_nQ0$rn)&;W*bY2QV*Hox3uo@J* zCWCc>;tOOKD9u~L?OF@f1y+M%*A%cWm|dW99--?PR2Ntcid|E|xqy52!A%8Wg*xgLT2|0+sU!T|zz}zcMg@)u7ll1FQ>X7pR;^ z=+c4e0;@r>YbID1C=5aV0+sU!U2afaU^OUq%>wI!*##=+5xNqfy1;5s?3xYM1xxdw zwhcm86;u~k4T@cJz`9^|fzC@o=$Zo61y+M%*IckJSQvuJd4#TYP+ed(D0a;Q>w?(@ zIxhvG>jYF6SPhC@^TE16c7fssl;)M;>F^O$7g!C7T?@dvV0MAdjzH-84b=r!gJRc0 zur5%1f$RdMc?Y;%!oDCe1_rPi6uTCIb;0ZcrFn!d9jGp_8Wg)0gLQ%Y1xg#BG>_2b z0@VdpgJRbbur8Qgpfr!r6$jM?R)b>KQm`(VU7$3N&{YA|1y+M%*D|m!m|dXxWrVIt zP+ed(D0VFe>jH%#$X}o|kI=OSstc?J#jX`#T`;>q^UDZb$Dq2vYEbL~-?{<=h1q(w^nn&mo@q?rduo@J*)_`@v{dMxB z3__P4R2Ntcid}2Lx;k2Egsw?YU0^jRc5MXf0{IJ+Hb7|}p=%XX7g!C7 zU7NtVV0MAhJVMtIs4lP?6uUNqb;0ZcrFn#|dr)0qH7Is%0qcU<1xoV>T|c0@z-mzJ z+6vYM3PX^;KxrPKOUNG-t_%!dH7Is%1M7m>1xoV>T{=)*U^OUqZ3pW@F6R-t+@QL^ zYEbOj0oDbx3zX&&x)Pwez-mzJ+6mSL3qw$vN9d}8>H@1lv1=Dt7tAiuc_|28Q=q!Q zYEbOj4b}y+3lv_UG_MFxhwGraz-mzJ+5^@FvkSDQ0-@_TR2Ntcid}obxKey}c(zd&gNl;#n-1Oh?)u7mQ5UdMk7bwjmbh$uvfz_bcbqK5rW)~>UBXq?ljoQSPhC@$HBT_VF*g|2we}Ly1;5s>^cF~1+&ZDwc;s4*Dt6puo@J* zPJ(rT>;k0&P@0#8r$doIkQf64SPhC@r@*>kc5(gNAc@eW2h{~ugJRcdur5%1fy}Lz z^0u;q+vN_`1y+M%*BP)bm|dVWkI^cY5 z1+xp3<`KH4LUn=FpxAXDtP5tBuHMTegsu%xU0^jRc3lALg4qRHM}*LI8mbGd2F0$6 zU|pav1o;b;<`KG{L3M%EpxAW@tP5rrXdMwk7h@18HW(PdYEbOD4Auop^K6$Y{1Lij zpt`_nQ0%$_)&;Zc@2Mwi5xUHwy1;5s?79lp1q(w^nn&mgg6aaRL9y!^SQpGL(0WmX zu3V@tuo@J*u7h=f`~~v4nAGt=W_UX6fa(IPL9y!wSQpH$hYKoQ5xQnUb%E6|=oO_T zmL!7AW?;Ap)&;w+!+Fm{R|e3cZLs8Os4kEiCKO$_z`8iWsu&n5e*O|e=z0a!1yX~m z>o!;y$b}${g`f6qLg-=%28l5+fYhMsx&zk54UuM;$+g`Ip-UO63#0~B*Ig7{-+#-9 zBXl`Jb%E5N>beKk#Rs)ZFO&TjLRUOg7f21NuKQqJTu@!+)jRhhbTvSAfz+VtdH~kN z3e|Ocp6p+Qt~pR$AT_AE9)fj2FOX)K?7UAJp=&c#7f21Nu18>9&`W0-QdXRth|qNd zstcqBRo7#%F6f2C48JdAPeJJV57h-ygR1KZSQi`AU+WC>?Gd_ELLkB*HK@9tf_1?{ zV|AQd7($l~R2N7Ms;*~XT^tZY8Ep4|+KSK>4AlivgR1K}SQqpFVuq+Z)jou-T&OOP z8dO~`z`CH9eKMS56xxB%wE?ONqy|;jORz5JQ9BHto4#=&bUlFT0;xgO^$M&DdaNqL zb}QX22wmc#5buK2pz3-J)&)I$kl~I?_icnOf2b~y8dP0xz`CGIav2Pme*Z`4>VWD3 zsX^8C7OV?;j0MBmCkmwqU5B8$Kx$BRy#wol9#+Ee!3|V%GeNw=@Dr*Fqy|;jd$2C( zHINMd{5RSn>@p04Xa}i5)%5|a3ue~>L20C%k_goWQiH1NBUl&oSUQHor}>cb@(idh zkQ!87pTN4HhYm2P%zgO{;lc}0T_826x;}$-L8sLjyss^pjL^j&4)GUA4XUm$U|rC| zSQ)DJG+jXG@`UOFsX^8C6|4)oWRO8Eh;ueVS0hvxNDZp4Z(v>UysXZejL>xustcqB zRo8d0E?5{=OuTvmq3b487f21Nt{-4sFnbQiH1N7g!g}Uy0UppCEMgLv?}Fpz8V!)&)IQmElxvSRO*xa;Pql8dP0>z`CHz z_!yLKPWMLWx)0R_QiH1NFIX2W_1=B)>`x-tf;3#0~B z*MG1s=rj_8z_V5A2)iajb%E5N>SADKU|?qChd6~{=9v$62wfMTxS6`!g4tCl6u20n>mgJZNDZnkHn1+}ku(fNDg6%- zx|E_J{sO5%)x{3h1#@AE#B`)KTP9Q&NDZnk4zMnm3zb=&k>YC+R2N7MsxD5jF6e=P z3`?X`44pDWq2AET}G!8dP1pU|rCS4GeRx{X{AcuS0c#)S&9(1M7k=)?}#n zVvk3JhDa>LUm!K8y7JkR)g0;R1rY@X>(B%Tv z1yX~mO9ZS7x^<9&z3^ByLRTzQ7f21NE>W;9Sc_;{%5nvSt~pR$AT_AE#K5|s8ygt1 zj?YGFIb4D20;xgOB@WgFYl}t~Z<~g&OC%l=8Xz^Ox+K85U@jEpFIGk9(uV2+sX^5x z3DyO3p~Z#H1qfZqP+cH3sJf)Ux?nE6DcGpt?Y6P<6?Ib-`Si9;?TP&}EbW2}6(?R9$jlT`(7(RpLZy znR`NYfz+Vtk_YR8x$yKY$Mp!i8lk#CYEX44fOWxK_|#s)2BGU9R2N7MsxC#aE?E9L zCzVuy&~+WE3#0~Bml9YPEPs7BGiyia;)nLcL26KSDT8&v+5ktc%dJJ|@`vgIsX^7H z0@elFfPGT=vok_hFH{#u4XQ3xur62|pmk^4D}=7IP+cH3sJhg^x}b+{Gvsn{El21Q zN`k~PNDZnkb+9hz!fOTxbw#9huNPDoNDZnk4X`fQn8O(sKBT^0CsY?m4XQ3pur64g za>XDl8sWkvP+cH3sJgVkx?pWKt|wf_5xVX`b%E5N>e2@5f~CVE-glM=T{6j#&;Y4H z)ujX01?x%a7Jt8m&=m^R1yX~mOBbvQdISSQ?~{V*2whX4xdhR{RmzApt?Y6P<0uDb;0uT9O1V}y&I-fh`&H; zP<5Grb-~)AKiKztN7&^8)df<6s>>9t3zjzO)^Y7b=&FV40;xgOWd_y->q&Lne0qV< zwF{~Xqy|-&Ian8TaDjoNxE!ej_yN@gQiH0?0;~(VD1?Fi$?4Y!yDZZnp#f5Zs>>3r z3swRoE`G$0&{YQ21yX~m%L=RumJZpjbs_cj)A01sBaM5w>vZJURI*!i5~^5PyNxpz5*(>w>wkmLt3qq00fP3#0~BmmOFa%!R={21xy{ zdZ;dt8dP2OU|rCwk{H%b{$7i)YZg=&NDZnk2e2+!3)XVh9Heo8%TQe)HK@8A!Ma!= z-ew4pYq^WCOC$p#3{r!t%L%Lt=E9@q9Y`$)O{gxA8dP1*U|ld5uKC%C)T&H^>H?`j z)#U=#1#{tiCYdON3l~Fmfz+Vtas}&xxzH^p2C3z+6RHcO2340ESQpHN|K80`L)i5R zstcqBRhK(h7tDpS30fHlUB;P^Fa)VV)#U-!1#{t7VbN6xU7k=~AT_AEJi)qPF0A9Y zQIF8o1l0vngR095tPAGC^b)r_2wjJvxw>vZ?#{kQgk2d>T_826 zy8OYqU@qKQbN?hl*FvZ+kQ!870bpG)7iw|6$VBLR1l0vngQ_bKtP9rO5P0|usdo4Q z)df<6sw)Vr3)bH7|HRdSu*)DD5{4i(sJeo|x?nZY3~Qb32weqGT_81(5!NkG5s+!9 z=7fOFf%&v->(gF@IR~J+Kx&v6;?r_UN{dsWH7ZDzUUEiuu^Hq@%}}s8E2Ka+AmaRTMYJ75jX%#zH+oXo1!_@dOp(#)dNlz5OLypr+7nYjfy z5EGO03o7GF^NLeT!1}v?!5XfyHp)^cYNJ1c0D2W4Z9HuBlZBc%1Vo7FlW=Uo$Bsn4Jz%B>YhnBVw zny^WLbfn~$CP5QFTrs*BNL^}PS#DwhswdIKK;%TkkJQ3%r&cECr$BNtTor~ONF{1MfUCtK3{stIY>X6_ATObcK-Hw6 zhEA@rF_H*ajfn}mIVd7fHAuR^cA1zUiGb7;6s4ABrb0>zxZ5!VK`Ox+IxjH?)n%BX zAhpFMMVWc&s4CIL5b7|Z2;@|VattYuE>J!NWnWbDF-0M2b5k)RvLq8-6r{EcJ%6GI zKvbXwdYKWD07L~+0E7HdW`raFR$+`*3X~xWKvWBmh!TS_~~k z;gO0elAHmm6XQX(93mK@f{7_eh9Sh_%QH(d;&W2-(xK%n*l4JHN@+n(W^!T)QjUSi zq!yPHyYf@?ES^@=bPNunSzIUB14D4a_3K+>s5 z{zK9UQh+WE%?cRqgo$G~5t?ox{=yz)P$eMium&kq9#W*CMG>kTY9OG>fs9YhD=7li z@L1vvhhjv?fzwA?W?l-YodmA}!Ep|j0ySDNT2L?bg4{``n<%Pcu;#XIX|}m)OZAy z1@W1AY57HCLXdmGjW}rKj;04g z8mD%63l^sd2o=d0iJ5sS25^@lY(c1jxE;S5h&hHtn1f#pK2Ko_Nfh@&6yP)hly(?! zh6zL#;ty#N|6jQ>c;8g-K#f-2i zc$Gj*F(+&aUL{Bo1S;R*og$=oK@~^R0IH{;8enM@R8OD?LtF_>?noVXsQFkVAUYtC ziDDEaey~VDbQpm{0*ekT5)d6GxO8BVfarikD;7JjNFW6isBr-esAA-hLKTNt0r4NI z46@HrWgvPWX%(dI?vD) z14>~SQb^jsHeuI>Aq8%_NgK#M9NI9XAnrs292R{zBq2Hx0f$8=4oQek zL_Wcy6Ne;3CnDgm=)@rj(TT`2Sajl$L<(4NprZ~yqGgd3G+89g;Gjp7h9r1U{=y~; zaWf)2pc@X+jawd~A1NrY+KyWuq92jKvD=SZ9-<#9La^G8TOOhxQD$McAGbV2zXiC; z!4|%d@WU;S6nUVSM+}&uMLLoMk`|DSNHP%1U{Q@E0dXZF7LlYNdaz1CbRn`PhAym9 z5M79DiJ=Rt6hs#yo-uS`m4fI(#4d&|tWrn;2nus7!}4f>k4*)VA)r{mrUVkSu;{?1 z0^)u|;A2w*F$KRGh&hPpz-K{5ywI@lFKd}nuB zL--!MDu_vhR6)!_gaAIX2&saYg-FWy%p#-;ViqES<1>qpDu`K#WRK4*LaLA=5i>PF zW|QzH2B;DwV=&VKR1G8ou_pzn5{S=m#W7S7#2f;OASU68VHA@HC_?fYD1^WxZlFPV z=$sl_=wL`g90GAI9{qR}KumzR5|0UZ6d-v46gwDhgoG$8W-z274uH52kA6G~ASNL4 z2!<697vNCppfVNk-`=fhA2`HixA<0B8eVoD3TDJ zi10y?gy_T}3DJoNCoDQ~NJ4ZX!V8N|9Fh>7h;YNA6Ne;Hz=DUML8%tBEFu%RgN`nP zt_c+G*fk-^K->t43$TGma*zPUE(g&E32f~8u**U8L4q2)KJ0Q3eUO00t`EB$L?0xW zvFpPwhaQ-)7)Zkz18FGpYAAMLYJ!Dw8kSiFBsrWh0M~~ll;O5vmxF`|mQaT4!!8HW zhb5HZ`moDE^kE5QxIXN1*kSPv!!!e*3Wyo#(S~UTJ{9PZ0*W>0Vn%Ga8776U4HQ=}IV@!_ObX&+wD^HZLiFK~ zgy=+z6;z!#Bq2J{;sRAC4oQekv=~6ui9-^i6D{0Pb>fgj4_HuqKo^Z-iw~F-x;9XJ zz~ms|3eT6wQV@5d1v#od9Fh>7XhDvu6Ne;3Ct8rB>ck-l(TNu1s5)^-LUf`9IjT+^ zlIQ^oiVyJOJ*;g+s0_L$P>@5VutWw_2I5Av;D*XUbYYi+=tB!^6n)s`Ao|dP8bu#= zIfy>AfJV`WT@IoTEtpaCVV6S>On3~y7R_SI7hrSY3eb&!#|K;mB!E%!2&xef*JBGw zG&ArjftZ3VT+vLys{~>SWDo}2&cfv%yhPLK`j#2|tt!2$zGn5-n`u zvJjoPWFdOd!Wd02E?J0Pw6I3gi%S-w7cI=u^x~3*=tT>AG`+ZF(E}M2I~a4O@L)!h zMb`|9A>5kLWFf9biw6wdxaA@G(c%I_KW=%5ezf?&(2rXlq8}|zF!bY=hv-L(7YzNl z<F4vBkRH{1<{2T;>fzN zN_;!yK*) zGhpG4!zu*{2h4zl>%uAp(S;eXa9voXAi6LE7Oo4c6xJ{YZR*0B&cPDsTENK}EQ2k~ z!4eR+p$9Bj3Ze(A6hs$#z#{3wDh1Jn9?}Q3WOxOR#5yPWFf(f5OwU03i+0i&Gk+8!Z;lb>ozV=theNblo_mA-d6G0$n#wX^3vLxIov9QyM+ML2(7y z*M~JD!KBc&f#L}!2MKAESb|AG+=>>AFiD6$9Fh>7XhDdo6Ne;3Ct7zMRVNNfh)%Si zL)D2x5~35WTaKy|ha`HyBH{yWiuCLdZh$H$2^NMLb@`_KX&ECbPjO$MR|Ex3{NV3UF9K?`IgJ=kO*deDLvNe?y|h#s^6 zMbd*!20hR~IRbRT2KG?KvE~Sy21w|`*9~EWC44mwHW`RdFv1e92b&B;4@OwR^21JzmhUCg{-u31wXUT_hbCp$yl95teXg zVUvOQ9wRK_da%hr^k9S~Tn{!Gh#rivgzLd3gEf?mv9DnSodAQiOb1Iq@;^LUz@ZE> z2;wUAums6KbYPQ#=s^!lgdS`%5IyK&iO_>h2BHT&ED?IJ$w2g=hb2M}HW}=p3{U>> zKm(^`V_YQ$NCFaOa1D@9##v$@bYO%sTn|QA!kvXp2I6~+u!QTuCIiuf5teX0*kmAj zFv1e92b&D`P=+Uec%VT-8CQv6jHv+<%JAHe5teWr*km9+!3ayZ9&9oYJs4pL*Mm(4 zq6Z@^;d-#iK=fdQC0q|S8El~pKC}tFoCO6lL;_t4C_EuDSdueD0^%~X@PtS~^k9{O z=t2uoWL;RLAiB`P6j>KmDTpq#P({{-RSKdDEnJaxVU>agAo%}jv!?3QA$;_PK_nqOLCZFoes zLGKJY786O<)5YD@$Iai>0kq>f9DM2{T-M*g&(+n%KfuY|0lK#rO@XDildrG8uaCb2 zXgbaxbi5;6vx%>(ucMc{iH=UIE@d4$vJOa2aP;2PYqQUuPE&M~C42(xT*4d(#4< zViInIlbeIPzn6=TkGF$gsE-dgwhKTJo|a!^Z)$G=N(aUE7I5{>{tf}|9`3GgZhj7) zd1Z+?nJM=SDT*JQ-5vZ~oPFH<1AH9(^6gDwX~y2PpeVmAGbJ^} z-V|&jL;_)*mxHT!fR~GprM3MYjp8* z@bmTa^7IVwaT_xEyjb;BM5ptOn<0WOXX zPVVl$ZhpSrq&Uyn$HB+j!_zCk5h>mvqcNZ~Q(O#+fs&$1Z~&L&!=2~i;^6G$=<4F( z>g5m&J^~Tst$cgaoW!E^R1n+Vw74X{C>2p`KF^Tpb;poIHGd z{rv+R;K>(~L{p1Pz`m?30J+uzVuFRefxT%G!o{Y}elDIKUIESyV0pN?&OQ#l0p2dY zZa(hd6r7m{&L+rdu{gB^;y<{(2;CkIZe9V7PAUrIJx`zx;T0|IUr;~r_RDvIJ-Ky`Z;=dIk_WcNTjGOO@;?!NvgeRAzY)2 zpM#6Lvy+p*uL}Wpl_tX?w#42PQD3>8Cs3#(JmBo-5a8+N?cp4N zJ?OxTNg*d)f&vllVpn$uA0KBwA8&A#1dlIJ<%w1@Axwa4cJ_4e^LO*}@k6$>II{{= zlA$)&z||<&1bfr6)MU5`E^ZEPuCCtRj{bgRWIcZe4=;CTPf$4yFWs<~s$iSJzK7fF z>g?d->*?;{;_il234j%Xomhg>)PPn7aNW)>4z6zg0Zy)d*o&%6P#{B(ShqJVM2TpB ze;*$wM^{4mJ`;ONb@p=ba`N@?b8^L=#GuRcVD`gZ?CR{`2hpG@vNui5E6qh}YB;+)xO#XyIXe1b zFR4IFs9>HcEkU&OT>>1Oy?y=tojnNo2W$e^GfAb03}fOQ;O^t$}9o@aWe7yZJ3N0MX1?0A}w}XebpR9*a0}h}*BGliY8#3%o zb4!a$>`jwW?M*Xt3lJKe96UU{{5*Y~J;>>VxOh4ExVicJy1DxkNQBtk?dsy-;pFe( z>FI^N69ccx;k}rW47l5!{T)2KeO%m}e6d$w5G%nIW)X4+))mw*bo2%_wTN;w$OL3d zy*yofJsh2U93YK^g2bZ4+|-iPB1okTy88ptc`GbUErRQF@pW)@4RCgLcSdO&B^DJW zR)Ts-X=xw>O7cPd+T6sP9B@*Hj1|GnaQ1QtaP|st_w_|e?+{0z4J?6MDiHsJ+5vDA zKz(;tFMm%z7boOQ4_685{v&r55E=sF8=8DWbP{$W;wVSJhucxc4JE*uuY9PT>gOW%JXn+l*33QPF$itxP9pDDI`Zxr* zJGuM&`XQG!F#Vv|#cUkE@dl)(QhQwU5O`960V(r9BWQ2~j9pv;T>O1p9LkI`;eyU?4sMR#?mixF{y3b2+}c2D#ku%9IC(ia zdpo%hYHySoA@^Y5HXD1odV4rKd-yt(86mYd+#KB8Je>V}{jiTvlo=s6H&ET<>FVg{ zM_P0T|Vw^?k+AKXvGRf7ArHx5nXQXAm{iv zlo_K$m#4FrqnocM_8ebkj61rVeOz6gU7ZQ0W@AM25GlTmeLUP;oV|U$9LkK5qRZ34 z-wD(t$B~>NcTzxeJJN8QtCNGfw~J?hw=W^*Kuv%oAb4cC_&IpFI{N!Kxe@A{fQsN^ zQ(`gbs)nM}#2g3XGz$X|VBpd>F)>s?0)}R$hNgxFmPRH>f(i-> zh6V;^W@ZWsMh2Fa24JZKu9UWDh916xqz8r!462NfYr^zWic*tH%Ai+MGBCVnWMJ^& zgUG>2E&&F;l+>isbd_M3*c=8125SKr4?;UI2sr7Lq*j!uOfbgVN*Agfq~(< zI0Hk21VkO^A~tO5t}`$&Op#z<$d-ht!)4wqMh1q-k_-&G(hzl^tGBV4$IQsUP%F*A z&>#a*$A-fnrx+L*_Q)_Ww8=u$;j%Y`k%3{IECU0RJVYHk4)b<1GB9|^GcYhKLe$}M z-&qC*hG0bo1_dREI$ZWLfy`54VDN(8osP@A_Y4dSvy>SaI#nR%!QEE@ngfA|fk++( z28Q!cH6T6+I|vv!=z-@#K|BZssk^Ph!0;TZmYIQp0jv(qJW#Z}! z-OddODoD6sG0#wqfx#B479K8W=7GX58mb0r98U9!)fgD+p=xoN2MWKrY77h;(bZvb z-+46#hTG`s(A)d?#sxi1i^24W&KU12dVRh@yM z5ULh#FBbFq)fpHTqpQPW-a&N+hO_AE(98q*_q93$!*6tTSj>~uU|>*%-gAl1ea=ud zg!~(>!N8CVRg2HOMhymrsp#skxNoxt1H*oFby)m+SA&7!ExI}^=5cE>Fo;9%ipJ+Y zQ>Yq3{`J&kUE8xIH9*D z<8z-nR1G2jT5B;dxI@+AGcOgYhLCxcS_}-WP__8XTMSi0$h_@Z3=D^%YVn!(5UPfd zd0({{7#N{9cjGfp9;$|rdB)ld4E9j9xXc6P-&m*`LgwXaGcZ&_)#5S_R9;QjW?)#2 zt`19jIjPOSa1~u0TKWT-_gR~Pfn5jUI=H=9%v052U@$~ihh`qgzy3N54Dsmdu$Wh? z!@$sqt`5ySP<^yqhk;=~x;iZ8-PK`Wc!{nK%{-8Q*>xEhq;(1V*HV{(!4+K{7W0y! zY9J=!u0P6k85o+OYT@BrgxVegHTxDq)ga7saL_|j2WpD%BSIahy?llUb-WA=4A+TJ z2f9f82@&c*&6c-BsAFYdU=Y%S`4mEf+jVIE1$9frG1LiQgbSz`mB3Jk8Gayp9Wm4y zV3-GL-@0L_!!!>RZ+=9m(`R5{$Rl&=2pzj(H;2#uX1zPV4T7wC`q8dXKw7@4ZJrzY9biWd4tr?0S$OzC# zVSG+%S!zx(b~(^kFs2k(M?7{p@G?Qj9fcT17AGg>fhIkR;|o%Y;=w90)PP0fVHahB zEx}Mzm01vvv|Iw>0~A%Dm8gVOfr22VJdp^qu&V+kmyZk#4E+oY41o-cf}o@kZWWVX zkeZiTQKXxjn3)%oRGOKS5>s519Fvoo6yslzn&%o36^b3&c?jNlON(A7_yN|!DW@2FQ=yp*laO^(s z(YZyXfq{X+rL%&?we^2VPV-B~l1LEY*8G#P#2DQ)xH+!f=Y4uXB^bjlP(1>6fX7P- zkkP%SAba!(H){v05#EZr!WJ^iKjh!oeDgf z4{>;Ox~Ld{!cD`avqVJ!>@Sz@4<6m8TMv{7!Q2QIe%T2QG8dHsm+tdE-N!t-0}4F4 zgCxL`F5Mqm5Ae78Gcqvvw!Vd0@5%4_)uZ(rf6HzL1_lc@{+7)k%a0%b|NsAgkN?LT zZ0s0Hzk76__Gko&)EAke*ar^~pYC%Woi!>7P(SPf)sE0m0S{Op`Onq(tw*m@2Ha<^ zy}rUeojEERE}c0D-+^4Z6yy|8RKYxR+M_!l1KmIMpwMJ?HGb>Z>;A9#2V=PpYG{H& z8{~mrrwX{8*z7Ac1t$xSZjXxNjuN2i?wB(RV|Vir1_p-aAB=S@$DCOi8>(3tN|l;_ zFqX=?SpO)Mcr5`^1Pc>bs(a09bfCkT86G;0pqPLpHIHsk+U|y=Xw+mM$iTp0z`(%3 z!Vu5Ez+ebwfjnmfX7$0vKqE!QV6kg(u?L_;#|YBVjFIbk9k%8eCm?g}}zyK0w zVNhgbVE6(SGh$?50F8;UFoZKQFn}r&7KS`V1_p@9-HZ$jpvD6W!vaPI1~#zC_u#V6 z8DZ}G#>l|H36>RNVqo9_vrL&_=0!6xFo3E&7KR2U1_pkx>{7VwS01f@I!kKUc2 z@}iW}qx(FhY-s()-|+@C8oC)2h5WssF!Jbbz5&i6JRf{pzm>{0STiE&KxAf%msdfF zues8Ifxo4dfq|hrkfqn@|H{Ar|Nk#B`F;pQmlk+5S86bn>Yy3|%L0&mefoc}!^=*H zSqTg!(%p@q;CJj~L)Bz_;B`8x2&OTwT?wjCMpfa`eGX;}sGfjiNRRFs6$20SVDx|| zzAAX4+7D+PV_;wq1xFvq^^l|qN)!+lFCznk5Li|No-p(o85lsBh=sumE(RJh1=Uq7 z4CF_1DX&N4K~O});<&=a8XUj1HVxK{@aPr!;L*JaRO*%Tdh~W9)Po|O$FVnz85|ZC zuk}1T&5RGcRtJR}s!9^V&J`YZrSK4&4`;0e4UB`c9LU!apt?}Oqx%=M_Tz)5X>f9m zhot5l6$4NfuqahW@oR%MV>j5VrJ^W)dd=3o5tPC~MT>z)>;F=j-f)orJi491ImH4L z*%0$R{yzY7j1P30gEEl?C=2^^G@NGR%!spT5bc2C`!Ks^PgJUNLNIU{0 z&g;?L1S&7Pc~&@fa)3e?QLY*vc%6VMvI}0iSP(3vJYJJpNacXyy+p+WlvW+%4!gi( zuofPJ;_xy?6V7shv%KNuQyN^XfRTX#C8o)!axjy6B_x__3*iM3q@Ixkg%@i1vIEp` ze4YQ@kp)zjl*nVM*d+vtPjK7zwLAa*#t#e(4A6=L)hH?!V8!qtoeF2|gR`!{S@%#1 zHS%g~%;0l?2A>6@qyQBX-9;>DQyb$is*>D!9F^ZmGK#g(*aPJ1vQ2FTF z{R3J=f{O+Lq@n@CxBMMPks2pE!EuePTu{Q2GLXuKiENs z@Jw9?5Ai2(7N`{qDWDnQSy=&|m9@~bGHRjioBYwE`=)2|3*rb_zKHWYl0Y2S<627e` zOGG@o8$hLax5x@dOCd*oCn3j9L6C|FkgT|8cLS&_cj^||;Ak1d;>hn5#NyZ~2#VW5 zSgIoufCW5?5pBp+xL6K6DYV1ICZZ<=s+8)^kaSRMjaDpe+JV_}p>fGn0?!kmBm>D4 zD^SZ~aB~gZz~a~V1WNOeVHS9s4bqwdx7nc0OHlvG0oI=8?`VVhc~UC1APfM5SZnc8Q50r0>Gzy7fz$T*!WAhKLa`DcUpfrXO7*q^CST_*V!fHOE z5O)|6eChC@0*x#}f@%R=3{>ezg9Gg#T0!<=8bb(Z5f=z}H z5P4MdJ;8P=GB7bPq=1&eAj}5Y4$*;X3&d=YxuCv3#AF7nZuckCY>>I2rBL|H4h5Ud zXvM)`Rl>#~kix+rV8YHIV8jC|%^5%om0-F-V~&teg|I;WiiYU+=VI_L5oE9p;b-70 z;`+exfb9ay0VdEm6T?E7b_NCpGq7qeIOek=7P)wEn9;ci`C7!U^g?0axjQK z;bag^;b0IoVP_CE5(KrL!Gmfr-R5AGAR8epke@)!UuFhHRwf445=bfprF@VMkSs(U z$UP7i$j1;JAXRptAw!T-1_lO*JgV8C{wBi5ARQpZsA?ekKsG?k1(^vNH36vvVTe4c z9?%dWGXvPiDVz+VA#fjqQwhu-kZudOk0C6OpFrslw~ry}K<sv3xDkPQ%XL1u!M%z;#bFhm|z&qT1f#Q4|}tP-Rf!UDN! zI#>)>97EKB+yh~Od<@Y6a(@ewk0J7?X3vF~4RScNTm&&u)j;%tY=D>xG843j5u_4? zA@Znt7K6>jRT6-fXo7TtuoYM(NH>H9@-b)xikShIZqOhwNGAw`27(~v2!sXFy&h~L zF5RGIpCFweYy(yavKztz>D~$!!=)QElnv4e!nR=7P8!!UE|A)lJL{jQk*-TnzjsoDBRy5S^ewZjdez zwujpbVS#iW2a7?{2#60Es0OJ9@gV9zF$iIS(g;Kc$lO?vGAM?~gZumm=2IEL>;Qx5FH>@pq>HLXaWFH6HW%MAU1Fs0?kgrbUT1mf?Nh+ zf$V+_76YAkqX0hcMnOY0MN=Wav_v64O#ytu4FhaSITN%voB=eSodRK|q^1_YBpE;) zkQ@W_7!(EAEIDXXn}TYJLRx;2LSAaQ0%-1)0VK%40Jau%Hh_Y}if@Z`J#=vbW0w9M2LxR+DP6BPk)3F&N#8vg;xw7sdp(I4NI)@{K5Qw$r-^Xx6(f!?`LDXY&!Mx%9PrJitqL^o7ncc zdiK5kbbEt(@GG~%rB$zg)Ky3v?vN@!xZ|T$ce%1PjQ`@Fd}PZu#}$tP9GBnc`(?0x zN9_XfP|yCY`fr{jR&CWusF#0!;9u^k4EDGKTd!{{{yWX~%MmF#gM)_dD<&@#%Sg>| z%?K(f^O@?!eX(IXd(GkrHy5=$Evj+OJYM!n{q_gHz?&DJvM=RaWKlLltmpHrk_D&B zpDX>l z=WDrP{yAl)a%6i@unvsBLvmx-v~LbuVEi?&KddQe$mW9a7w*@8@paAjsq0gBdz^l5 z?c#TB(Z#5{$*bS%9XGyJou4Yl%6*RQRm7tW>5gYNAN33QwPuZQ-6rP92S3fU9aWCj zgzx`#t-i%_QnjhgE#uNf3y6Pp8kG}3$#4D%0IxwUs_H=j7u@8+Ixu+6ueO3MNxY$5{y4TM?>Zc!07rH)= ze@{i0{r@ScXOmKraWuGvS`|e{)bg;t8Uk32GR(hE!H%nL;|NjSdfE?0N6HD|A3??u#Hb6v>_j`a^8O)5J z9Uq{gDR@KoED+7WfV|fOv~Pl$5wzO_A_pUp_iupO;LMDmCNpSv$Mp`zI0n%C0|T-e zP;tl12x>xrR;sC=z2%3g2GpTvW&~CBAl3aF@)lsK0X3JI89`kdkjws`O)bDw1L}M+ zGlB|ikU6Yo3+`d60TsH;jGzV)h!xE&aT`+&Xbl`QBdFm5vQ^LEMK`7z(6m1@BdC)E zvMWFP%zsQZARjX`f*RN$m(2`QbHr2ws&<$eK}}MSdzg0YFTqp;8VhA+1XZUXy9EDV zzlf;@v?79;5meoP%vqA=#(}AZA5_^ef|@lT_w)#OU4f_p#VyEW5Y5J*0P4tsR_%ef z3=9lha1rR%5e8LLb0_xg=M0nsLVIVF80|N(KBnv9S0v7=d%7Fwq;Udr^ z$-oL1*#=U;z`(!@7Xgi^fCTyBBA-B91_lOpxCm&B93;pG7tsSHe~=Jd1T@747J!R@ z(krUSbhs`CX!vZx5IGAMfra5?6cH64KSR)P0LWxe%3@UM)fKq(3=VgeHZr5}h0r~?5~1B!pJh$*PK2oeFsEm*`DwAKS80!rav z5xDK3Jcud+N_7wsn8~2@gDL__N2ns8bjZe_hqQ_o)M#U71i2GrbLg62c{T=+Z6F>r zC>g+N7?Ae_fmWJ9bb&(QVz#6`LYEk*2w-4f0INZ<3pAz0%m`Xj4ANzG^QbdImo`)v zSPhC@py>{TT^&bPSRiycL3M%Epx6a!f-*CLNd^Xn_=h)NAaq4SbwOm2{RLWNhOkTh zuEIKmt^%kouo@J*K%3)m+0_o!1y+ONFVI#wgk4(OSD!%GH4mx_tOms{aOi>k1&X1^ zr?-CMg2&fZs4lP?6uUs%=n!`Ok4}4y&~+B73#OJzi7${{JHGbMWro}J1gZ4VLeHP4A$0wO>H@1lu?w`477>QODqo#I=;8$>7X}6fuo@J*Kl0MH@1lu?sY8g0SmxaJnZ#S0hvxSPhC@pc()XhCjYbG9z@& zf$9RQL9q+8l@MXq1cN<05xRClb%E8O*aceA%*+T2L;jrx9}v2(L3M%Epx6akmyWP2 z=uEFSLf2=gF0dLDyFkOd5PyNfuyK=^4i7vG1wh3o17uK_8O1KpmMw%`pfE(}(uV2+ zt3j~~wDAdI7sxrFFhuBbh3W#UL9q+8?j2#5`HZmB2wjO#U0^jRc7axzqlO_uS1nW* zSPhC@pe-c`yL#^$@E~-}gz5sTL9q+8F$3Z+SQv7^!*DB97g!C7U7%Hf2)jUGh|qNr zstc?J#V*jQKZsqhFhuBj1JwmqgJKt`wSutg|F5op2wj}eDhaFx#V%0&j2earU20HW zU^OUqf$B_zU6(W}b|G{*Lv?}Gpx6bfpCSGNg(0ZyWr2rb0#p}R4T@c$dLCgHe`AIy zLRSq`7g!C7U7(f-s$HCLyQV{Rfz_bc1!{L7>$Pe2E{H=iw4y$R=8dF zpt`_nQ0xK^M}u1qpjc)N)yYTbVgfaw;6vfa?G5mdE=v8y3%5%Zstc?J#V+u$DBP}R zL5m+Eba_K{fz_b+3p@x4w@c?CTPi=?t^%kouo@J*z=NM~yUv<_h(hR^2Gs>tgJKtW z&=Xu9g3`t;jkiH@1lu?sxd3Abxrh!ZzL*F&f-uo@J*z=ND%e}O}O>GCdw zE;dl3kAZ;!tOms{@IV^euE$JM)*^K2LUn=Fpx6Z-41?R{A%F2dLRSb>7g!C7U7!^m zh;%6YKBO0+s~V~ctOms{CvaT}uTx$e7D4D*1l0vrgJKt`PlK@QOLkEoLf1*CF0dLD zyFd%cAZ;5^7%~V>_<+#$0jdkE2E{JWVo!u!+sr1#BXo&_n)VC~3}7`VcDaH51!@C; z>{|J?3p_~*Pa7wBf}S9BZG!3ot6@Oi3FifNA*g)?O7qTpCc46UUknV_p}Ih7m{4?i zgLQ#=A|PFt8r-!Jy2Lx z8dO~YV7s7&EW_$JxiEyT(@6NFt~p}Ih7P<4S;1v4|kTzGq)>|cZ~6VN~l=2m#v#O#}?K`#)_3 zsQ}r_z~Bwl1yX}*7kJW}5tgD(@G5j8bfrRdfz+Vt0*zrXGlJR%AoFGJg`7d?ng!Jb zQiG~19PC0+`wFCMKi~ID2wfMUxmkm@GNDZp4D6lSQgNfl+?Z?>&T_sRmAT>-3@o70FrNyZ!Ak#sZi9ru( z#~^qy03&G6AV>~@Teuk*P&V_ydC=(zFdw#g56l7WSOZODK(@RUql$qy0vKuzcq%78 zJ~Ou<-ZifzwaB?Bvm`S)F()`Rxg;|`j{zd(lbTqTiY}E2QlFQY6Ay|}kdff2Boxu2 z)Uwnfh<#v55N8oo1~CnhAn=+-P#MHDNby6^p9GabOhc5Yc-=-&8N@Wmy+Q=t zMo<}2go2_SuhU>@1G^&VokJ8}S>*5F=IG++?(gjY%Us}f9q_{heLx3&y7~Gz`a=#h zMV0k)@N)8Y^z`s>asaLUfEfYTZQ<(V@8<34=?0btmC$f0XEz65XFnHz9}lF%HKEm+ zJ@}>^@JYIEuv>8QQp@3baoh@I;OrOR=j7<&>;PBk?B(F$<{IGb{IOZM4^+>p{A9C_@@Cfkqaq)0+asaJSu{Q;+DzP_(u2KQrt7C5p zU8jO@WPpR8yN9!v3?cnR>?&0U<j&z29Rb~O`wwbcj9D7svq85Zzt`6?rPJT}Aen=;e zrj#dwE*AhVbwSk&Iz|$Fbfk$?c-&#&*mE7#OMusJp_*z|beaz>ox*m}G#=$Yb+IB?|*Xjt~RGQ_w^o z0|Nudnb_2U`heBq3=H!@Q+uHP9gdSDV;LD3_KGtwNP(v17(jE+*!=-I(lbnwf#C>L z9j@?mWMp7CC&|FT51M+z;}6iNuB0>rLjY7AXzU4_KhhZ(81keU7_LIqfkq#|>X7D^ zL8%DTQ+^3m1LA`)_(U6UbqeA^Feo{($}lhpf;2$G1*{IuJkThbK2!}vC+-uUoMjjo z{Gn<={=j8kE>sO6^BQFs7?lff4OBD804XY zB5-@Lm}e`?z~G6l4$VAJa!;3KU?@jdhsC_9vJ4Ch(bb`u2Xg*?Sq6sN=<2YT_fwXE zffY2diYISP^v!FZ!gDPn17&%<9xX)Rhfx#bL9h!Ndx#V1V28LdA zby&<>EziKP9bFxod7$vSD$l_16kQz_^OzMF82CXBK=ua~^K=y$7;MqiVKFaSfq@|% zT^*Wvp!jHosv#5~6BQU3=0erti;vw$wUc_8=wgsLHA9;+e)gCJ;H zA5Zv!@|(UQ1A{lZIxOLrsmQ=kimnbV{6O(LS&@NZF}gY|<{eaIU^t7e4$VAJ``|TH z4I%%2R%BrK4^@jV{A59k7GQ?KP9DbMK20SC22-e7T;_qwmtZ9ZhHR)hP<;um7qFOD zs>Hz12vvv6JW&3fuf)Kx8C@L~^DZheFx*8~hZcUI`1q~Fz`zY!a)F!^FZ!fugt)(A6*?5^X@7$FuX)phh`oqf3SlZ zMMT7}unGf%JX9?_KG04o1T{Bpp=w}8ItXB%7zk>9c@d!wWL_c>>Oe~JKm^QEa5{Bx zKpuw&NkuR*Fib*INAr{WKvM{y;|o9s8pKlVoH+Q{a&bvfX>v(1ka&7QE6ph~hlnkxkux=(@5r*QynU-keU#Sl;;1UmAE!J|7`z@rzmCQ)`gDH)b3D3FfRA?Z?LOzzeb}S>Dp(YBC_w<|h$QeaGY+q1zZ3qpK{H^W z^%yJ+pjEe^bq_2IpsjEaG0^5)(2+|l44}2A!4?eHiRa7zflp04-Z!Vesj6QIYWJ^ifd=4hwe-^JskI0X~-oJjLf> ze8i)(Ma6&-bbP@LpWZDh9gGYN-Jd+Ve}atz1+@m~lsyBV?$aK}T~xqzo8u19(sGY( z4v*%OOkj1b2X=zajN|t>XbY06srrAwqjQal1IVW27ofw@!XrGoZ+NsGDDm^@Zc%9f z9Zc7K&ZGOPNB0S^2|nG2yRU)H^9m0D?F$c2@aTr<2c4(Z19qW@@fomEkH#Y)FF3}< z$3-88ZYYQ8eSN~C^?wP!Pp^xL0bFbkO5}m%JRq?PHV;J>Eb_Vw6n;OzCpm$l6twh) zg#olP6~tp<0PWEOEhS-L04|SmG?PR;;(d(n4;JAZ>k%0m1gq612?Rqt``6VHc5JT~wPIxgTBa5%s(=(&Mkz~chHpyL64 z0fz_tf}R)n1w20R3p#?>A3U00F_y0N=w|TfWIXQ90xEDlj4%*<~?OfB@4mv2I`7dLgovZNy7fbNDgLQh2-51i*_~lzbMG6D- z3=)stAP&d>2Ryocn0|P4`WXFiu?DNIx$o6!^R0O|=u{ELIxdgyZqQkG|AP}eIyZw@ zovT4I;NxFBJME1RcyvPo-=iBE8QpVK5IFUh}HuY%$?2^pZNv+V!(%VoG4=b%rEF&)9se9g0Y1Cm@^wA zh{;sKam<;Wk$;<8f(nbr@n%@c?Pyj2pKA&}Memq1le|Z_n}bJZGicwaN4J}XM`ttW zUW^f`0SCXEca?O7k`C9~;K=Hjs1ynryB!iQnV{a}aG{^4-<#?ao&7d6b z*=hF@R67`hbG!l091l9F6BNauh8cs0^}$lf{h)N%eID#(PziY*oa+N#2f>Sg3$Gmz z#e@&2AptHX(m=TbbWUC`%rM8^Fh-B=)1~ZS!(KD}zu?oo1zb0Q&ywW@nH(nJc^ten zulu-9H`Hg{kQD9H4N1!$jYmK^1XLfzMjr;1JO<#BCk-h#5B}1}_!6>vp=W0zl|Ei5 zrH^-~%{wfmj}N5uF+Kn(e_o#a_y51~ftRQL{r`^4hW`4_aSgA7UEve z*fzwypjHILy$<1yq2SZQ41BsX6FhnYIY9Mo0<4|o(Hkz|0Zr5%z0)6n%1bD>yB$=L z8-MfZu1^4+0|*KOP~{r{Y7j^Gbf&0i`1CFZXD!f?!LG*N_~jiKJi6zDssT_9*`1%@ z*)1dI(Hjh{)w{bvszJ?1rvF#@dAmU^HjnOR5QS9zocQ3uzY#1~`pM%sSQb<+W6Bl{tr9g z^QK3ql}Gng$Kwp3<^$M8&F>gXg*`fVg9=cO&fTB@dU*?UWbr>n{#H;K?E`5Bc=S#N z$FTLQ(iG2bM-G=>H%5={Qy%a_2&MVsF#*#20X2g_%^y%R2-N%mHG@FSA5b$0)cgT8 zgB%|~nn9i)Jeyy@n?N4DU?+KYpY-Sy2bHoAx4m|>1h-G>EWyd}I4E5rh1+D1`+d4u z1bnQImT>rVvIu%KALRId+@tvbhc#GZ%`H$`vFHS!gbE2o*lED=he6ByK?|5!7(ALQ zIT%X05!sOg++{=-5%6fPlt57jZFo=Y(Gl-b5F^CumfKO<01l6A)t)Rou!9z|U-5}eU89=&03rU$7 z7=_pwgc!9LxF2v9a3rt?uz`Xbx>Ogc8M^ctq#Lpb8l)Svgp!#-QH+H_?285i#}QDl zLKgUfbb*F{AZkGaOAr=l$O@thxGSixXxuCP9K<2VBFnrNqV7Q{mzECKVZ2AalPEQsv`%LOKI8U=M^K{`MfvQ!?V3&H}~ z1Uj}3dagQK%T`)5!N^>wsKVf0u zKf=nu6~fKHYQhD!1Ew1kdJx^9c!ID%#Rx<2+6f{UB2t(vi^?xTyoXZ1Yf#L#mHa4s*;$jd9;bago;b0I6f|Ny|X=RX3 z5Qc110NDv)fpmk;lVN56rw$Wt_&F}1a0clBVNd}Mu@k}q=~@j50nk}MPq-MkN;nx< zLqOt?Eu|n`pcDa74~j}E#_iy z&d&qg5UXHNp;~|>Y~vaffNcr z1&K4Zol{mS`upbd-wS*EJI?R)wY{;vWx;m_^W;x)qJDmfGYm`Y7Pbc*{dKdv!s_#a zhbO-T3H+PV`CRSc=XH&S1z}MiPgXN$Pj0HXEYxD*m7#R#Y4V#VD}ETXXk=PeoMe`2 z=@Rn!)%rB{+0I!PXEff9-66Dc=VsH$TdfQU2V|9;PoBPgd1X!M4hy?yk(bl{d8SYI z6F7IUtC6M4!7*~tf7>V%_C>-@>%t<=o%9emQFdmw@9O2D)_IrKp142FRxkY#M{|NJ zs{4J(!bh@`d+oM~SSHjJHJJ*W-?NDENXv)1Wj_}b zrFbP>;MaS)?rw;hn(v>Qn#BQo;_EJa=Xt=TacB3ruNP*S?+`svrl9r`Cco!+)x_@R zipenZ^(^x)w1mfNo?f;8asngYg$*9ESCraA^dhgH$aE=x?$%?i=04x#D5$gtr)2WZ z&;d2bz}n#i<{3JmAuG5vn1Osg4yYZ+%m~UfpgQ()fTSa22M)3tP*!JV1QpYuHEF3c zO0Ggyi6N^2O|3A4_lAMYu{>0?6;lmpOo^Ehl;uI@=&#}h-IvI~fO1|BXk#KXBd90` zwTkC@rv1h=2jp62Mo={jQgb@Mt_9Q0oS-6r5!7t}x#!YCElW&uK)oSmMo@DNw3hA7 zx#}29H6WKVGlGU)Kp|yV@b@F88c;FJ%m`{sfP5I3kRpkx1~mT0%m^yDK<32INv^M$mi&$UP0UFYGYYfT|m2Mo>co6h3c+jMhTJ2Ne0B zxCGG*@Uvz>gF&bwpn?=tBniR=t>l9qnF1NH2MNQ@npp+nfH6$u5|{@fU?Q(T959B7 zfJR`z0??I=3=E)?&rwBeK*0fCaR}3u2o*t`*8@879Ha|z&dwC58pPQ^;L%d>NjETa zu0quyP7C@36+wg#D<}{_M#Do)94dl1hsXpf0@0P0mQz{`8r4J5<$|iFpeQr1Bn_+r zaWYX1iW-n)2~#)qu`df{0vz zih#~Df{46=ia>k;(*GMpBsVp;I2Ck6H%JQX9?|g4BR=99YB%rVEsJz#^c*E07X!ha4fKTT^J<|t#@(v@Y(F#(d)39ne z;uHX3h-YA@^B}F-0Cfxydz*ub6;u$q457NfYEbqYgHPT8?+*vr)$W}91+jD352_2S z24%l7sF97Z>-b3rXN0a|s4lP?6uUq(3y8hVVUv$AAx^QG4%G!#gJKtGgbiWW?t9-$ z5W2v3J~1#bfYqSb1zI11*dLzV{&^)r*Bz)`U^OUqfw~L`yZ-o|H@1lu?sXZia0MrVEMf5 z2)lBiy1;5s>;k1Fguj;FmwJTIH36y%tOms{(2`JQa5@C}Ym(}c9)zwfP+ed(D0YDs zOd{;s#ja9@&~*c<3#km{HSPhC@pv4OayN*VNtwQKh09D%H zGM#~e8O1J87ab9X;U){tB6PVxb%E8O*afOd5O!S)&Dn#{l>yZSR)b;}Xq^Z|7bxw- z1>IYXIPIkestc?J#V&A-3{M+jX7lV2x;8>}fz_bc1?pHL(&5bOTOT2GU4`lbt3j~~ zayk#FqyokAp2a425W0Rtb%E8O*ae!5VP*t}KLZ1Uv@5?pLYE?_p}+u{uwh2A3)Go} zga*hi(SSN{gf4feF0dLDyFlaXi1-TdOio4U%7y9zt3j~~G)aW8OFs8z7(&-%s4lP? z6uUrk2nf4&-8tEg(6tk)3#poN$SPhC@ptVg97lP8p^&Msl z5vSO&f|`m9kbC@4!w|GK38D)WhT> z3$(}wkv2NcIZs09IsnxLR)b;}sOm@9Wqt5%7ed#4s4lP?6uUre3P{fd6o!je-28$# zo#!7^7g!C7U7*!G2)m4Orfo#%5(RZEK=*`#!WqRb&?E&!7sxKvvyrNZlS;Iqy1;5s z>;f&9g6IN;;g{19$_QQFP+ed(D0YE|$iQa^f|{Zco#NXOr{-lrb%E8O*aaROgXb^R zuC4V5UF}d^U^OUqfd|LHZ5xma=e?iMiqN$fstc?J#V+vR65KA^4G$s^x(-5hfz_bc z1?p8G(#FYzN5>Gl?n8Bf)u7k~9+HFGwP4T8euS>SP+ed(D0YFCr$O>E$X_A3O8*hM zq(Kc;1_lPO8Wg)g^Q4IQy1vi(B0`rXR2Ntcie2DIDDb&RAiGfg6%N$}R)b;}sP~Gn zD{6nlLWEtVP+ed(D0YFT6TqPXONYGhGHNnZ7g!C7UErZ@ur81bJ2xdBMd;cJ)df}q zGL+#OC+MtHFp~lGv<^_OoS6~SlLg5>Q2+8B(XZqMHSHM~z$-sdb%BSr89^;ckS+%4 zSBDU~?4i0qYEX57&*FjG)uwd;>8zPLs4kEiR9&F6cp$xXkX_{kQy(MjS_RbwQUmGM zJc5dV)G`q`VFWb&!^{X;+YC~Tz+bo!Cyb<|rX`l zg!&Y_BzT}0Ref4fYAQo~JZJzpC%(8OB{M%B($|mAF902JQp^w^pO{=!5}%o$6rWa_ zm&_0kRhFEeo132(UzP?@k0D+R6)!8!gR)?u1xZ^_uQ8-#78fLzBxgVpB7$37l9-p0 zSd@Y;4mJ!bh!S=%uY(W&h>v#<_JG8Sb4F@%HpqFY$)!b^C6)2XAc6Sg{QT_9R0i1T z4k$*!V-9*^0S-y%9(fd5^ytNA0)`rF27x0B9*@|JK~n+Q|8J;*;v6(Jpk$kV5RVwC;E;yI5>9D|Ze#qqaZ1CSjauTu+>0iPt{AO6M%RTdjjkQJ z*hbfjA_wuJfeO4{K#_%n4=!1VUPHWkamhmT8sXK8OBSNn7_VMjve1A+DYan<8(ft^ zLkqV8`*?pyT^(GKUzC`h>R@kZZ;!7|cW|(Duw;Oq%i`zY;Su2F@8#!Uuj1@h3_54T zUd7oH!clSdf}CzrY;OiXWW&kB!8O3g&DYV##{oK1ZEtE&0n$-Ggmym%e=j#5FP8ux z2YVG4Usuqaw!MmrKUAw5vQ^Hm4j%4)zAk=leh!ccZ+p{{e0x)HwU$_tYHtdk^R_q5 zO$D9jQ4FuNChpA$~cA^Jp&g>&d9jN;Qoo51{{7Z#L-TA&;QOA(NnGf;FuSfJDonRR01VgfDF z0u6&QfbtGZ2V~X^qyxeN>440!^iSt6l&p$A(b%#h=u3>|=AYK(ULgyd#GG?l^NPE( z*E8St@mln5tt)JGhuFpz)|^KF`?-<#5lzh|%3z zupY?SKd58)paERO_*hC5M?XRrXzLb8BUlZ}_!uY!A?(WDaaa~Hy1NOa1$++>c(x0v z%mig5gk9SH%Woiboq_5Ct6|VXDnUVmN6g@HKd2HU3UnzShznK&VlaGz+6)mvE@2@n zOh6~IP9gQE&T$09Ow3*tRe6AK(cqa4s9RzZ9>$WR4H+C8-- zpeR2%wYV50fuj!(){d?51hE=x#~F@##7FN%3Iq(6JD(07wqP*EcmK>GUvD z6AMdIaAO11)_4bQYbTLG)V`}FVMCDT3Z8@Qk69r7__14K+PR&Z4J-{Y*P&ehG|fBAa7t(XT!w6uu6l0 z;TdScj)8#zG%t=#-G4>~hF97Q3@<@bYtVH8*wlgMC64MbF#HEil;Jr|i-(DUfm5G> zK@?O$fY<0?_b+JnakU`>!xgAHT>kyX$iQ&Vkb&V2Xi5r?d2bmQ7>Z077~-L25iavU z+txEp85np#6G(Xc0opVtX2!ta2rbD#br`mA0o@Ds)q;VcA2i*A-1b9@U(i*#Yb_ZV zyg&hoN8NfR28IkP1_p7^Gz%X8g4QLiwPj$K51JwY-!O(foI$1SQ>YqPQpM&E6=nv8 z*Y*qy{Gh1`1_lPu>I-b@4l*+^aJn!soB|F0gXXb8>jeY?5|C>*kUf#i3=B6s7#Ive zN7Umadt67RkV% z1g-XQxev6a$03q|Ap%_;7W2v?85o+-)uFi$)RtTj$-uAyT^$zl&P6gX+(K7}#k?Pp z3=ABglzoHo!_+lWggWHS6Je?Q@1`Bj` zSj-EHVPMEYSBJ&Cju-}pDd_6Z%md|*O)(4%r_j}5G4DkT1H%_|b!g^+;#Vk^fk6qn z#2cS~9by?6e9+ZlF)u5YfuRar9TxY^h-F|{g02pWd52;d7%ri!!(!ftSO$ha=<3kS z1NBv;;usk0;t0oYOdJD42D&;l^FZO(22}$w5qEl?7RSJ_2&xty&S>U=(%*qN28Ju> z>ah6tQyc@sKXi3i%#(>{U@(Y>xDIYF7W4e#85p9_)nPHOBA$Vv2VET&^H#+(Fl<9t zhsC@r@eB+v(A8lv4|LVI5cs-rq;d$&JWzZXBrq^IpsT}TUR(kLLl(L^Ear72FfhzO zSBJ&CZ3zqvhtSnwG4DYF1H%V&by&>fOJrb>0yWH$>lrNOStK$rc%ZApVqRJz149wI zIyCb@<;w)98c2%4ot{@DGB9j`s)eU3H1j~|`BEYS!!vYsSlq{w#K0f`-2#BmJiR0a z1}AiNSjadt6kj%g! z1KJslCw@Wor4>{Sq4;o1W?%?{s>K(61<4EyE$Hg7xNlK11H(FWb!h$t#qXJ928IXd z>adviFPVXX3wpB-F86`_s{vI*$iF5j3=9rXwYba!xi2n-fuRUp9TxXZNMT@@gRTyX ze|M!YFq}hIhsC@%DGUrh(AA-t2TFfpsW6{HXq@fIR0akks9Ie91-B(C6$5U0=haZ=Dka0VEBcu4$VAJd`P4*Fz7(Gq%gq!fyF$pGzNw+ zbahzF18r~VKv##wyk%(&44cr^p_vCte;1%?AhChF{JWFJ!0-a97VZx;^FaP(OJ`t^ z0&SB*&gWR%XOYgp;DW9W%{ z1A_{5kQSGJLE+~FRYNHJ{4y9AqM&MVnFk8LiVOyZ9&~kB+_x%&fngiEIyC=+%)64o z!0-ZH9TxN0G8q_zKqpKf#~Ye?pmp~KnG6g8=<2YTmzT-FP=&4zi+M9L85nk;tHWa6 zwM+(vN9gL%%mbA#;3F|%k%4D!P#}weK?ZbuCLaHS;@1kQ24*C#^2#lXfguR07FYa& z+8YH~3=AFU>ah5CSr!AsCUkXZ{sqPFg)9b!C+O<1n8%dOz`&Oc@dYmTfx=HGn}NXw zT^$zlqOutn($LkRxesJsOEv?;6m)f1%-fXBz_1Tp9h!Nd@Vf(51Mvy&^6CpnT@FMQ zF8_kYi{+qdAS!X2rEiUsw@!OWez%UD49hUIh zk;A}n1YI3k_<_uOl*7RA4P6};^F(qP7!-0LzQE-^Q2g5EGBEg|tHWYmPA&sO1-d#k z_kqltmdn7f3|$=-^N!>)FkC=ahh`oqKHfpqKzxEbet+dMFt9;aE#UGmDE+DAF)-Mm ztHa{Hs5}OSG<0=n?gPa~OCAHm40Lr^%-fd7z;Fm%9h!Nd@OzNQ!0-WG9TxNW@);PU zK&SoSDgQwJwScN26n+8u3=A<)wYb6$d&Z&CpR!zy%jSj;<7z`$??T^*WvApd?UU|?V?goGYET(Fp@QpmtyfUXYBJW%@c zD`a4ZLsy5zyqZD=h7NRfSj<~i$iT1-T^$zlt`ssbJU~~6#k_xo3=DkGMGW}-t5d|l zV1cd=`@3^LG_QMk+lr9Z1;1_nQLby(szrOhP4 z*kNapfjj~3uVRJ^Xq}Wf5$ZroX&i`92U_cvMx?rhM5qHTKe-IGG4_p!m3rp$;>gLE{@-RZxdPDQxZotuE8TrVi=$bddG}b_NDh zGv>WSAB4kUfVe>Oear!L9&Z2#O(7TAW%G54vX)MW!e_Ys;?jbG{Gt*R1z=ahyboH=30iGBiGhJ3glg-Wp}U}{u&^0% zzeXtNAZHJcUZ?+_-7h@4e|p&d`~SbbOk_tm1ABu<>!p(VV~h+Q%||@qV-JH)4|eeA zjrtEd3f#i@8|bnX1E1a!70AK(x<7gxX9pdP?a>`5;L+I#auw7E9-WP#CCFf>!LFiUWn^G*HU7UB)HihLKI+q1 zqoS~jfq|jHqx*zwuRk+%&3E@{pY9L;!xB83|NZB0JqEhb1H4upq~5@BCuosx_Ycse z1uiNHE}bDGLvug`r3Q+1{*;6-99P_KF|vYI(I=RM0JK5EAIt(Bp9)$o$HD+QG96Td zu`t|VU|;|(wPRs;!oa|=6`U172XxK?vsf4z7(f#$EDU0d3=DI@VtR}W3=6<4(1~@R zd!ASrycj`+6(}2lPH2PJ2D%6ZV%uy+1_p?2YZzg+?O2qOan#5T|&=@8pq z!EIw?g4relI=>X`4_P?NAvg?F2swCk2P$}Ue}rY5)=Q-<;H(18HIU1<&@)bsN`^;g zBj}h!Q1MfMl7&u#&g3@!=4yOk7Xt&M14w}aIQRH5!BWC$kM0-$!xB82|NiH11qCuh z0;Ci(_mmKodmKG_gAF0Z5RuXhJ-T0j9SzSt{2ics&>VZ?SYLup<@4y&H$L$4C_H0# z|8RwtypY@t%?Lk<@(|HFJaR(*l=D z-G@Q7KmjNxWPmb3d|dQlP@^4^1wb28Kr;+144_00$pWBOI*7-@0J?4rk|=jGFfc$8 zC8)fEB+6^>EC9OK3Upu|3j^q4Gf1Ljf@c9OMg|6mDUpmYQ&QkbyA+Pul0;8R;H8`#guUAXlGxbaQzeKMXGVtxuQ8c=U#-Sb**(1Fu$wq?FbJ9{jE` zDi$8F`_MpLJWxTv!r;+;1d>4tjBopPU+jz!@a?|g(HU_7R9kmOobWh)3~Y2~#0`(u zOQjkf-7PAhdz(C35Ae4fU}Ru`mQcN6EdMWfbRY9*K2iV*caW>B&z0(;s0ZbDsCtj? z^WgL6P&9cq{`wDUAE4@rLfC>;7s!eY3?P^EsDSo=bh@ZSxON}%IQT-rv-@(Vi%JYA z6?=f|CD1i&psEoTE+stOTfmxLz5$ugxkUw3RYGK4x<54kP~&d_9S#j@oEU(Nap;Uu z(SYO)*Y0CrGcj_614O?^@{OIK^Jh?VtONGC0aPX^fK#>nHTS0~Q8xcq#|oHUr5k;qX+R2~Xvq^bT6Y&cXmn z?~uGQ6`sl$!&CVlcq+dQPuox6EKoC18M<4I3w$HV&;KQC5MOy5X9lNE(AKxZ5)2Fs zprhs?i8?gQqxlVHqWy8wyU;pxadn;y{-fb#r-GpG8a5O$hZK z-RIzm8mJV-fE%bjC@CA9njwi8 z)_en}YaFdNSXx4)XCsJ};Dm-fJ%g^M1f^#qSX&2lScNa@4z{tR` z37iFL;Dt4)B!jd=mcf%T=t?I@s|QN=7<64qRj;G4Jsc%x4N;zTJNnV zONDzKnLtfC2T*Iy19CBnN9*lUS!jCc4Q57@_V}OZ;L|-5l&yVRZ}v6R)L^+2WQ z4se+Q>L?*O0(5U)j0&=|c7evuFdbt7Ix^}wILN@>2KyN7*&iOQCrkO@9&A2h5Pult zHwkpVfn=cG0yV!t-g3d^t@Chib)SIw$oSF@(D;Uj^?81mLl75&j6A%HgMono!T0!| zXaPEr@D$jw4#AEgj-YZQz}5JPPxnX1?mHm&@`Bvkd?dgz&M_wXFz5nD@YQ_Xh90fo z_*+1CAMkJE19j0V9J}B6bmpjdID#ARy^jA^{B`7adE0WbB+;XDj|wO@K)noy*0=mE z;LHGN(Rf(4fq11l9^GLIplX)IqdQE%qx&4V?FQ+ymGFbEnF6cENrCDMxDq7r20K@4`_A6+jI2NWKB>Zh1fie7b+Y3ZQNml>%ro0wo9y zkKSMp&+hZ!k_ha2cq6z{1gg%l8`_85^zZ+F^giTyXfqRPwP*Kvh?Or}|NZ|Dsv#lm zO3)|_q%{fJPzKsG%fbMqa1>qyf$B;~5%d;b1hK)pLXz+fkP@5)%8LS^? zB4{K;A?|R4B_k-j3`%)D8V`bQ9)ozU0P?SO(47$b#!U7M4d35@yaD;|AhJwqM4BzgTzMyLuLHB0CqoDanhGU##Y+USN zPyrF()4LNC`kvkAL0o8B2NySbObiSSb`1P2s-U|mJLiBad{CSvcpN_t%3dD-k2l!Z zF_eDi-xkZ{Vg0*I1Dwyw$WIa&z&?r3n zKhy(UdwFz2EcfZIQ3>!s@<6YTii1!0F^}G%$8Q1>~|JkxH0Xxl*4uTJpjI@f+J)Uy>)Gwh;nyv4!lyGt#lew(o0FjR@lt2cZYK_(?qfdM z2l%%MIPq`eVbH!<%I@+1K3!!7ES;iQThM4 zXY(-*7i);CdxF6}_fdf+70}g!5yl5z2LJp29}!fL+6EDi4(L$_D!m~2u#16#0g{A4 zT`JIhkSq+Knhw;sVqw?^mjw+IJpxyr?4Th<@ZgIGBTO&op691vS%1(bOR#JlTs8xA ztua^@bd){BwoWFP-U&<$40ph?4#A-w&2J*QZ+UdT1Z5a5NPQduYLR!=s8o1BG7IQh zXmH)qP|Ltrq73IktNgPb-L4j(gj?a!d?X?kbbtnEM75yxHt0@XP-VF9Ke!K=qY|(K zG-t{0@&VK<^8n>Q2M3E%CjPc{pj+a)*Mbs?tMP5u*0=n9py3ps?!BN?0!swG-RiE! zCq0v0R5)4>)TQ}$yQm2GbYFm9_UG9x;b2iLz~6oaG*f0#EXdz}3UqH_wFq;mj!$>7 zgz-t^+n&j6tq1C4J-RPA@NfI)+3m(*X;Gi?|FFmZgC5NX6g;d?)x7ikf6%k}0Ee&j zshZV}{||dMALnqjzRTZJ4N45XdqE|LNB4P$j#B7|l<@)30Eq{vi4XwF86Z!C+IIz@ zbl`v#HitcWdqKJ(jKw2I+no`Tzfa&~eX@bO@T{gQN^sc)F>9 zv)UOM7~X-?2&jV$Q3t9aUxUSVfM(hcLrULZ$1soH9F+qejc**l*NNVAHU8$&>$}0H zvlKF}2f7Pe(?!JrbRjmsrjJShzkq`Rzov^y0>6NV0Z62PU%aLU%(@PU(8kgiri}t_whISb3-~jZgLlGye}!@#uAC_Gml;vd%Fs8Z^PNN5ukUcW;P_1E{mW z0J{Debf*QV&C}~!;L__4xqH_Ibm1<4s{^Qn?{+QlfQ*nsjrZvEF!1R1Edbq`3NBco zs)aze4O^C|RPeX5gEjg>`~{J2`3&l&g0yvRQ2}K<&+d=Dtta_gE;2GOIP!1f1Z4uy zWmm4<&%o_g7k-!LEhqU~+Ccg`*QkIlYIkjYQsN1nRq(U~&oS_~f-X1l1P!i&hEzSf z0|h+0A(yd3+O7O8CLlj|LtBNAw(Cofuc4awTcjBo7!aB;8=UWu8=NI78n6aui3(bS z^93l+hb2Jl0OihBP>&Llh(TEyrNQZ1;nImTu8A_d?^^-U1a5BnI)GY|P=RjW3Rrs+ zTt`8QRHO+D4gXZQi2-3VWYU zW8|a>ns@@OI%8n~tuqB(|G~nro`Hb@w9}Y{0W>@enipeX03CU96P&m1GB7ZJ&Ie#& z_`|@!09uL5!Vt{JzyN6zgGPQJt==wB+=9#fRq*yNs5J|beF|?0Gc&f#}!~|$Du>f97Z18CPU#j)ZbpumxIWvE&F*9h;5|jWKy000Z{2!tc(S6LL@d(HX z@t_g|R6c;Cv-LKA3n<(htQq)QK+)s46WovO4N(bjH9p|c+Y53m*m4wU5~#HesUbj#Sp!nmP*slI*Fgo68nyxnX|N4C zi0lK6!EQ(-cp?=@o{+%?Sb^jTAG@e602NB0CDM!!T`GH6STpCg#lEFfwrNuFo04aq!4=uFR;FWQU$oU0Nw8dDZ12{U>$o< zkp$}du`qxNBFOa5LMGVs52*NoOd{=t7h)&jh1gYiA@-69HjfIrSqU)o{T)2YdaYDTTMZRTK_5K z_vrRbKu8OtaQR#Kz{Qbo0;ntk4e!FrqSK&~2izFi11W{}BbP#dK<%MgP&cRbe+lWO zk3CvD2vjP()B+_fqDr49B$Yl7Ji1X!pC|mSpk5oK6rrf}0rkaugP|QwaM47tMf3n1 z6^P;oW%wUj0G)xRB1DVG2Qk`z2I6j?Zr=o~rOt71GYD4dfC>v(i35sWSo(i0>Dc|{ zwFtH}>(T9+04k_JttQV-R|fPn4C;|UiW$%fJV-GE>ia@kNT54TAuXi$@L~ou@(0?% z!omO=`Gd5O^588b&;$acAXy4Z0pP;r7`(s%T|Nhq1+|MHg^M!0g%kiUT%zGEq+EF6 zQVB0yTH%GuOnBk48s0+M4<9SM1Ro*14QDaI3m09`@uRT91yrygT1huy0SoF#fuk5& zo{-&%;&1r@D<9s2vNE`t18N3=8m*vu7SwkFl@nmwKqbUR)Di+TIuD9NpYFq;%nfcg zgBw1+h!VpETx3Lnnmri|r81zh0os%R)x@w~6R2rq1{xwN05!xx^*(_%546B>>HYvo zrjY&>=oB>6<_)M0bi{1lfJT5plLVmV4XBv|DnLQa9E=VZXg(ZoGshIIpaHdVAPt*9 z(Ch+#iv%di!Fy>a9WHWOIY?vtZ~0q6mw`fZD}hqRwEz^{@FtEgbetVqpR0gi34^xG zr4rVRfHrWj_qd=o!h2kxcmwseKtT`cG=ZXm$X*vXQoE0V+Bo1e*A3}qgGwS$(uKC_ zqhk*{b{~6v6DAB=;>3WEgOz}wh7hE@(0%EUvIjK$2x;PghNU2V zvU>~+;GP@{11O(Bnm9^~3=E)?g;*G>;HA(Uc!{$SlqA5V5NJREQucsGZy_vDeF-Ur zbl{~B=)x07KP?Gf3KhdkA<$KnkQs|EcqudwUJ7l1mqLf&rO*|4*>e}p0v)*w>8GVI zGccTmltRJaRiz5X|2?{IcE1M=2y#OP1Qp_AqYr~7mOOlV7lMYbJiDRwMuRnDi3*$t z9S{W1MSuoML36Aiy&nG`SndV|VyQM}ccFvIweD*k-KRm3#nAl%RIF_V zD~8P2b+&zBU|{He;b2kCQp)CFQO#PS3wNLkd?>*YVTNb-neG>mOxXIiG|K}aE-A253`LL{0GalAeVT8|GIECk&w1sMbcE%bu0K-mR! z!Z!=U9R>yl(9uhfrCXrGi&z-A;X{d{j0_Cl!3hkMUqN>{u`p;eGB7|)wqj&pNCan( zXt)m0!VicYJ&X(tU%+}ns~15{ZP>}p#s@r(GlIGk9-WRH9^E%RIvoW(IvpiEIvo`} zIvq7UIvou>Ivp)MIvpK6IvqVcIvoR!J4XEb|NsAS#~22NhW(w637{1)H6Gng91ugC zKqd%yfTs)`B|N&FKqe`8bUT4e)9~na0-0#w(d`5>)xx9O31qTEw-d5wc(0F&0ceG=Pxs;8U`23>Z~mcB zBMMDT9^L1AgIWHEJG=}8)nc8H1udWsu>oj=60{b;@=t9G<;8G9Hb8 zLCeO91VDqp44^J}xW!A*qC8O6%<$;-Wd!BTg#Y0YKHVR{3)es+TDw4nA*i_kDnLEE zA(KnHK$|Q)yU%)be*ilTH1Wv=s{1)StdEs3dvt&3%$MkOW$bj9@#qa@^yw^D01Xke zek-x})c)$*ebnRsF&}8(*QfibU$2dskM=X4UKj9!aL?}Zp1mO|&=u>+{v1Bc?|ih+ z`Dj0WE#lLC8mtU#txvK)hi~^kuwvitqn^Dy@?detV=Q_MpqW<4I-#$CBVb@4A?Z#T0O_u_~^r+NkCA$i-iGnb7v4Z zor3~mA2>~esua)>F)ZMvjR(PEpheW6V?S9KKvfNdB?XEwuwF|zD-_Pkg|qq?85oX$ zO#vF-;}~}sv~CD=XeJ9oJp%&+gvH3u!obg{$-r#D1S%@P ztExerMi2&VqGJXvl4pRhKx1~GQ3_@TMSC^|`zNXlCMmiM9A7}guMBXVp#7B)^`M=g z5Ef`{8$>5)gOW37&;(=w0|V4#(3TL0N{}6$;9ZZ3983%xN7TXQ!gPRSA?iSJ4q<`p zgXjRMN+Mu3XrU}KgQ5TngTNIv296R924r2Rrb5gI`2wN~WcF9kv8j06J{972P&bN^ zfdQlgq!`tI5OYCxLCgi2sSIi~ft2D16VN;zGdO)ChafIjcs)0Kd^3!(01V_*Qq z;}cZ|h7{1wK4Rk&WWE;xJC;N3V1n4efG`_Zd_vL+$lOE%X0L^s4GB6>*nn8L!UbY3 z$V|{_y&#n!42cg^J)i~*GXo?@oM$U1PD4bcHI7gP`7GaIzgfSEy&mxY1% z3kL&7i68^AE>sso+y=^V5M3a%L3=vznST)y=Afx<21pkHq#D(K5OYCxLCgi23917? zDnS?`kE-W7++5`FKve_L2Qn8D9w0McfeeIVh&-wu(9{zoCnLu?sv3wskhzdJ1ewW* zRI)+jQT2evib3XbF))1LU|_hy$-qz|$iM(fhasT*84zg^R2oA}0PVeout2*mA!!k0 z59rKrs28xNmzUtMVH9O!5M|V4;4I)sU^id`*B_wM!C^W?8UN$U1PD4bcHI7qk!#pV^=ghla@&4F+T#xXgy=0GVrpR6as{ zh#DrKWi6mo!GK~esv3wsP{=^c1(}&mz+7HN(1|Oc_7-wj;4&8y79cYl2$(AjHy1g^ zahVH=KaiQ5379JhHy0EWAhSUeNf38GQeK=gskg@gsjOwc*~AeA5t zkw?{I3pN*AqnogUZtVeebQvIJ5J(RL188U*5<3tUD2za@Luk!d0vbd?-0cODg{T9$ z1HuBu4nzmYTu?6_VlsBKK?`X?d6S8Ofh4m*=7Mf(z-KmS!5Xyvg2T6Yq7__bx;$sL42%R8bLezuWB@h;<28HMZot6O_)&ZFh!Vr0o>mV$U9iYA=$mgIoHWvd! z2@eB<3FuxZV(kE#UyW3XKukupqZpjJ!L7q1+ziM%KrVpj0EI4u1@aR_2guwOq&^Kq z9@T8nO)?<&gWB(?VS~$TNZ5eP1#O@Lg$oE{GrJz_Zbo)y2KGhF0gzTU1A{b3ITY7` zYhI9xAS{rbtzcbX-!yh$)~J6odup4@2w&*#!z`eD+O**ay1X4%BXY z!pXpJg^PjVhycVcke$%mNkFFHw-00&=sp#YN)U#)2i1Sm!S*q7urP2Ku@u0<95gf! z(gDJtyQ?7i1i}J^>0GcbaEKoPorJ=`0Mh}Ig{T9CID`cXafl9(D$vRVkhvfXkq5a5 z!UE|AZKZ>zFOtj#nG0G>3^EslAts`ly%OSXQ4R*t6b=U7FWd~QPe7rI>IYEHhUf<6 zYzPY!(hxs@>;TQ1gX{odh&-x2ptcyu4;%~(U$_|02{b(nh4SY#dYvJ17U$&0UE7hW?&RxW)NuNDS(xapsfo~ zP2f=>NW6o_hnN{ax(?M-xVaz|AYX!LR5cKNAeTeJ0%RuW1}%_E5QfO3>bVIvmr;s~L8^qC zK`ModK`MlkLCS=KK`KZLH2uN=y2A&g8-zhqTaeg-ut2`K4>1AhRzlDQa*%2e1`Xsx zbU;`j9iZiF(00NlwgT1!7I0buwSPf6Kp1rH0z?;t1=95zY!A4n6#}|Xih%*910)Mk z2l6|F1xgzb9UxVpo&(5S5QfNuLIJ`8>Hdf?`-uqHT$m1!EJPiu*$^EdRX>qxNr*~R zv%f>kW`MXCqyyv%R5cKNAR8d&g3JV+(Ew5j!Vq~>J%8cmf>eNf38GQeK=gskg@gsj zOwjB)NF@kE3>KzSCT3#1BE9)ny2!Vr0os~{|p`TP*`LH9#G0qJC50O^(F9Syr zO968Nq|E}leGaA@v{(kB8^QwVR)^?jV`5-4g6M!=p9al0q^Oe0JeF7qL}K&lSG z498)u3 zKq^5PVlS$maIky9t%?**27VI`2L2#!aIOH|MhMac!k}dukkkcXfxmq(gDIC0f;UL3#2OI|Zc8VsBdVB?Mq4E#uO0@@h_F#*B?nUD`Q0bFN6XEeMAlH5||EcSfY@dT3no%o~lq#l$lq;fTE%(H7_wYRRMm# zyaMQ;J+Riyyu=)Zl+@yq%)G>s%=|nC&%Cn4oXix6ij2g(l$=zBg8a<9lGGwpxs=r6 zS@2nW3OJ?n3sUnSj!VlgQUDo+q!)ahZDL8PLTO%Ra(+rGSRu&kNNP|G0Nch; zl3SpsngaJQG{~N zBgCmi3;{*?Wtk};k5(3>DuCUiu3D@PNrCx!>ENgUIaNU;CpAw&HAP1uH?cxNHANGr z*34psM1`W%;?$zD)D#7M1#r3tWf8DTKvpm~mXs7_CY6??LW8UbYz^4rf}+&2%>2^g zoJs|li&ImOk{(P@A-S};BtI9$0I&rhQy2mgi%P(b1s!S$u?ZxupaEB+sgRKfawy0> zsJ_ihEmwe@bg59BT2hjkm#&}z_A$)V@(C&xzjn{mN*Q}Cu+OPj&rjzj{&0_gBQ;}^Kb96bDY+ZK#+T?sa zH7B!Y`T{pEl9mo;-Yd#tYSAL&%x)(T0# zT-f!iGSq+5+*=!UZz_MiDVHjzA}`+3zhY9ZzfqgW%@ya>uNed{*;n2y`!|3!f5s1X zy~i_F7HJi3)reD`q_3V(e@Wm~{O7_2j7OSG1_$FT#Ii@zVDVeZ}DZHeon%fO76r0rG*CHT_P7uo-oZhDnw1q z_fJjD;+qT0=KkUez7r^&xazXjchQ)jCiT91MUMrqZTMO-Pi*tf|3TbuPrhExl)0gD zv-O;>Qcv%wq)+gB-*8)F=Za>z<-0Uiz4Ch$-FW@e-(seV3YP?Yy*@WRS#QYvVaj~l z{XCd{fnz z*_BBJ|2Q?Ht608!$ObCSIs_ zD|jhgzhdX$dnIB(rvE4V+mA7-Lf#JsuGvZf2ewZldWqWx> zU{>tBUmt#^MSN}&^}hCgOJd1t(<_U=N_>8M$(G^g6!pW*^?4m}7vt{l>v>drQ1RVf zW)oZXP27{qZaJ-6w&YEW*XQLQUfp08p719_H;*OjhT{E$^0?F=6!3p|_eA(Fn0mFH zic4ObMM<#+9q})*7H*bf}Q)fs_;JJ(UBBKWWYm5B79&G1w{M&c-O1a^T)IUEO-W0HBh%DbIDxvzi zC@AUXtv=qH!8Y=`Zv&-R%~K|&25$fT-J*V>b^et^yC#*m3EvOr+z!svuik07^0tQA zvX}3hPKlXk+_?H|G&=bD1;zZW!TCIri{lBi&w^&Zv zQ}X=aJ#SWT{@j4MaVj_xQuBF&m~^{E4Lzbf-}q3 zlET7rPsgOoAtro>l(>#(7)K<|nN#}xe@F8{3w=lbD=!ms=hbaH?E7H3M(@P$QTwzb zE(D2wO5yVt@&&2=fw@792Ms$&Y!${<5jOipXNKVWMXX=^>fIPsi`3OsR_(TO7}RLhgwp1J90KjTVgk zEO8C;fwoe!LpPbXWKKAGfuVzH)G#a1!OHs+Kw@1*p2dR? zU8}Y;FW)*fJbbl}rD<@(f!bMHvZ||IuKj&P;nsDn@P}_}C1k_*%wK-1yLY-lvtx+( z&t$Emce4DrIuv&+wOT$Xk9-w8)1Q0Vzbk9}pQU}$>=+s@OGs;*{1|lC;`C`QZa*;T9vcM+v(#K3O$wt+NSD(rn&(|Kr!} zVCy+~*)dtsckbjDd#;~9v9v3QpKqy-&EqF65h1S~lUR3(ss7(@rKT?z2!AGrAn->)yTV%ftv(rK^Wi9Ty6VZn?NZs!Qkkg~;+RKF;SRO9zz} zKijB!#oKOvlO=D26&FX?nkBOr{hW3!D39eIhtA?!2FIGZn57~IYS*p|e7b7d;%U69 zHX)}>X{Qn;` zBm5Ymr|6PTv7&FpUMF0zcMp|Cfh*TCm0KZRthmNFzBVECY7eE zfKGD*4Y@HeGlB*|Kxz;e`O)y_lKDg)PV%qdO1MS z5mOCl8#OZ{XpjM9PKtVA5vCf@lsGdZXy^=d-Mx0#f*1y{KalML9kRyE_@9x1L5zWc zLD46t7gG($CCrSVAu*79e$AQTj;RJTWy8z}8Zre<`CW-AoPwzaG(E}82paSTne$Fs z{0XKS(7|fVjGzHSkU18w8ago5fVz*&jG(~}kU8rgd9Y)u0c{*$W&{m&fYg+)IiHEC z26XubGb3m@6=)E4a{_4FDo8bQ_<&r&%m|v$2gTgZOWkpp=75GHm>EIS;2<^JK`QB( zY6L-(K8&CVSCEN)T^630YCx`FW&}+Uf?}n10Y??48qfeCGb1QwLFwyIMaX7MHJ~9v zW=2rAT9Sc*K~`+952hN>Msj9G&;lCJv}@GL^V=}hfKmiABWURcDE%z?74`~KjX2m} zpaq*CHI?ZZFEQ1CrtO#+L6c`7zyCP8P#jYY$feATpn)b(3>0-q_F$%GkPXa?py4u5 z?9RU#FO6vq$T!T4ps5&8zE}~)wFsgH6k4Es1){|n6u^0ofdOPINQ4hA0-7EMiHO2Q zK#K@KB4Th6(4uvah%j6v8N_8^VBm*~fR?R-1O?zCpvfzch#*`9_%L%9m z16B;A?vs7}TL6TyPN!s0b%q#0x6I4Ht=pim<^& zN}wX_aFHIU2nSqb2~^1fq?;3`mr&n`1l#aL_l>4Si}@`I;Yn%yv*o3l@RRdozHX4i+(j*$#?Yu!u4E z6mJFw22g#$#-N9E)fH%Y1v4Y4o(0)st8>s$9BdMZrv@^Tfq?<6hCvVM;w#W4OAuWk zJ5;;2)+2N|Lv?}Gpx6bvN{N{fVj2TO+pU1B2wm||U0^jRc7c|zAne*;sjQ69RSVSx zR)b;}Xc-VQBgnrX7jm|jw<2`ShUx;VL9q+8kQQOrCb3hS5W03kb%E8O*af;Efte8$ zBOtrZ7Hjh(bX|w)0;@r>OBr0Bf8Wg)gElh;JB9o@?KDG5q3bwQ7g!C7U7!vH!Y++w`8WH7It0PJBRw;mL$Y#}K+$L5)8K z1_rPi6uUrMe-L)X+DOcZr^b;mk*woouRtGYEbL~ZPA11 z0;MRUoM{^oy27Bkz-mzJ0+mCE{B`ToYhL+IK8)dg0A zVi%~yMcBob^~MmP>kL#ESPhC@prRX5ZnSy}sv~qgfa(IPL9q)|Cm`(leWj@cq3a7& z7g!C7U7#8Okq%!q?CwD5;sAB~7#JA9YEbL~)kp}t_<3_%5xQicy1;5s>;m;45q8zZ zE@nmOGJxs=t3j~~bVeh>uH{Cps}Z_fpt`_nQ0%e+#}}+TG-Fu)8lfu!stc?J#V%X0 zE?C*S_(A;%gsvQ@F0dLDyFeSmnHeFaD+5Dvf^9oOR|8ZRSPhC@_9%9>{aKNT&@~0B z3#7g!C7U7&61h`ekU zU+Ij{brq@$tOms{P~Qj%T|GwwLYFL57g!C7U7)3g2)h#Rvx*{gnL>4e)u7k~+J=nqm&ao73WP3Ss4lP? z6uUrIZ6WOPFnf6hp(_=t3#J_f z2whX5y1;5s?D9ql!!Ns6m>_hmh3W#UL9q+8Ss7s$)6{rNgs!7dU0^jRc7blgLHNtT z@Z%zcuDeiOU^OUqfv(*^*ya93l^LPyD^wR)4T@c$qtXy|SsdCj0ilZ*G!VrAITMl@ z#V*hSE`(iYyf5)0bg4phfz_bc1v;n!VVB~DGFgN!Tc|Fu8Wg)gTj3$)JSZ>o*dD(u z2G7f(P+ed(D0YDc8WDE+RV%h3bmc;Ifz_bc1v;4$kq$Lkp0OcxwLo=&)u7k~I)MdY z7iTn!9zxe#s4lP?6uUqN(jn{$k6Krb(6tS!3#!>;j#LgRpDS#4>w? zE-9!kuo@J*Kqt%~?CSIn`i0PC4AlizgJKtGYb`_;f&h zhv)*802i|*?Gd`tpt`_nQ0xL7TY`wMQ|Hr55xVN3y1;5s>;fHeg0L(5koq=+u31oB zU^OUqfp&Ev>`I%z#So!uD^wR)4T@c$QEr4?0XnKR2wfMTy1;5s>;heO2+;)#Ljiag zzJ}@ot3j~~G?E9=1q(xjE>=*}fPsMltOms{&~=Ike}Tdfp-T>`3#|jg3#edyK;f<8gpWBGUrWkI=qiWm0;@ss7kCjT+%DsU9aj*#=0kOX)u7k~ zUc?EvYyZKyi3nZCp}N3oQ0xLPN5&KZ9nq3bH@1lu?sW? z4{;$V&C4%*Y>v=X1=R&sgJKtW%RM7xRDpq^$c?KJp=%CQ7g!C7UEuAt3DpHwgJM@3To=f$pn~5W%y7GWpt`_n zQ0xNDo+0w`uc$@N2wkaAU0^jRc7aY2hqSRlA-`o))(?cPTBt6t8Wg+02lT-G)fe$h z1fgp>R2Ntcid~>vO%P>N;^f*8gszQHU0^jRc6Gx;1LVTX^A@xrbe)Fk0;@r>s|TzL zBn{G)v}xm7gs!I`VFm^Uuo@J*K<7Fl!fKOcc9*-zt(s=+cMk0;@r>3%mvc+!h6;d4UX-eF$A%P+ed(D0a<8vFnr6d}oBN zRH!bn8Wg+cfOUbg1jsJMyUQOVbTvSAfz_bc1zrIHkFOISe=;L<&4%g%t3k1A9@s8W z$b-^`KkLD6Zg|?*2Gs>tgJRcwxGsH@1lu?w^|36j4+x@PJ*Y(VIG z4b=r!gJKu>7&5rOs_yWtMCf7%El6QtU;wK@v1<|7g|Kw^uS9tZLYFdB7g!C7U7!^^ zh`emNuv8ME%O0u=tOmudC1AT?@ipP^gFb|=Xs9l*8Wg*hf^~sH9uyic-f{0k=qiWm z0;@r>3$$tj5{97o3hi#sV}r-nWT-B%8Wg+0$E?A_P&)jtD?-;Ms4lP?6uUsjDnjxX z$gU@%mnX5q?YaQf1y+M%*Gd$B1@YQ6Aas3z>H@1lu?ut?FQPnLyyE5;4!B+XplD=Z zU;wK@u?w_y8WCSx{dq+Yy7ZyCz-mzJS_5_=NE)=DOuIv{jihw1{WL9q+8h7giAK>k|z z^a_%{K0|eZ)u7k~J~|H`hI7t;<3`xU4_d0gz`y`jgJRbfaA?5t*FHHVr1;W?>H@1l zv1=<>7c2~a9nED%*yRq@1y+M%7wC>WNLv)-FLvFx3lO@Jp}N3oQ0xMo42}pxP5tNT z2wnA1U0^jRc7aX|M%Z=IOKd4Z*KDXRuo@J*z(=vc!?4#sKMbL3J5(1~4T@d6z@Y&O zLr`9Jk&bTUfv5S)P+ed(D0YEvbwT)RgTYk^gszuRU0^jRc7e`7hUfy>Rhr%s&I`Be zA5<4u4T@c$gZCi1Kp~(1;E)PJmndk_3IhWJSPhC@`@sH!PVF#&$_+`lUD{AxU^OUq zfmXU9?7EV5cRE6sD^wR)4T@c$6P+RX3*;|z?)}UnaJ%B5y1;5s>^cZ`AuJtANQT!V zbk#z2fz_bc1=^yF$Y1iC%g!Qn&4%g%t3j~~bfG)KUtS9Lo*{JYhUx;VL9q*Th&RHn z*80}F2wk_Ky1;5s>;fNa2v3K+%1&z#x_(1-fz_bcbqpLDpaKFE%VEc))+2ODgBCO~ zFff4CpxAXBtP2)~U%#`KAaq$nb%E8O*af=90+GKSo)i^D=!%Bw0;@r>>m-U@Hv{fh zB6L+lb%E8O*af=g5MkG{Q=Rb$U9+LOz-mzJ0v|aE55wQpGm{Xyc0+Z6)u7k~x~mLf z*O$)>#}K-1Lv?}Gpx6aE+!~QKetlxuiO}^Mstc?Jl(-qBB^bbmynr}N40=W29c3U6 z1Lz=2W=81n5W`K!>uX>uCK(ulKnso-7{F>!b)5%?Drij<$Pf_=wiyUrtx#PcHK@8k z>ra^(K`8~K%WmBiD}=7yP+cH3sJg(%elmjAHh^^LUT%~{=(-Hm1yX~m>k`<7pp{@C zUHxpwHzIU#Lzn7;)S&9R4AuoTl%Zs9!c~MWJE$&@8dP1N>oJ)bL93fUcAeGwVu{d| z1JwmmgR1K)*e=j&G?1J)4km;ycc?Cq z8dP1NW5<~pL2IHwx(;%_@<-@ufa(INLDh919EPwo|0+`hDdcxTb%E5N>H?h{#0<|V zC*Sb~A?*4H)df<6stdFRoS6}{{tD#6nCa0E5V|y>83?2XRo5f13qk9zK)UibMeRZ8 zN`&eHsX^5RKDw3>I?>MHY`ISlp=%~o7f21Nt|wr-K#iSl{`XM z9#j`d4XQ5C;r7gourN$hN=Ne7YN#%d8dP22BY7D?v)&-P`d3A5L)i5gstcqBRTt=B zVP;0q`Vf$=nH8i4Ro82+w11R|fFS^_aWFEJM(Qd*o^6c4V4K~8{eXpaYN zRgVYlPmhOf&Id^sr~bOlH&M4+T7GcP?J za>fD!Y%hL1NItVTzPKbYFD0=k1#B#r78T_eL4{mFM{GD3WtLWGIPK7lF)I*p_#zY@D-az<)$c6@GPdS)`Ju7bp(VpuXpl>u#Y zEGI5Z0!Bl|{B#4Kc#}QwgS(S=v7)r`TF#vpQN@7WBJVXiT zkOYSK_#99y#21&OWah^gfDUF!i_Zt2ECNb$5aHzf+}!-U__AV%JVQKGIb1vsA^}RJ z#RzsVICD5BX9R$abz~^dOi9fHXIXHnhlPJ}Mrlb(et8}POaOEeNj&Jx4Y&xz#VA6V zd6^~g5S5uZsc@BGVW@Is@xs#7qDpXZK}^m~%ubC5oq~eop3LHc#FFF;u&E3wFdo=2 zhP2F_99V=SiWf);200W2608jI@$SKpoK)ltN(!LRN=+^;$}Fjjhop_<{QT_9R0fsO zyz4b^RkUpFpkq{IQOF_Dr4Oax*D#CQKcX>LAgNst#2Qq7D+(sOnI~ zAnG8|imDD(3@MNyIT=)*FdzjqvM9t*NWdbCBL_ILI7B@pfRV)^>M_M3>LCG*sUA}t zq8^f0G1X&=L)1ee2va?#I7B@pqA=BCibK>xA`DYKrZ_}BB;qjDV~S%$7NlUth%Klv z#CYUjhDuKrDfz zR5U4wSFlP!bU}QHRTow%H0L2&-)PQ5l7Lu*a08MQy7Q2vAi5B4K$3#!!YYO2JUm?i zB)8&Ih3o`;>X6-oPaVWONSxzS2QiPZI*56YoJrU`!s;OAL2@Et^9ZX$iVRRs3ZvtN z6b;zrAr6A19PBC}L4{8R#0-dI@tJ{71;h+UU4qXHd@7Iv16%~aI-5v=fGQ5L6yh~h z8DvkR%0To$at5jlL=QF@h#rXdvFX7k1JMKVE;c>bWS{{MkJMv;`W;0Gstltu0ac4B z4sna23Z@Li&)8%jdW>-D!6pOIV~kS|HW`Q>6P$Xm$v^`Dt@8x+KDsDWF{~#A?^;2X zV~V3`05yOh9V9dzND>fF7^uJuLz04oFjgsuE<@b9uu4I68R6E2RSKfZ7`HC0QfNT| zNyp$mCt6q_%RsC`xE)yz5*pa$Ao>ul$JB>i4x$g?eoTGX<5dTB!J>0r+%R}@dx9qXmj$0n0AJUe?Z9i^#h<-@h4Yz*W z@(}&Vy)kU=$1M-h4`~D7wjZaweY`(pa51rgT0EgTd}>dy{Wy5vnPm?lapev;_L+$a4U9zX>kg0@DFfw_i^)a zfSgBdZ(5RXZweV>wKvU$3@+Q7f=4jnx{O@BoxMFh{ahgSz{OqM90Gj&oZNi;d{K;p z9A9m33K~$%FG?(`v^NFKd%*QM`8xReyLx*1dwDrP4?~8ius4NFN7$P}kFZ8)@pSO? za`X50^!7p5f;iY3uG-nn!Qa`>+uPgC-2pWEZ*K}cpBm)de0x*ydDmcX+na(;yoPIZ z@^^3z@bdEU4)8|vQDO?*kkk}=Q_z$OLRWx;tFybiucJF^IDj)X9&LUO0d8JCE^baP zD3*avyoQBGT7D78fW#EIWzMb+?v6fw&K^E~D7wHS^ob>@_NLIov>`^o^*Q-F_>Qj_yBKvQ-nU}0EYl?4?kZQ zKX-&aQ2xQR4^-qJ>~nPRadP$x@ON}0NuPy_hpVTbvy-!fy^4!3r2Mm2aq)*6?CkE~ z=I-n1=;+~uFc>r+2k|s&UpND<&Bezdz|X_g)z!t{0e1Aay(vT=#4Gj|pyX6+Zviq0 zlr8h~kahcexOfJ*xVjV8omp&enh1(dgmxzfA7@X;01rPG2lxr#uuv}oCnO=} zfg?0KI=J{cIlB8hqUL9qPwh=12ZBS*gX?p1cW`m?b@z97b8`S4qzy^QDfR~Trl9%E zOwcLhD7J!1Ye<0DTfj|m^>heu^>+1f_Vq_M1$q=WiWwP+5YOi&=E99|4sh`F@b`50 zaSd?r%Lk>=qLN~JQ|J-kkZcJ`QQ(3eRKg&1Iy$&{c)NPLdibGOZVC!w=!xL=rf_$F zW@zDheH^^~eFI!wJ-r>kvvS~L!W~d%d?0f@T>7S#1`0^P(9G1()X>1v$OK7HK|#UL zz`)GROhLiW+z>=5C@3UwrL=`G^zaoV-BDy*Ps9SpeQLzxJ5Ab(gB zsVOf2C{}Q1Nv}Tf37#0%{8e4pT z4zH6ZLLF#5nkNzJK-<>Sh)@SQ#;T79b)ZAd&Jv*xl%APEg)hXbU=o{uLE$1pggVe6 zab`rQ1DTgWggQ_;)I@|jP&m&bLLDgHwiBTabOhx?BGiG7K4bzFs^E}=5ZJ;GFnock!(|>Q3voy>Fvx-mI6VFZ zsWX&fU~nU#4itV-QVa~GP<3$kA#Gs+#Rup#+j^)P5Fdmc1PmPXK*K>G4iqaeF)*}9 zF)%Cvd5D350hI3@7y=IHB^85Cih-(PU;x#ta1NBwz+i9yy8iUq87-1yAg#Pn3~>OvHy zAft#>ip^B;dQi{`PlASGSBY$9Rc1jvXa#9eYB9)1@j0nwsW~{!C9E3R?3D6E6tfFU z6LT_4Dsh@ls`^yWBIJ1JP%Vb35LwV=dhv;%HP@gO*$SZa^O1pp0d#ytAOj<~#T;%G z0~-2EttisXP0Y-TNh;0ENr@>gN{-3NOp5U@NX>JN2y)IZN=0VtrDPVx1f}MrCKjj0 zBqbK7>g6Y8F<3F!2r?uwFkD~|W{_dHS;7FPeKV7b@{9A+N)$ALG!;OD-MN`npi9M^ z^K%O_b5e^K7+fQQ;$4G+;)6q-on3>2;e7wlka&N$cwbjv|DZ^?sIO;mu&1AUytBVw zh-*Yhykn3%T+Y)k%+bfw1tb>g>*^N*mv9Vn2MfeQ%?xt%b9aTyx_SDz#yg@~4igU6b%pZ3_%zS(Hjra1Cj`F^@HmGX^;2xhx0-5 zuE+wQoERVC?;r2u?}zXq%=baAf$@$ZAqaQDy^bvC=MPpC?-UsiG7fGTNN0RVWPoeD zuV=8YV~Dc{s#LIN6c(vqXGg#I5Kvh8dPcaqI0ksab%8~}@)%OS{w|(wk?~+7ojp*( z-O&dW3X$>QLH;4GV3#5y9~AV?9-)5T@jj>#;Ork16dDi`50->Gz|#*T?&=&8AK(~- zhMvB=zdQH(5yY^5=qdletG#N3gD&h@Jk!9sbp}(rad2g^Cd*PLQ!H~dMc7b zK!pk9>Pn4*#F7k!l>F3U1(0p26`92)3i(9}1*t{g5ybpFg_P91%+wT32GB+Yn5z== z6riOJ#F+dd=(UMSi75(@Ei)jiOH(1bKt_Y?Oick_=m?q%z$yVA>xal7DF=({C?u7Z zz>Ef&SD9L(0Fo(5&0_%X^#EU33M#MCit=+6ic5-86LX<5Aax*_l6;tWNNNQrxbwj` zI)WVq8e>&R%SlWxX7GjHrU;sd$}CDvQGkyKgKlI5?LL4y1Q9Rriz_qpz;`&p6!_&M zX-=wCD9K1Hfn2AFrVu{xtpFNi23_cw3tG{SbR{NOysTJHp*XWD6-7a6ZUM+M3Z=!V z3W*BE$%%P6nR%%SiQx2?UxY|gple+d6+l&PiUPRe2N{p58zPBIE8J`h-MRTGnQ4^@ ziI8YlD9=dE0|gdj!-_&K=)zdgjE_P}W?EV*Xip8;8<4op%mc?{Dp(mxL?`Be(n=** zx+FDEMe4|KIFXaQbokwR)pW(gvELHG8iRurTrm!zhE(r|KqQBi3DI181g7K2;^ zYWgW8<>V)4E95}#Y%MER0JSYjL0ZZZb4pVgoT0jq)Pk5g3Z;38Nja&YTR2lvL3K7m z0Q5>yNQA@EBxKcgY6{rRnR)5(Gy*aOYI#XMST}Y<6p4u`?5P zk1^;{Qn2$u7odXDrzY4HaI=tHLaI5?xn`J`!GQ&Xfh>k~E1y&nHPk`H?Hf~P7xx>*h$2K9Kpf>naLuV26{ka-*s zjh&1ht(Qt*9Hzsd&4!@6lvuzwqWmOA`7f{{(4fn2FblJLdxUUZyS7BrT4d#HlV2li)@f}c3WMlx1OoP%k zBLiroHfV@}5qymWXvCF~0dzqENG&4+Xk-g?nGPcZ=umex2GCV;pyR?pBczNBpo6GE zm#{E0fQ~rU2g`yE&jpRYFfxFSWd&{aXJh~!_zAisgOLGrlq6{LIwJ$DM02)AJWKdvaU;rKN%gCU?$iM(PM3<2Pbkqdsuv$h23q}S8 z(4nx53=WJ844}hT85ukn8NhyKWC&nnU;rIB%E%DG$iM(Pw3Cq`fsug$bT}p>Lk1({ z5K2ad0!B!0nUSG_k%0kps3Idn10w?i=r z9V5d6M#$lEj0`In85lr^xG^$pU}Rtb9hSz(u!9kDC>bNe0Y(M}(BWT<44?}FLE*~C zaDfqWm=z<#4MqkA(4kR`3=bF?7(jTJX?N#2RfR_zbz&D@?2G&rt5jKg@#g2-=eNIab}s9;c+>kj^~6Hv z85MUAitjPo*Sv=<`3mcUjmn?BUSC)(C|UeUXI_TW+&2O4%t^&Tj(0gO`l_)^sHj~0 z@osw$!;%A+j<0f!+4iomTea!Wr?)(dGbV3QcR#qKL_nmw=7mN&Lwc0`_Xynfe^;9x+xu<*>*L4U zjz8gFo@wF7a;E+4C(%2#dLHs$7o|wJ?Rc~}`Ff1IsR9xQ#7TyS#Y|EUYwCLVQBo$BSg@j>#gncn4h<=ySx-}hP=;cU5+ z;RJuu95&_~A1l5lCOuG`ciR2pb_0*E2Ge{r9S; z)xyqiOG6%8iRGqF3wix7Zl=cVA|5&8ZP$#`SN}QGyU8!ulykxNCEi?*rMZu&e9Y`q zdiZ(8{>F(dLW@gIWB00ah&&lp~%kczRCDYtgAP*3{qq9|E4O>Dh3x zleY>+m#k?2V3wv(4U_k`&UXwAk=yJiv(Y^2q)NzN4s+e}GIOF~w35TxX+Mg;?EAF- z7wgWDWgnzAOb`v0vj7zV-~v<0;xq4;4pz_!|6o3OSKLBxT4czX#0DyauwHQsTIm6{ z0!|>0v4Rc@f*g(nl74#TEEhO4fjA7Hu`>_@qz3gU36KmkBdBQrk`H4uJb};!D$hZp zAT_AEKn)7W1z{lhDS0L`2wkAdGeDvsHK@8k_i`~aLWji}+zvm9M(6?^sSMHuQiG}s z)I4Nn1g#DM$)D!65Jcz#9R&yy1*t*R1)9Z$9PI^?UwrHoJ3<%eh!&72NDZnkP?HI9 z(Ak#f@BI+EI2l2D7#KimP<4SCY=|&iHal4iq01Di3#0~B7pO*MW(3ujAai&08@)v6 ziihd~sX^5RJ_?Lc8l;7Rf#GZ6gf@gO*ae^S$lrzP0;xgO1zHk>2#u@9THYY+VghvypcgNq>H@W35ozPeH|D(v zT{=)*AT_AE1i{CZfSb(>3=DB%Jl+Uhkx*SAHK@8kGgpXMj@VlBs4kEiR9&EX zF=lwk7xNURBkWoS)df<6steRILg?an(G!Evbr-4&qy|+N$VUiW*RHeFM@QiG}s)Kg(*1oieoy564sdJv(D4^(k6Fff4Bpy~pxM_`5@C@19X zKOdpX4XO*I22~fR?qvpFhXJxH_SOwugsv*6E|3~jU7#KmGb3o_4@eg~V?qZ)*Jh|L zkQ!87ARjR^g4O|nbS=I9s2!o}15_7C4XQ5i^_uY7{FeES{|H^$pbD9RfdQljRTrpd zhY0zFzHd|!x?-TZKx$BRfsT@6W(4&BK`vxDq>_lx)d$rDQiG}sbd(&zuC-HJCm?j4 zfa(INLDdE7aUyDm9m3V;5W0Rsb%E5N>H_t65wU#0dh;ZNE)7sagMk6uD@N4?ItC4q zqAo1;LOQ%I4yp^J22~d*9GDqF`3@8se8&Uw5Oz(2>H?`j)df1l4{-qChne$FA#|OC z>H?`j)dgBLf(VVjp07_Mba8;1LJSNHAT_AEKs|JX3m-;BKS$^?gX#jQLDdCHfy|7c z{yWHDZ;T%VBXs3Mb%E5N>H=S{3D?yje^C>mYXwvnNDZnk(8vKZBY2R5fq}uU=f@I+ zu7^-vAT_AEz}IUsf>t(xTv(sfh;)deG^mNkz`y`fgQ^R(GKiTGw9W~nOIDou62h)9 zs4kEiR9&DE4Mf_QG1DKZ<AG-E2dTZW2C56B22~em1PF1I-^X)INWGgEP+cH3sJcL@ zf*D?aP5!id3&MpepvEqvyq% ziD?cf4M5r?AahvrC(p)I0~*m|W`wkm85k0-x$|PG0p(&sY9QBHf?A0n_ay4>UJfw_ z6j%G8vEvQD!u}dm#1}5|6Dr~k7m)#Vvlti{{NN&XP!SKfNCH&EA1=}c74d|NtbvO7 zz(uY=MO@(`f1o06a1kj`ca4F8!3!*coGU?t4$O?urVm3@OwKMuIy8ss0;yqQKwc*X zzFw0Nv{DR|XN1+xfo@X)1r7rPgFjRkSPfV#g^z)OgOPy&AyUc503IDhi1hF=Fz~?D zAg?t8jVmD9hhPK2M6qvT1?Y-O5C^P=0VD!SwV=i@L29mp;eksW*t z3=&MpEdgfWL>Ur>hrS4RomxWcd+7rLTj#i;s`L zyQec;C2Ua+(vl>EdM^i8KR;I&XBT(4de}M;*s3IiVt)sJe_t10Ur#5vVwfV7rAr7M zt_}en{*KOkvkAj^~xYTX@NoqXK<+EYn+>h1^H$q6?Vt`fYe2BFl)!QI8l&CeIfP>8+YB`+YwA+CN1<&F-X zZXOSlR=Ax;yn?&5}lkJoIO0;oxT0s;A%kTfR<4q403ny@o{tZ^z`+HD*~;B zf-kK?sPuC1_Hl7>^zcGh35!|Saw~*lH-`YX01szhXN0lvXblMoLMZff@NoC_@pSh@ z#6Q}yEQDGg2T$h!S8pd5L`ub6s)elF$IH>n)y);*V6bxVS}WMfE@b5%F7BS5?p_Ed zgV!>FS1iHSZ6Pc7bn^Cg^!D+C2OL->SPwSkP62M-uAYtve_}5ELYVIB;Oge%@8##~ z3pX9haxjE?F9%mgCwDhbf4Fi`$_20Lg02ulsC9R6a&qv&R~L8`xnW<_2G`@{=-}ez?CR&^ zi3n8aLN~Y?^8hDLA8$uD9|!2tH@J+Gw}Z2nzmKPzmov(KcG!YA&}jy_`9+m*4bI*U ze%|hGPTu}r4$xI{_NK6X6fUERDr96&4UK;8gthcB@=P0X`5g|4oH8H2L#*U8Jl-^bkMG7J zf@^ejc5wCZ@bYnUc16_)Svd%{6uh*{-n2X;H4iDPxcWPIcm=rm`nki>J1ERRi6qtD z6tuDsB_*a7A!~JYaPf2Y@pN|$a0tzVEe^Cd1*MZ@$U;AGo-R!-21O>^v7okshhKoJ zzn8BAbU~m!_#6>?Q}FUZD8~SFfCp$99zvssgTIr%ldG?n18jL9WJ^CZZ&#+4fbulx zAbC)3Lg@2$aCHpuatiSEM8nA_$FAxIPzG2Um{(A0L0800-#0LFDK_S~>_yNd<@!-pR$m)5XO#z|#YCehYZ< zpuH)0^`N~eX!)Q6_-K64UK!{TL)f+(usHHY6U^;4U?m`}xVPDWm0&Xk6j0zjJ75*q z3_(?aYzEd1G8pFIR)uU9j_oiQrV*fsyjEs@b%rGQyl7_K?kvT*?=p+q3@JSj* z>VN~5l9k-xiC-C0Id{Th^7vFl12&Y&c}ZY3=EFU3=H8y?-iJo(q(;}1XJ*!{ty`=!Uh$4nlbE-DTlttU%4dL5Zw zf))>YH2(ho|9^d%9LPWoAIR!xm+o^eoh2#?yFgL=KhWc~y+`Z+QhumxZ#eV+K!?}b z{DMrM_yt^496s?2Ith5R-Y(Jd=sx{FG{U3PUBILDK&fDF0Ha6u+5e#y-8Whfl<>XQ z_UMe~=rnifEN3yk?a06W+rei{F5Smkzm*7jbWc$MEe-YP_7?yx&}8U7?9m;glHk#u zqmtp#U7}Lp(Osib;n92~z%lMHXh|n%vV?^JwD1x%$;rY1x|s^Jh=qm0A=sn&je|$` zEsySlAkT94Ix=}QA9092405EN@k##h10J0|Dh3|iUIL(XDJ}-75`G4$6g~#25MBl;6CMVsNn)VY zvkagD50oK67__K|8N5IZ!U7c{pn-d427D%fieQj#5C$#qftUbcflL4m*)uaRvN18R z6)}P4W*I<*F-SECgCQ^ zs8CQXRnS#X&B-ZM03Y+F2{)i96}+1#8N4qBrZYb&D>WIsBMEdIYi42&=&G0FW?6IV zZ}C6k>AZTVWGZ{Y78Aw&Zy4KNF{oZ?_TK+;`q_X)COL=D$2%5lam>xT`Tt|LMc}$; z%b8*P&bUpc+(EU6%-Cd8ZQNqs&kuNAw)(`@`57|Z%!`WGZ#B_M>Dc$u4z!3EpvJj*nM6-hDH$W`d8V_c;2&lFI$*_P$ za#M4Y3o1c;5LRGdVo>q%15M$AxZq1p*+3$Opc!P45XkLd5tslt>9R5CA=Ry*Dh4rU zzH;5VXjZUEApM{jE)We?gK|wJXlViBn#%u$lR6N(GC^7x7#P56Q0xLFT~xc6;dX&m zhJ!SM)u7k~n&3v*Rl)Y~6+##25^az!uo@J*Koh};wKmDB&Mho(yFhEULAt>1bJyaJ+4eF(5pvf9$Mo{YjWETRLGeRys0}WEdL-TMvDCdG(;3%SyQy($K zq4!Fm+zf=G5o{dN0k>Erkq*a2k%iicOEXLwmv*?*z^y&-#V;tv!{ng{wYoYvxO%%g zdAlK>1PLl8?O`X8LIza8qih95h#?;rX9o{YH)kg&SEQjLc<~4sT!99zy=i`u0|S@7 znW-hDeGefC^#?4BETHN^{Q)I#e}G8@veN<-o7nmTDWGBmBniVf`U3~i)M4unoMvQT zNMvJR&;eyM1_lOD-Uhed(fSRbJtP?%3=9sStOc6E2d%loa$-s&Xe}#L4a|Ai%mZEI zc%PF2vSSRq&I0?1DT^5y7_M_MFjRpu6?mT-c6Fc~WQ%wh80Lbq2p;q1GcYi0Nf^;z2MdIL`4iFx-Nw#bq8y-4Cc5h)&Q+Mg|UgSj=M)U|M-pE zwJoZMPzQ3~Q4DpM{bkU;wNGg3=+)Yn%^XN zbpP_`{^;9!pj61Q*MZridy7g30|SFc^O1!3!=PSpf$;%Q$GU<){D4pA7I3fBx4S?9 z)OQZ>ZT-gIvKn-hX|jYz_iGOjcOghOa{o90+-39kX#5NA?1}hvpM`dv;T>utenBQs zubE%aNdes13;=ba4O(xPn1OoCVeme*I=EYR?td7#56#~S>g9s^$UfaiJ-e@gd&)0C zx4T2dI^{jPuXVtFn(ALD>aAr`i z5@gxyGJZiO;^FM!?ISuW9;&jRXs3tGl=)G_}LOYrE77wDAljOPG#_$wft{{o+G zNbsY^Q91(y184w%g#ont2(+P#g#mQ6H)zd03j=63ID`eN#~|vGpgTEP(1%UH3Bve* zXZK5R?0SOw?Y}&_Z-NF0V520U?U|r3LmU1Gfc51?e7es;gA*RT#@M6RqxD;f0w{ok z;qeO@BRTy)7#zPPoUf%j&5dt&mUDQtzAfPghgSD7kM67B=!6CfIEX-D0v<2{r(1h? zm_#u!FhIg&7Xt$WBqTtongi@t@Sw;~(4Yt(Xi%g(Mx_9n@LO+}_<+VkK#AW)B>)sT z9F|U?$O%vI=ne))rjSRsGdMCiUAmoFJi5>SzW^C80S%P!3pyi`vaMj8f^?)*D>;F<&Xz+qlC&8m z13)83ph2UAc#r>y9=Kyg8#PvBz`5?UN4K*DhA|JoBE|wyw&P?;B=(Cy6uwFqRVWB2t=AC-ho9~A|U?(;64 z$sGT~JziUZOzUL!=*$)Xd6n6*lMNhD9-Vry#K{Y>=R7FY{=eYUnJnSbnG7BY%TdYj z>8=4Md3bPx)}=zCZ7y^-I16~!GH5qA3xf$G19&$$q~wqY3kS!gf@ktalsFUw#bI}h zN`Oc65e3J%_&Cr=W2s1QFf%Bzz(qa&CtA3+o~%@GK`k=S6?uSS)xo3t94KNvpaI)@ zpcE9U;25xY9SrgvsDQu(ixhOJF^8kjXR4uKw-z{(|ydd z`u=J8B(FAE_>vm!R z=fM9Z>>k}t5}uum5O*Rg_vsE&@NKMh-Ao?6;Nj{Z0Z>K?01aL% zcyym|{C}zSK&iY(w~vZJcZf=WN2j+$XD|!M2~3@0V8?rO@}s*Gw8|Qi;+HZoFn~@% zU}0e7XJg<`;b-7C;bY+6#0?%)0rgX1OiGFo=Zk zGl-b*F^Fsu0P6!49|PAWHn1*G9~!0$GPDaC z8-%bxx6m>C%DxESo72rw9j@H6Oubf*ZyO#t=kVJ3ift3g~1VS!8l?Y&@z`j>}+ z--MfizX;-AP&~xF*7jca53b3;bTY-;bq_n;&{MzfTe&r0Ww$( z>aoL20PS9bm;hmcOaQOjhlUsjgGdNFgNO+mgNP9%#6XQRm~PN6Hi&Kr3#1zqZ_Esg zRa^{JUpN_xLO2+BO}H3%jW{2$7qEej-(UcZ1i(xH?P!CT0AYbl0A*yvU^#p+2XqD$ zq@}F@n#ohZI^GRGzzB3&7wF(EWE~oav2-1U+|uF_g``vk8(RfWzYt@icwff|O$NVw zh0?r&#N=#+f};Gg%#_q3h2nzLRBJkSy? z1+XDWrJy6az!L(XQ?Ec`sVQKtf@%r_R{bUU5Urr#z|^AymP}1iKr$I*ls~w)0tv(P z%rfwaVc_%b6!KEj6H7A7QX#f#sHSK#z~&FCc{@qJ`{-iPMF?vta?7*HHI1mM$PUkT`zhwQ<{_Obrv|a9=!G67KraQi^}0X$Q&)bEG32M zj%Mq>>gzskh2M0Rir35TYO*e}?o+>V`G3Si-AVI*pX<*D&9Q=$?7+@%fJzO}_@9$s zYXoFo0&{)?RHA{#BJ9{B&SR^ zjG&SPRPvRr-Cm5T29%eX89})nWX{yMZ+kkdOfCLfqHn|`!0|NsW z+#FDw5G2SB7XkI4K_Z-R5zwhJAQ29*2>#g~P^g0EcHpx;Ah&}>U=9S&cYsAqKzk)Y zCWB%UEMf?%Q$Ql1&;W}Vf%a~KL_l!?7BPg0fI<}_0@DSG3)Fce@T>?UY~XBP#J|sM zVEaKPf*RT&8mtCoz6CT|iI{Jhtv!n!p$mMJ8Fc1^8D(w8#)eY4JR)b;}Xc!JLKenk*cPnD1YaLV4nlQ-)S&7Dx2zdqF0A>|k92y- zFQ_h%8dP227B! zEs`ck%Mz;;sJVw#0<`cGqAxWCrvi}f)D+BlU?jV-P6cDgqfh4|DS!qB`h+kR6?hDR z1sfhy;7afq0}f$4W3Tkcmf#*Rb>ykC)LH>!8yRk-Pzv_X^A(y;{};ThZq1}@eN<%?ds^@>Ei0< z=Hi4j`;IhIkEACNvMUF4ogrMiv!8>Xv%jN{lM{Hm1|-PsO<_GRdsBGV3v?YJLYt3+ zhm)J1r@NmYSRcqQICY`yOK@~>@(u8F_w;dd0ClL4w=+SyWZ+!_pgtLB`vBZRS04vw ze>ZPOe-|g5`al~6APz}EEZKMVa|rNtcJ}h~adLokyTIX>Xm1Mcc!4%QfO}r{rr@p@ zcy)p$$_;;nRwo#m7#kXb7cziWCpd#wCveL%FkFI`dDvDb^njX>PaeX&0PSJ#6&A{LcYI;H2h}c#gfVOz==4W8=2Q{|vm>12+ zzz`|Gz_10>yn@c=Vl(d)0|Ub)K?a67pavDVeu1tgK$|rOS+@bI1{@~f*;4GY+y{gh z7|uY|f+{@l>@}Ksp!W7Fs2W1%fo4JfLDk|i57ds65oTa805$QT;R3c7oXuf2KvpeT z2{SObLDk_iFGZMvp#ohU7W1YFGcYVdSBK_bkoyh@Gca61SBJ&CPr?ig|IpQ;nFng) zfbRLS02vI8UtInT6JcOTLRW`o9!R=Dgn?lSh(W--O(F~o`_R>)nFmTQcSIN%-k__) z;$JRN1_m)ua~auQEasVrGBCKHtHWYmk|+a19=bX#=Jkj&Fw8+$hsC^Iq6`ej(A8lv z?};b_!xwaQSj-a=V_=X2HT3cL7j(LmjTi$%3c5Nh<~4~iF!Z6TLvtUft-nT$f#C?c zIxOZr5@TR^hprCIJW%}dh%+$AfVv*Y{=j0Ml{f=~8@f6)^FaOP6sQ_lZpD?J3&a^1 zYM^Ryh2Nn zuZJW9LkPM$H1k05TLe`@D1PfC85p{tYH`Ics90Gc$-uA&T^$zx-jZZsc!sVH&3&NY zV3A^AkO6g63Ha9v={_)A?gNEiiWCDw2@&Q^l44+(hprCIeIWDpNHH*+L05;xzptbi z7`~yaLtAwPT0kuV>Vm@}16-eDu6_dbe!YoM2O485!%$~{aWA1B0|P@XhB{1pLG7m1 z80s)rU4do@e_^P@G!JwhlLe^KMDZ`Cd7u>-br|X}%>%7k+lx&d+I?!E^K3q&siWH} zuIb?AB#huDAmx{JL9gtN2i@3B`PL_o<~JV32Yk9Og6?(@^f-P1bn?B&{{xNM`2}563_t{89~C1L1A`0yHcuws*8io# z(CJ)9$l9uxPZ&WrPaNQHxxvK1;Micnz~6F?iGjhj^)`RYQ4quWW}Tc%XN-!*E>KbD z)9IoDn`!)v<|NC_2s1*2gXK}QCt4s3j_2o#L;Mpzc*?quM`vSjw11PibZ{x7y z5h&&M_X@(Y&}q+TO#P#TgB+vd{Duq`?~eNn!~SUeY;P9odtCw zXe(K;$4k(vG{^2=uHC0SdP6|-{HH;VWN1B5n$z6^c6X)2S6)U!colM z1seASJHf)Iy9BfY4H60--H-tA=>~g0MWw={8xlF7N%#N{<1=9Ac{CmYB_qf9=);bk z`7Ezle7oH_Jd&^bcAxXH{#0k^*?rEl`zXi(p4taInNRp=pGup+FW|!Qz@yjm0l%Q5 z0>6L{hXB8zr-5hlOUBYCpnY}*9^HpL4nAOY;umCL;1}>wad6@n^kES2wLV(n)cU{9 z&a?Y0I08ZU!>Hg%={SmbGjUT*Rr$ogAvRnte6&pjCTppw&!a;GK&Wpxu}J zf^4A0B_80NgbI#vhe5}lL44s5?il6>T07(5+x-LVzMmegm-t&iS4#M{9^h|L2WS5n z70|v!(E7Oo&twCT55W63L6=|{-){X@DTG*01X`LB=5111%wH zJy0qNUe*TMBiMSNMBpXpQVx&q!=9aP9FCo3EFkY^cyzx57ay(P>H<8vKZDY(XZJN9 z=3|cC4l<7X+dM>EyE!^tR4g339V9wkR16%u9Rz&49XLP*tVj2GQ0f4Oj!XB0)&r$F z9{&$}G#^v&u)bTf8MFolyaWrJZNQs5LHjzJk2pBSJI2KycI;;J?9St8Jy0j((S5i3 zL)rvzXrBk0=K&7wcc9R2eOm$!<8V-@ICdX#G12GJAP9W&!3dq_} zNC^)LO-R6lVwVFHpx_0G3ZBV7JV2=feI=p+DB>(YsU-feN9#AlO2jbm!Y(9f&`Lzt z)&rGFF5Ty$NgtdQK#Olsm4Q|vy0#vu(*`Y-gA_ra@<$FFH}EBgD0&`%LJqXbsndsdf|b+CYMV1f7;vYLmTf!~CUf!_$Sx&<^|15UvV3=E(qEo5y7gasN? z0rdlz85mg@8CXEeYC$If!jv;GFn}6`5FHQ}NC#wHiKG+@12>~E1Iq`<8W_-NgP@8G z)GY$V2m`}RBy&IwE{Hi07RVgXxxvf~iX2P~93h~1Lg)a=Lezmwgs?#ES%?mhxuB)b zFykTepveme3#1#gYmk{ik(G&o^$0)MB`_TzS%^ARvmrV_s>DEb0Mu}ZN>sB!lgrEu ziZW~rGFSK*L`wu1I8p=|kadFG3egGbbwF64{sKfN$oxYD>;Sb=q3(ae%Ydu{m-`_) zK<0wZKZH6Td}2C!xP#6oWo7`)@*taw>PLv1K_LV&7i6X(bY>1@Hbfp(52%2Ln2Q`1 zsA?ekK;}Zi0%WEc0dqkq3t}#E%;Pc_5|1D=?Fg6)+6E0V7vv+5*&rI1xsbF6GBb>T zxu7M$Aai*b7@qJlFkIndU^v3hz)&Kp%yz<`$4K}~%~sDN@JgaukT2C)xhmjom` zfgFc5K9j(`Pesr=JCHqS=7Yi-Vk&B?gqRO98+O+K$O4E;)Gz?u>jd%-NFI?#QPn{7 zf$V~q3o;WlLJiRaIk_J_9fEFFg02KCV*9}IfC;=35VYF4B}>x4v=D0H4uFuyCCL*%ml?WNF@kEs)6VOnF|RIkeQ&FB9KZDhRCDp0o@jcSVao$+$-dOZrUx#&&(@HEdnhlP0j#` z#3!bt#Dk9NiqA>SOE1Y_@Pn;{%qz`JN-a{zPg8)JP^~w zgL6h=US4Vr(&3LyK?OahC+&xI(+tVqp)TxAQNIt8mxNK66EYQj7Lb_B@# zAkQOorxqor7L=4G<|u$}vP~=kU(5@=S{7tCai)OX06rfqGcR31qe4M7MWIqbHANGz zcE^$uP)LCsm6(#EkWyNZlbM`Yl8WJEXgq*p623e&f5s$fyZBE+l8cq^Id)pdXjISM zzHDo_L=?j+gB$w3y}uvp{>~9?Db~3k!dE`Ay({_rg)3a0i__Qds9hi)>e+uYXZwN+ z-d`_y?Ko^?XE?cL!w%&+bM0ylNVBjUni_DLYg2!N$fLz`!z^Ci3r&$aCg*#Exzj`2pRPg=*_$$Uyl z3ePTV-n^;vbj9CC8=0aFG{0|eC^F~X^tWU7v;F6*YnlSs7KCZNmT_K`$Nl4lTd0KU zv�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 literal 0 HcmV?d00001 diff --git a/vendor/openexr/exr_base.odin b/vendor/openexr/exr_base.odin index 0db4cc7ff..3301af08b 100644 --- a/vendor/openexr/exr_base.odin +++ b/vendor/openexr/exr_base.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" diff --git a/vendor/openexr/exr_chunkio.odin b/vendor/openexr/exr_chunkio.odin index 612db2cb3..9ce9d0914 100644 --- a/vendor/openexr/exr_chunkio.odin +++ b/vendor/openexr/exr_chunkio.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" diff --git a/vendor/openexr/exr_context.odin b/vendor/openexr/exr_context.odin index 958e30490..b74986183 100644 --- a/vendor/openexr/exr_context.odin +++ b/vendor/openexr/exr_context.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" diff --git a/vendor/openexr/exr_debug.odin b/vendor/openexr/exr_debug.odin index f2c8e18cb..9b66106d8 100644 --- a/vendor/openexr/exr_debug.odin +++ b/vendor/openexr/exr_debug.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" @(link_prefix="exr_", default_calling_convention="c") foreign lib { diff --git a/vendor/openexr/exr_decode.odin b/vendor/openexr/exr_decode.odin index 7eca819f7..97495d407 100644 --- a/vendor/openexr/exr_decode.odin +++ b/vendor/openexr/exr_decode.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" diff --git a/vendor/openexr/exr_encode.odin b/vendor/openexr/exr_encode.odin index 402aaba81..feedcfc4b 100644 --- a/vendor/openexr/exr_encode.odin +++ b/vendor/openexr/exr_encode.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" diff --git a/vendor/openexr/exr_errors.odin b/vendor/openexr/exr_errors.odin index cf2194756..882171f00 100644 --- a/vendor/openexr/exr_errors.odin +++ b/vendor/openexr/exr_errors.odin @@ -1,12 +1,13 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" #assert(size_of(c.int) == size_of(i32)) /** Error codes that may be returned by various functions. */ -error_code_t :: enum i32 { +/** Return type for all functions. */ +result_t :: enum i32 { SUCCESS = 0, OUT_OF_MEMORY, MISSING_CONTEXT_ARG, @@ -42,8 +43,7 @@ error_code_t :: enum i32 { UNKNOWN, } -/** Return type for all functions. */ -result_t :: error_code_t +error_code_t :: result_t @(link_prefix="exr_", default_calling_convention="c") diff --git a/vendor/openexr/exr_part.odin b/vendor/openexr/exr_part.odin index 24e1eb081..79ebad604 100644 --- a/vendor/openexr/exr_part.odin +++ b/vendor/openexr/exr_part.odin @@ -1,6 +1,6 @@ package vendor_openexr -foreign import lib "exr.lib" +foreign import lib "OpenEXRCore-3_1.lib" import "core:c" From 971d498e799bfeca5e7b074379feb6d933ef59cb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 May 2022 14:21:24 +0100 Subject: [PATCH 159/245] Change path --- vendor/{openexr => OpenEXRCore}/OpenEXRCore-3_1.lib | Bin vendor/{openexr => OpenEXRCore}/exr_attr.odin | 0 vendor/{openexr => OpenEXRCore}/exr_base.odin | 0 vendor/{openexr => OpenEXRCore}/exr_chunkio.odin | 0 vendor/{openexr => OpenEXRCore}/exr_coding.odin | 0 vendor/{openexr => OpenEXRCore}/exr_context.odin | 0 vendor/{openexr => OpenEXRCore}/exr_debug.odin | 0 vendor/{openexr => OpenEXRCore}/exr_decode.odin | 0 vendor/{openexr => OpenEXRCore}/exr_encode.odin | 0 vendor/{openexr => OpenEXRCore}/exr_errors.odin | 0 vendor/{openexr => OpenEXRCore}/exr_part.odin | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename vendor/{openexr => OpenEXRCore}/OpenEXRCore-3_1.lib (100%) rename vendor/{openexr => OpenEXRCore}/exr_attr.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_base.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_chunkio.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_coding.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_context.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_debug.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_decode.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_encode.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_errors.odin (100%) rename vendor/{openexr => OpenEXRCore}/exr_part.odin (100%) diff --git a/vendor/openexr/OpenEXRCore-3_1.lib b/vendor/OpenEXRCore/OpenEXRCore-3_1.lib similarity index 100% rename from vendor/openexr/OpenEXRCore-3_1.lib rename to vendor/OpenEXRCore/OpenEXRCore-3_1.lib diff --git a/vendor/openexr/exr_attr.odin b/vendor/OpenEXRCore/exr_attr.odin similarity index 100% rename from vendor/openexr/exr_attr.odin rename to vendor/OpenEXRCore/exr_attr.odin diff --git a/vendor/openexr/exr_base.odin b/vendor/OpenEXRCore/exr_base.odin similarity index 100% rename from vendor/openexr/exr_base.odin rename to vendor/OpenEXRCore/exr_base.odin diff --git a/vendor/openexr/exr_chunkio.odin b/vendor/OpenEXRCore/exr_chunkio.odin similarity index 100% rename from vendor/openexr/exr_chunkio.odin rename to vendor/OpenEXRCore/exr_chunkio.odin diff --git a/vendor/openexr/exr_coding.odin b/vendor/OpenEXRCore/exr_coding.odin similarity index 100% rename from vendor/openexr/exr_coding.odin rename to vendor/OpenEXRCore/exr_coding.odin diff --git a/vendor/openexr/exr_context.odin b/vendor/OpenEXRCore/exr_context.odin similarity index 100% rename from vendor/openexr/exr_context.odin rename to vendor/OpenEXRCore/exr_context.odin diff --git a/vendor/openexr/exr_debug.odin b/vendor/OpenEXRCore/exr_debug.odin similarity index 100% rename from vendor/openexr/exr_debug.odin rename to vendor/OpenEXRCore/exr_debug.odin diff --git a/vendor/openexr/exr_decode.odin b/vendor/OpenEXRCore/exr_decode.odin similarity index 100% rename from vendor/openexr/exr_decode.odin rename to vendor/OpenEXRCore/exr_decode.odin diff --git a/vendor/openexr/exr_encode.odin b/vendor/OpenEXRCore/exr_encode.odin similarity index 100% rename from vendor/openexr/exr_encode.odin rename to vendor/OpenEXRCore/exr_encode.odin diff --git a/vendor/openexr/exr_errors.odin b/vendor/OpenEXRCore/exr_errors.odin similarity index 100% rename from vendor/openexr/exr_errors.odin rename to vendor/OpenEXRCore/exr_errors.odin diff --git a/vendor/openexr/exr_part.odin b/vendor/OpenEXRCore/exr_part.odin similarity index 100% rename from vendor/openexr/exr_part.odin rename to vendor/OpenEXRCore/exr_part.odin From 89c2e1a5fae48edea399e92fed2572ca3733b0a8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 May 2022 14:22:25 +0100 Subject: [PATCH 160/245] Add `vendor:OpenEXRCore` to `examples/all` --- examples/all/all_vendor.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/all/all_vendor.odin b/examples/all/all_vendor.odin index f83e906a2..e4603a84f 100644 --- a/examples/all/all_vendor.odin +++ b/examples/all/all_vendor.odin @@ -8,6 +8,7 @@ import microui "vendor:microui" import miniaudio "vendor:miniaudio" import PM "vendor:portmidi" import rl "vendor:raylib" +import exr "vendor:OpenEXRCore" import SDL "vendor:sdl2" import SDLNet "vendor:sdl2/net" @@ -29,6 +30,7 @@ _ :: microui _ :: miniaudio _ :: PM _ :: rl +_ :: exr _ :: SDL _ :: SDLNet _ :: IMG From 1146604344810fd6cb7c1121fc2e30bd7873d583 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 3 May 2022 14:52:09 +0100 Subject: [PATCH 161/245] Add LICENSE.md --- vendor/OpenEXRCore/LICENSE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 vendor/OpenEXRCore/LICENSE.md diff --git a/vendor/OpenEXRCore/LICENSE.md b/vendor/OpenEXRCore/LICENSE.md new file mode 100644 index 000000000..32e8c226a --- /dev/null +++ b/vendor/OpenEXRCore/LICENSE.md @@ -0,0 +1,11 @@ +Copyright (c) Contributors to the OpenEXR Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file From dc323cfa1d935e6b5e9d8bf04fb8597fc8b66bce Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 4 May 2022 13:29:52 +0200 Subject: [PATCH 162/245] Small fix to deprecation warning. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 2633f8e55..a907324b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -835,7 +835,7 @@ bool parse_build_flags(Array args) { } name = substring(name, 0, end); if (have_equals && name != "opt") { - gb_printf_err("`flag=value` has been deprecated and will be removed next release. Use `%.*s:` instead.\n", LIT(name), LIT(name)); + gb_printf_err("`flag=value` has been deprecated and will be removed next release. Use `%.*s:` instead.\n", LIT(name)); } String param = {}; From cec049b7d3eabf2ed371f59214023002ae705cdd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 16:04:26 +0100 Subject: [PATCH 163/245] Make the link order of foreign imports deterministic --- src/llvm_backend.cpp | 57 ++-- src/llvm_backend.hpp | 5 +- src/llvm_backend_general.cpp | 7 +- src/main.cpp | 592 ++++++++++++++++++----------------- src/ptr_set.cpp | 2 +- src/string_set.cpp | 29 ++ 6 files changed, 381 insertions(+), 311 deletions(-) diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 7781997f7..267431551 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -29,29 +29,46 @@ void lb_add_foreign_library_path(lbModule *m, Entity *e) { GB_ASSERT(e->kind == Entity_LibraryName); GB_ASSERT(e->flags & EntityFlag_Used); - for_array(i, e->LibraryName.paths) { - String library_path = e->LibraryName.paths[i]; - if (library_path.len == 0) { - continue; - } + mutex_lock(&m->gen->foreign_mutex); + if (!ptr_set_update(&m->gen->foreign_libraries_set, e)) { + array_add(&m->gen->foreign_libraries, e); + } + mutex_unlock(&m->gen->foreign_mutex); +} - bool ok = true; - for_array(path_index, m->foreign_library_paths) { - String path = m->foreign_library_paths[path_index]; - #if defined(GB_SYSTEM_WINDOWS) - if (str_eq_ignore_case(path, library_path)) { - #else - if (str_eq(path, library_path)) { - #endif - ok = false; - break; - } - } +GB_COMPARE_PROC(foreign_library_cmp) { + int cmp = 0; + Entity *x = *(Entity **)a; + Entity *y = *(Entity **)b; + if (x == y) { + return 0; + } - if (ok) { - array_add(&m->foreign_library_paths, library_path); + if (x->pkg != y->pkg) { + isize order_x = x->pkg ? x->pkg->order : 0; + isize order_y = y->pkg ? y->pkg->order : 0; + cmp = isize_cmp(order_x, order_y); + if (cmp) { + return cmp; } } + if (x->file != y->file) { + String fullpath_x = x->file ? x->file->fullpath : (String{}); + String fullpath_y = y->file ? y->file->fullpath : (String{}); + String file_x = filename_from_path(fullpath_x); + String file_y = filename_from_path(fullpath_y); + + cmp = string_compare(file_x, file_y); + if (cmp) { + return cmp; + } + } + + cmp = u64_cmp(x->order_in_src, y->order_in_src); + if (cmp) { + return cmp; + } + return i32_cmp(x->token.pos.offset, y->token.pos.offset); } void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name) { @@ -1922,4 +1939,6 @@ void lb_generate_code(lbGenerator *gen) { } } } + + gb_sort_array(gen->foreign_libraries.data, gen->foreign_libraries.count, foreign_library_cmp); } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index f2bcfaff6..a460b1a23 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -135,7 +135,6 @@ struct lbModule { u32 nested_type_name_guid; Array procedures_to_generate; - Array foreign_library_paths; lbProcedure *curr_procedure; @@ -162,6 +161,10 @@ struct lbGenerator { PtrMap anonymous_proc_lits; + BlockingMutex foreign_mutex; + PtrSet foreign_libraries_set; + Array foreign_libraries; + std::atomic global_array_index; std::atomic global_generated_index; }; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 1a431a4ac..0866e3687 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -67,9 +67,7 @@ void lb_init_module(lbModule *m, Checker *c) { map_init(&m->equal_procs, a); map_init(&m->hasher_procs, a); array_init(&m->procedures_to_generate, a, 0, 1024); - array_init(&m->foreign_library_paths, a, 0, 1024); array_init(&m->missing_procedures_to_check, a, 0, 16); - map_init(&m->debug_values, a); array_init(&m->debug_incomplete_types, a, 0, 1024); @@ -126,6 +124,11 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) { map_init(&gen->modules_through_ctx, permanent_allocator(), gen->info->packages.entries.count*2); map_init(&gen->anonymous_proc_lits, heap_allocator(), 1024); + + mutex_init(&gen->foreign_mutex); + array_init(&gen->foreign_libraries, heap_allocator(), 0, 1024); + ptr_set_init(&gen->foreign_libraries_set, heap_allocator(), 1024); + if (USE_SEPARATE_MODULES) { for_array(i, gen->info->packages.entries) { AstPackage *pkg = gen->info->packages.entries[i].value; diff --git a/src/main.cpp b/src/main.cpp index a907324b8..af5f5ff76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -164,341 +164,357 @@ i32 linker_stage(lbGenerator *gen) { build_context.keep_object_files = true; } else { #if defined(GB_SYSTEM_WINDOWS) - String section_name = str_lit("msvc-link"); - if (build_context.use_lld) { - section_name = str_lit("lld-link"); - } - timings_start_section(timings, section_name); - - gbString lib_str = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(lib_str)); - - gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); - defer (gb_string_free(link_settings)); - - // Add library search paths. - if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { - String path = {}; - auto add_path = [&](String path) { - if (path[path.len-1] == '\\') { - path.len -= 1; - } - link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); - }; - add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); - add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); - add_path(build_context.build_paths[BuildPath_VS_LIB].basename); - } + bool is_windows = true; + #else + bool is_windows = false; + #endif + #if defined(GB_SYSTEM_OSX) + bool is_osx = true; + #else + bool is_osx = false; + #endif - StringSet libs = {}; - string_set_init(&libs, heap_allocator(), 64); - defer (string_set_destroy(&libs)); + if (is_windows) { + String section_name = str_lit("msvc-link"); + if (build_context.use_lld) { + section_name = str_lit("lld-link"); + } + timings_start_section(timings, section_name); - StringSet asm_files = {}; - string_set_init(&asm_files, heap_allocator(), 64); - defer (string_set_destroy(&asm_files)); + gbString lib_str = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(lib_str)); - for_array(j, gen->modules.entries) { - lbModule *m = gen->modules.entries[j].value; - for_array(i, m->foreign_library_paths) { - String lib = m->foreign_library_paths[i]; - if (has_asm_extension(lib)) { - string_set_add(&asm_files, lib); - } else { - string_set_add(&libs, lib); + gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); + defer (gb_string_free(link_settings)); + + // Add library search paths. + if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { + String path = {}; + auto add_path = [&](String path) { + if (path[path.len-1] == '\\') { + path.len -= 1; + } + link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); + }; + add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); + add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); + add_path(build_context.build_paths[BuildPath_VS_LIB].basename); + } + + + StringSet libs = {}; + string_set_init(&libs, heap_allocator(), 64); + defer (string_set_destroy(&libs)); + + StringSet asm_files = {}; + string_set_init(&asm_files, heap_allocator(), 64); + defer (string_set_destroy(&asm_files)); + + for_array(j, gen->foreign_libraries) { + Entity *e = gen->foreign_libraries[j]; + GB_ASSERT(e->kind == Entity_LibraryName); + for_array(i, e->LibraryName.paths) { + String lib = string_trim_whitespace(e->LibraryName.paths[i]); + if (lib.len == 0) { + continue; + } + // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because + // we will never uses these strings afterwards + string_to_lower(&lib); + if (has_asm_extension(lib)) { + if (!string_set_update(&asm_files, lib)) { + String asm_file = asm_files.entries[i].value; + String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); + + result = system_exec_command_line_app("nasm", + "\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" " + "-f win64 " + "-o \"%.*s\" " + "%.*s " + "", + LIT(build_context.ODIN_ROOT), LIT(asm_file), + LIT(obj_file), + LIT(build_context.extra_assembler_flags) + ); + + if (result) { + return result; + } + array_add(&gen->output_object_paths, obj_file); + } + } else { + if (!string_set_update(&libs, lib)) { + lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); + } + } } } - } - for_array(i, gen->default_module.foreign_library_paths) { - String lib = gen->default_module.foreign_library_paths[i]; - if (has_asm_extension(lib)) { - string_set_add(&asm_files, lib); + if (build_context.build_mode == BuildMode_DynamicLibrary) { + link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { - string_set_add(&libs, lib); + link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } - } - for_array(i, libs.entries) { - String lib = libs.entries[i].value; - lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); - } - - - if (build_context.build_mode == BuildMode_DynamicLibrary) { - link_settings = gb_string_append_fmt(link_settings, " /DLL"); - } else { - link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); - } - - if (build_context.pdb_filepath != "") { - String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); - link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); - } - - if (build_context.no_crt) { - link_settings = gb_string_append_fmt(link_settings, " /nodefaultlib"); - } else { - link_settings = gb_string_append_fmt(link_settings, " /defaultlib:libcmt"); - } - - if (build_context.ODIN_DEBUG) { - link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); - } - - for_array(i, asm_files.entries) { - String asm_file = asm_files.entries[i].value; - String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); - - result = system_exec_command_line_app("nasm", - "\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" " - "-f win64 " - "-o \"%.*s\" " - "%.*s " - "", - LIT(build_context.ODIN_ROOT), LIT(asm_file), - LIT(obj_file), - LIT(build_context.extra_assembler_flags) - ); - - if (result) { - return result; + if (build_context.pdb_filepath != "") { + String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); + link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); } - array_add(&gen->output_object_paths, obj_file); - } - gbString object_files = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(object_files)); - for_array(i, gen->output_object_paths) { - String object_path = gen->output_object_paths[i]; - object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); - } + if (build_context.no_crt) { + link_settings = gb_string_append_fmt(link_settings, " /nodefaultlib"); + } else { + link_settings = gb_string_append_fmt(link_settings, " /defaultlib:libcmt"); + } - String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); - defer (gb_free(heap_allocator(), vs_exe_path.text)); + if (build_context.ODIN_DEBUG) { + link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); + } - char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; - if (!build_context.use_lld) { // msvc - if (build_context.has_resource) { - String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); - String res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); - defer (gb_free(heap_allocator(), rc_path.text)); - defer (gb_free(heap_allocator(), res_path.text)); + gbString object_files = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(object_files)); + for_array(i, gen->output_object_paths) { + String object_path = gen->output_object_paths[i]; + object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); + } - result = system_exec_command_line_app("msvc-link", - "\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"", - LIT(res_path), - LIT(rc_path) - ); + String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); + defer (gb_free(heap_allocator(), vs_exe_path.text)); + + char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; + if (!build_context.use_lld) { // msvc + if (build_context.has_resource) { + String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); + String res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); + defer (gb_free(heap_allocator(), rc_path.text)); + defer (gb_free(heap_allocator(), res_path.text)); + + result = system_exec_command_line_app("msvc-link", + "\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"", + LIT(res_path), + LIT(rc_path) + ); + + if (result) { + return result; + } + + result = system_exec_command_line_app("msvc-link", + "\"%.*slink.exe\" %s \"%.*s\" -OUT:\"%.*s\" %s " + "/nologo /incremental:no /opt:ref /subsystem:%s " + " %.*s " + " %.*s " + " %s " + "", + LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), + link_settings, + subsystem_str, + LIT(build_context.link_flags), + LIT(build_context.extra_linker_flags), + lib_str + ); + } else { + result = system_exec_command_line_app("msvc-link", + "\"%.*slink.exe\" %s -OUT:\"%.*s\" %s " + "/nologo /incremental:no /opt:ref /subsystem:%s " + " %.*s " + " %.*s " + " %s " + "", + LIT(vs_exe_path), object_files, LIT(output_filename), + link_settings, + subsystem_str, + LIT(build_context.link_flags), + LIT(build_context.extra_linker_flags), + lib_str + ); + } if (result) { return result; } - result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s \"%.*s\" -OUT:\"%.*s\" %s " + } else { // lld + result = system_exec_command_line_app("msvc-lld-link", + "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), - link_settings, - subsystem_str, - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - lib_str - ); - } else { - result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " - " %.*s " - " %.*s " - " %s " - "", - LIT(vs_exe_path), object_files, LIT(output_filename), + LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str ); - } - if (result) { - return result; - } - - } else { // lld - result = system_exec_command_line_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%s " - " %.*s " - " %.*s " - " %s " - "", - LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), - link_settings, - subsystem_str, - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - lib_str - ); - - if (result) { - return result; - } - } - #else - timings_start_section(timings, str_lit("ld-link")); - - // NOTE(vassvik): get cwd, for used for local shared libs linking, since those have to be relative to the exe - char cwd[256]; - getcwd(&cwd[0], 256); - //printf("%s\n", cwd); - - // NOTE(vassvik): needs to add the root to the library search paths, so that the full filenames of the library - // files can be passed with -l: - gbString lib_str = gb_string_make(heap_allocator(), "-L/"); - defer (gb_string_free(lib_str)); - - for_array(i, gen->default_module.foreign_library_paths) { - String lib = gen->default_module.foreign_library_paths[i]; - - // NOTE(zangent): Sometimes, you have to use -framework on MacOS. - // This allows you to specify '-f' in a #foreign_system_library, - // without having to implement any new syntax specifically for MacOS. - if (build_context.metrics.os == TargetOs_darwin) { - if (string_ends_with(lib, str_lit(".framework"))) { - // framework thingie - String lib_name = lib; - lib_name = remove_extension_from_path(lib_name); - lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name)); - } else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) { - // For: - // object - // dynamic lib - // static libs, absolute full path relative to the file in which the lib was imported from - lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib)); - } else { - // dynamic or static system lib, just link regularly searching system library paths - lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); - } - } else { - // NOTE(vassvik): static libraries (.a files) in linux can be linked to directly using the full path, - // since those are statically linked to at link time. shared libraries (.so) has to be - // available at runtime wherever the executable is run, so we make require those to be - // local to the executable (unless the system collection is used, in which case we search - // the system library paths for the library file). - if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o"))) { - // static libs and object files, absolute full path relative to the file in which the lib was imported from - lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib)); - } else if (string_ends_with(lib, str_lit(".so"))) { - // dynamic lib, relative path to executable - // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible - // at runtime to the executable - lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); - } else { - // dynamic or static system lib, just link regularly searching system library paths - lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); + if (result) { + return result; } } - } - - gbString object_files = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(object_files)); - for_array(i, gen->output_object_paths) { - String object_path = gen->output_object_paths[i]; - object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); - } - - gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); - - if (build_context.no_crt) { - link_settings = gb_string_append_fmt(link_settings, "-nostdlib "); - } - - // NOTE(dweiler): We use clang as a frontend for the linker as there are - // other runtime and compiler support libraries that need to be linked in - // very specific orders such as libgcc_s, ld-linux-so, unwind, etc. - // These are not always typically inside /lib, /lib64, or /usr versions - // of that, e.g libgcc.a is in /usr/lib/gcc/{version}, and can vary on - // the distribution of Linux even. The gcc or clang specs is the only - // reliable way to query this information to call ld directly. - if (build_context.build_mode == BuildMode_DynamicLibrary) { - // NOTE(dweiler): Let the frontend know we're building a shared library - // so it doesn't generate symbols which cannot be relocated. - link_settings = gb_string_appendc(link_settings, "-shared "); - - // NOTE(dweiler): _odin_entry_point must be called at initialization - // time of the shared object, similarly, _odin_exit_point must be called - // at deinitialization. We can pass both -init and -fini to the linker by - // using a comma separated list of arguments to -Wl. - // - // This previously used ld but ld cannot actually build a shared library - // correctly this way since all the other dependencies provided implicitly - // by the compiler frontend are still needed and most of the command - // line arguments prepared previously are incompatible with ld. - link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); - link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); - } else if (build_context.metrics.os != TargetOs_openbsd) { - // OpenBSD defaults to PIE executable. do not pass -no-pie for it. - link_settings = gb_string_appendc(link_settings, "-no-pie "); - } - - gbString platform_lib_str = gb_string_make(heap_allocator(), ""); - defer (gb_string_free(platform_lib_str)); - if (build_context.metrics.os == TargetOs_darwin) { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem -lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); } else { - platform_lib_str = gb_string_appendc(platform_lib_str, "-lc -lm"); - } + timings_start_section(timings, str_lit("ld-link")); - if (build_context.metrics.os == TargetOs_darwin) { - // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. - // NOTE: If you change this (although this minimum is as low as you can go with Odin working) - // make sure to also change the 'mtriple' param passed to 'opt' - if (build_context.metrics.arch == TargetArch_arm64) { - link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0 "); - } else { - link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.8.0 "); + // NOTE(vassvik): get cwd, for used for local shared libs linking, since those have to be relative to the exe + char cwd[256]; + #if !defined(GB_SYSTEM_WINDOWS) + getcwd(&cwd[0], 256); + #endif + //printf("%s\n", cwd); + + // NOTE(vassvik): needs to add the root to the library search paths, so that the full filenames of the library + // files can be passed with -l: + gbString lib_str = gb_string_make(heap_allocator(), "-L/"); + defer (gb_string_free(lib_str)); + + StringSet libs = {}; + string_set_init(&libs, heap_allocator(), 64); + defer (string_set_destroy(&libs)); + + for_array(j, gen->foreign_libraries) { + Entity *e = gen->foreign_libraries[j]; + GB_ASSERT(e->kind == Entity_LibraryName); + for_array(i, e->LibraryName.paths) { + String lib = e->LibraryName.paths[i]; + if (string_set_update(&libs, lib)) { + continue; + } + lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); + + // NOTE(zangent): Sometimes, you have to use -framework on MacOS. + // This allows you to specify '-f' in a #foreign_system_library, + // without having to implement any new syntax specifically for MacOS. + if (build_context.metrics.os == TargetOs_darwin) { + if (string_ends_with(lib, str_lit(".framework"))) { + // framework thingie + String lib_name = lib; + lib_name = remove_extension_from_path(lib_name); + lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", LIT(lib_name)); + } else if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o")) || string_ends_with(lib, str_lit(".dylib"))) { + // For: + // object + // dynamic lib + // static libs, absolute full path relative to the file in which the lib was imported from + lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib)); + } else { + // dynamic or static system lib, just link regularly searching system library paths + lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); + } + } else { + // NOTE(vassvik): static libraries (.a files) in linux can be linked to directly using the full path, + // since those are statically linked to at link time. shared libraries (.so) has to be + // available at runtime wherever the executable is run, so we make require those to be + // local to the executable (unless the system collection is used, in which case we search + // the system library paths for the library file). + if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o"))) { + // static libs and object files, absolute full path relative to the file in which the lib was imported from + lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib)); + } else if (string_ends_with(lib, str_lit(".so"))) { + // dynamic lib, relative path to executable + // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible + // at runtime to the executable + lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); + } else { + // dynamic or static system lib, just link regularly searching system library paths + lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); + } + } + } } - // This points the linker to where the entry point is - link_settings = gb_string_appendc(link_settings, " -e _main "); - } - gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); - defer (gb_string_free(link_command_line)); - link_command_line = gb_string_appendc(link_command_line, object_files); - link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); - link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); - link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.extra_linker_flags)); - link_command_line = gb_string_append_fmt(link_command_line, " %s ", link_settings); + gbString object_files = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(object_files)); + for_array(i, gen->output_object_paths) { + String object_path = gen->output_object_paths[i]; + object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); + } - result = system_exec_command_line_app("ld-link", link_command_line); + gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); - if (result) { - return result; - } + if (build_context.no_crt) { + link_settings = gb_string_append_fmt(link_settings, "-nostdlib "); + } - #if defined(GB_SYSTEM_OSX) - if (build_context.ODIN_DEBUG) { - // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe - // to the symbols in the object file - result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); + // NOTE(dweiler): We use clang as a frontend for the linker as there are + // other runtime and compiler support libraries that need to be linked in + // very specific orders such as libgcc_s, ld-linux-so, unwind, etc. + // These are not always typically inside /lib, /lib64, or /usr versions + // of that, e.g libgcc.a is in /usr/lib/gcc/{version}, and can vary on + // the distribution of Linux even. The gcc or clang specs is the only + // reliable way to query this information to call ld directly. + if (build_context.build_mode == BuildMode_DynamicLibrary) { + // NOTE(dweiler): Let the frontend know we're building a shared library + // so it doesn't generate symbols which cannot be relocated. + link_settings = gb_string_appendc(link_settings, "-shared "); + + // NOTE(dweiler): _odin_entry_point must be called at initialization + // time of the shared object, similarly, _odin_exit_point must be called + // at deinitialization. We can pass both -init and -fini to the linker by + // using a comma separated list of arguments to -Wl. + // + // This previously used ld but ld cannot actually build a shared library + // correctly this way since all the other dependencies provided implicitly + // by the compiler frontend are still needed and most of the command + // line arguments prepared previously are incompatible with ld. + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); + link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); + } else if (build_context.metrics.os != TargetOs_openbsd) { + // OpenBSD defaults to PIE executable. do not pass -no-pie for it. + link_settings = gb_string_appendc(link_settings, "-no-pie "); + } + + gbString platform_lib_str = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(platform_lib_str)); + if (build_context.metrics.os == TargetOs_darwin) { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem -lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); + } else { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lc -lm"); + } + + if (build_context.metrics.os == TargetOs_darwin) { + // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. + // NOTE: If you change this (although this minimum is as low as you can go with Odin working) + // make sure to also change the 'mtriple' param passed to 'opt' + if (build_context.metrics.arch == TargetArch_arm64) { + link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0 "); + } else { + link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.8.0 "); + } + // This points the linker to where the entry point is + link_settings = gb_string_appendc(link_settings, " -e _main "); + } + + gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); + defer (gb_string_free(link_command_line)); + + link_command_line = gb_string_appendc(link_command_line, object_files); + link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); + link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); + link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.extra_linker_flags)); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", link_settings); + + result = system_exec_command_line_app("ld-link", link_command_line); if (result) { return result; } - } - #endif - #endif + if (is_osx && build_context.ODIN_DEBUG) { + // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe + // to the symbols in the object file + result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); + + if (result) { + return result; + } + } + } } return result; diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index b45997916..ffe48d69a 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -13,7 +13,7 @@ struct PtrSet { template void ptr_set_init (PtrSet *s, gbAllocator a, isize capacity = 16); template void ptr_set_destroy(PtrSet *s); template T ptr_set_add (PtrSet *s, T ptr); -template bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existsed +template bool ptr_set_update (PtrSet *s, T ptr); // returns true if it previously existed template bool ptr_set_exists (PtrSet *s, T ptr); template void ptr_set_remove (PtrSet *s, T ptr); template void ptr_set_clear (PtrSet *s); diff --git a/src/string_set.cpp b/src/string_set.cpp index e27145289..746ad9529 100644 --- a/src/string_set.cpp +++ b/src/string_set.cpp @@ -13,6 +13,7 @@ struct StringSet { void string_set_init (StringSet *s, gbAllocator a, isize capacity = 16); void string_set_destroy(StringSet *s); void string_set_add (StringSet *s, String const &str); +bool string_set_update (StringSet *s, String const &str); // returns true if it previously existed bool string_set_exists (StringSet *s, String const &str); void string_set_remove (StringSet *s, String const &str); void string_set_clear (StringSet *s); @@ -149,6 +150,34 @@ void string_set_add(StringSet *s, String const &str) { } } +bool string_set_update(StringSet *s, String const &str) { + bool exists = false; + MapIndex index; + MapFindResult fr; + StringHashKey key = string_hash_string(str); + if (s->hashes.count == 0) { + string_set_grow(s); + } + fr = string_set__find(s, key); + if (fr.entry_index != MAP_SENTINEL) { + index = fr.entry_index; + exists = true; + } else { + index = string_set__add_entry(s, key); + if (fr.entry_prev != MAP_SENTINEL) { + s->entries[fr.entry_prev].next = index; + } else { + s->hashes[fr.hash_index] = index; + } + } + s->entries[index].value = str; + + if (string_set__full(s)) { + string_set_grow(s); + } + return exists; +} + void string_set__erase(StringSet *s, MapFindResult fr) { MapFindResult last; From 982a1aebb3dc67447c30b4cf7f4ab1a5dac9af7e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 16:14:42 +0100 Subject: [PATCH 164/245] Remove stray line --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index af5f5ff76..fc3de96bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -382,7 +382,6 @@ i32 linker_stage(lbGenerator *gen) { if (string_set_update(&libs, lib)) { continue; } - lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); // NOTE(zangent): Sometimes, you have to use -framework on MacOS. // This allows you to specify '-f' in a #foreign_system_library, From 9f95d6fa6568b83072a8fbe49846390c014a00a1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 16:17:24 +0100 Subject: [PATCH 165/245] Minor move around for path sets --- src/main.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fc3de96bb..07d6f6165 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -216,12 +216,13 @@ i32 linker_stage(lbGenerator *gen) { GB_ASSERT(e->kind == Entity_LibraryName); for_array(i, e->LibraryName.paths) { String lib = string_trim_whitespace(e->LibraryName.paths[i]); - if (lib.len == 0) { - continue; - } // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because // we will never uses these strings afterwards string_to_lower(&lib); + if (lib.len == 0) { + continue; + } + if (has_asm_extension(lib)) { if (!string_set_update(&asm_files, lib)) { String asm_file = asm_files.entries[i].value; @@ -378,7 +379,10 @@ i32 linker_stage(lbGenerator *gen) { Entity *e = gen->foreign_libraries[j]; GB_ASSERT(e->kind == Entity_LibraryName); for_array(i, e->LibraryName.paths) { - String lib = e->LibraryName.paths[i]; + String lib = string_trim_whitespace(e->LibraryName.paths[i]); + if (lib.len == 0) { + continue; + } if (string_set_update(&libs, lib)) { continue; } From e4743b15b15ea5f1b2611bbc1718274ebb03bf03 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 16:40:12 +0100 Subject: [PATCH 166/245] Add `@(priority_index=)` for `foreign import` --- src/checker.cpp | 11 +++++++++++ src/checker.hpp | 1 + src/entity.cpp | 1 + src/llvm_backend.cpp | 7 +++++++ 4 files changed, 20 insertions(+) diff --git a/src/checker.cpp b/src/checker.cpp index 1e33c6e9d..fdd75126f 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4414,6 +4414,14 @@ DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { } ac->require_declaration = true; return true; + } else if (name == "priority_index") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind != ExactValue_Integer) { + error(elem, "Expected an integer value for '%.*s'", LIT(name)); + } else { + ac->foreign_import_priority_index = exact_value_to_i64(ev); + } + return true; } return false; } @@ -4470,6 +4478,9 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } + if (ac.foreign_import_priority_index != 0) { + e->LibraryName.priority_index = ac.foreign_import_priority_index; + } if (has_asm_extension(fullpath)) { if (build_context.metrics.arch != TargetArch_amd64 || diff --git a/src/checker.hpp b/src/checker.hpp index 552e6aca7..1c9ffd8c7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -118,6 +118,7 @@ struct AttributeContext { bool init : 1; bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode + i64 foreign_import_priority_index; String objc_class; String objc_name; diff --git a/src/entity.cpp b/src/entity.cpp index 1f87f7af6..904a630fb 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -252,6 +252,7 @@ struct Entity { struct { Slice paths; String name; + i64 priority_index; } LibraryName; i32 Nil; struct { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 267431551..7cf588853 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -43,6 +43,13 @@ GB_COMPARE_PROC(foreign_library_cmp) { if (x == y) { return 0; } + GB_ASSERT(x->kind == Entity_LibraryName); + GB_ASSERT(y->kind == Entity_LibraryName); + + cmp = i64_cmp(x->LibraryName.priority_index, y->LibraryName.priority_index); + if (cmp) { + return cmp; + } if (x->pkg != y->pkg) { isize order_x = x->pkg ? x->pkg->order : 0; From 5931e2383b30ecf7f76bd435b818c977f145b498 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 16:58:40 +0100 Subject: [PATCH 167/245] Remove unneeded `#if defined` --- src/main.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 07d6f6165..561fa0fca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2863,11 +2863,7 @@ int main(int arg_count, char const **arg_ptr) { String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); defer (gb_free(heap_allocator(), exe_name.text)); - #if defined(GB_SYSTEM_WINDOWS) - return system_exec_command_line_app("odin run", "%.*s %.*s", LIT(exe_name), LIT(run_args_string)); - #else return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string)); - #endif } return 0; } From 0cf37bde8b9d21cb2f7392dab5a91000b89fa6ae Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 4 May 2022 17:51:36 +0100 Subject: [PATCH 168/245] Update foreign import for OpenEXRCore for non-windows platforms --- vendor/OpenEXRCore/exr_base.odin | 6 +++++- vendor/OpenEXRCore/exr_chunkio.odin | 6 +++++- vendor/OpenEXRCore/exr_context.odin | 6 +++++- vendor/OpenEXRCore/exr_debug.odin | 6 +++++- vendor/OpenEXRCore/exr_decode.odin | 6 +++++- vendor/OpenEXRCore/exr_encode.odin | 6 +++++- vendor/OpenEXRCore/exr_errors.odin | 7 ++++++- vendor/OpenEXRCore/exr_part.odin | 6 +++++- 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/vendor/OpenEXRCore/exr_base.odin b/vendor/OpenEXRCore/exr_base.odin index 3301af08b..3c71f6285 100644 --- a/vendor/OpenEXRCore/exr_base.odin +++ b/vendor/OpenEXRCore/exr_base.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" diff --git a/vendor/OpenEXRCore/exr_chunkio.odin b/vendor/OpenEXRCore/exr_chunkio.odin index 9ce9d0914..e5fae15f5 100644 --- a/vendor/OpenEXRCore/exr_chunkio.odin +++ b/vendor/OpenEXRCore/exr_chunkio.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" diff --git a/vendor/OpenEXRCore/exr_context.odin b/vendor/OpenEXRCore/exr_context.odin index b74986183..4b70950b3 100644 --- a/vendor/OpenEXRCore/exr_context.odin +++ b/vendor/OpenEXRCore/exr_context.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" diff --git a/vendor/OpenEXRCore/exr_debug.odin b/vendor/OpenEXRCore/exr_debug.odin index 9b66106d8..e376e9ddd 100644 --- a/vendor/OpenEXRCore/exr_debug.odin +++ b/vendor/OpenEXRCore/exr_debug.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} @(link_prefix="exr_", default_calling_convention="c") foreign lib { diff --git a/vendor/OpenEXRCore/exr_decode.odin b/vendor/OpenEXRCore/exr_decode.odin index 97495d407..2065ee44d 100644 --- a/vendor/OpenEXRCore/exr_decode.odin +++ b/vendor/OpenEXRCore/exr_decode.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" diff --git a/vendor/OpenEXRCore/exr_encode.odin b/vendor/OpenEXRCore/exr_encode.odin index feedcfc4b..9d9e80c22 100644 --- a/vendor/OpenEXRCore/exr_encode.odin +++ b/vendor/OpenEXRCore/exr_encode.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" diff --git a/vendor/OpenEXRCore/exr_errors.odin b/vendor/OpenEXRCore/exr_errors.odin index 882171f00..092b888dc 100644 --- a/vendor/OpenEXRCore/exr_errors.odin +++ b/vendor/OpenEXRCore/exr_errors.odin @@ -1,8 +1,13 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" + #assert(size_of(c.int) == size_of(i32)) /** Error codes that may be returned by various functions. */ diff --git a/vendor/OpenEXRCore/exr_part.odin b/vendor/OpenEXRCore/exr_part.odin index 79ebad604..7d7530e50 100644 --- a/vendor/OpenEXRCore/exr_part.odin +++ b/vendor/OpenEXRCore/exr_part.odin @@ -1,6 +1,10 @@ package vendor_openexr -foreign import lib "OpenEXRCore-3_1.lib" +when ODIN_OS == .Windows { + foreign import lib "OpenEXRCore-3_1.lib" +} else { + foreign import lib "system:OpenEXRCore-3_1" +} import "core:c" From 0e91e63043bd5b49dd81dd0f4e9eb1e29e457b87 Mon Sep 17 00:00:00 2001 From: zhibog Date: Wed, 4 May 2022 22:13:50 +0200 Subject: [PATCH 169/245] Fix issue 1761. Added the test vector to the core and vendor tests --- core/crypto/sha2/sha2.odin | 6 ++++-- tests/core/crypto/test_core_crypto.odin | 4 ++++ tests/vendor/botan/test_vendor_botan.odin | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index 7c7b2da81..9792a4cb8 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -419,8 +419,10 @@ update :: proc(ctx: ^$T, data: []byte) { sha2_transf(ctx, shifted_message, block_nb) rem_len = new_len % CURR_BLOCK_SIZE - when T == Sha256_Context {copy(ctx.block[:], shifted_message[block_nb << 6:rem_len])} - else when T == Sha512_Context {copy(ctx.block[:], shifted_message[block_nb << 7:rem_len])} + if rem_len > 0 { + when T == Sha256_Context {copy(ctx.block[:], shifted_message[block_nb << 6:rem_len])} + else when T == Sha512_Context {copy(ctx.block[:], shifted_message[block_nb << 7:rem_len])} + } ctx.length = rem_len when T == Sha256_Context {ctx.tot_len += (block_nb + 1) << 6} diff --git a/tests/core/crypto/test_core_crypto.odin b/tests/core/crypto/test_core_crypto.odin index 636632d71..f6b4b10b8 100644 --- a/tests/core/crypto/test_core_crypto.odin +++ b/tests/core/crypto/test_core_crypto.odin @@ -14,6 +14,7 @@ package test_core_crypto import "core:testing" import "core:fmt" +import "core:strings" import "core:crypto/md2" import "core:crypto/md4" @@ -230,11 +231,14 @@ test_sha224 :: proc(t: ^testing.T) { // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html + // https://datatracker.ietf.org/doc/html/rfc3874#section-3.3 + data_1_000_000_a := strings.repeat("a", 1_000_000) test_vectors := [?]TestHash { TestHash{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""}, TestHash{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"}, TestHash{"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, TestHash{"c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + TestHash{"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", data_1_000_000_a}, } for v, _ in test_vectors { computed := sha2.hash_224(v.str) diff --git a/tests/vendor/botan/test_vendor_botan.odin b/tests/vendor/botan/test_vendor_botan.odin index f0ff44ac9..0a93723c8 100644 --- a/tests/vendor/botan/test_vendor_botan.odin +++ b/tests/vendor/botan/test_vendor_botan.odin @@ -15,6 +15,7 @@ package test_vendor_botan import "core:testing" import "core:fmt" import "core:os" +import "core:strings" import "vendor:botan/md4" import "vendor:botan/md5" @@ -172,11 +173,14 @@ test_sha224 :: proc(t: ^testing.T) { // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html + // https://datatracker.ietf.org/doc/html/rfc3874#section-3.3 + data_1_000_000_a := strings.repeat("a", 1_000_000) test_vectors := [?]TestHash { TestHash{"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""}, TestHash{"23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "abc"}, TestHash{"75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, TestHash{"c97ca9a559850ce97a04a96def6d99a9e0e0e2ab14e6b8df265fc0b3", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"}, + TestHash{"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", data_1_000_000_a}, } for v, _ in test_vectors { computed := sha2.hash_224(v.str) From fe442d7c0c4767e5412094d47acc176aae3e2834 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 5 May 2022 10:45:15 +0200 Subject: [PATCH 170/245] [mem] Fix Dynamic_Pool. --- core/mem/allocators.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index b8bd9a065..118a7f7e6 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -746,6 +746,8 @@ dynamic_pool_reset :: proc(using pool: ^Dynamic_Pool) { free(a, block_allocator) } clear(&out_band_allocations) + + bytes_left = 0 // Make new allocations call `cycle_new_block` again. } dynamic_pool_free_all :: proc(using pool: ^Dynamic_Pool) { From 5d190b15d7a665ada76ad752e2b41b4e6456c075 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 May 2022 15:30:07 +0100 Subject: [PATCH 171/245] Minor improvements to io and os --- core/io/io.odin | 9 ++------- core/os/os.odin | 4 ++++ core/os/os_darwin.odin | 3 --- core/os/os_freebsd.odin | 3 --- core/os/os_linux.odin | 3 --- core/os/os_openbsd.odin | 4 ---- 6 files changed, 6 insertions(+), 20 deletions(-) diff --git a/core/io/io.odin b/core/io/io.odin index e9d839efb..3ad34d607 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -4,7 +4,6 @@ package io import "core:intrinsics" -import "core:runtime" import "core:unicode/utf8" // Seek whence values @@ -254,11 +253,7 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: return 0, .Empty } - curr_offset: i64 - curr_offset, err = r->impl_seek(offset, .Current) - if err != nil { - return 0, err - } + curr_offset := r->impl_seek(offset, .Current) or_return n, err = r->impl_read(p) _, err1 := r->impl_seek(curr_offset, .Start) @@ -552,7 +547,7 @@ _copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, er } } // NOTE(bill): alloca is fine here - buf = transmute([]byte)runtime.Raw_Slice{intrinsics.alloca(size, 2*align_of(rawptr)), size} + buf = intrinsics.alloca(size, 2*align_of(rawptr))[:size] } for { nr, er := read(src, buf) diff --git a/core/os/os.odin b/core/os/os.odin index e880ec21e..5e71e720e 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -9,6 +9,10 @@ OS :: ODIN_OS ARCH :: ODIN_ARCH ENDIAN :: ODIN_ENDIAN +SEEK_SET :: 0 +SEEK_CUR :: 1 +SEEK_END :: 2 + write_string :: proc(fd: Handle, str: string) -> (int, Errno) { return write(fd, transmute([]byte)str) } diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index ae5336849..21e9e54f4 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -163,9 +163,6 @@ O_SYNC :: 0x0080 O_ASYNC :: 0x0040 O_CLOEXEC :: 0x1000000 -SEEK_SET :: 0 -SEEK_CUR :: 1 -SEEK_END :: 2 SEEK_DATA :: 3 SEEK_HOLE :: 4 SEEK_MAX :: SEEK_HOLE diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 4a95028c1..6545423d4 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -123,9 +123,6 @@ O_ASYNC :: 0x02000 O_CLOEXEC :: 0x80000 -SEEK_SET :: 0 -SEEK_CUR :: 1 -SEEK_END :: 2 SEEK_DATA :: 3 SEEK_HOLE :: 4 SEEK_MAX :: SEEK_HOLE diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index ed73341c0..9b712cecc 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -167,9 +167,6 @@ O_ASYNC :: 0x02000 O_CLOEXEC :: 0x80000 -SEEK_SET :: 0 -SEEK_CUR :: 1 -SEEK_END :: 2 SEEK_DATA :: 3 SEEK_HOLE :: 4 SEEK_MAX :: SEEK_HOLE diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index a99c8fef0..dd230f9b5 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -125,10 +125,6 @@ O_EXCL :: 0x00800 O_NOCTTY :: 0x08000 O_CLOEXEC :: 0x10000 -SEEK_SET :: 0 -SEEK_CUR :: 1 -SEEK_END :: 2 - RTLD_LAZY :: 0x001 RTLD_NOW :: 0x002 RTLD_LOCAL :: 0x000 From 18bde22b2624252b69439aa188c2da92d1ae84ee Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 May 2022 16:15:03 +0100 Subject: [PATCH 172/245] Go to a `File` based approach over `Handle` based --- core/os/os2/env_windows.odin | 40 +++++----- core/os/os2/file.odin | 121 +++++++++++++++-------------- core/os/os2/file_stream.odin | 44 +++++------ core/os/os2/file_util.odin | 54 ++++++------- core/os/os2/file_windows.odin | 53 +++++++------ core/os/os2/pipe.odin | 2 +- core/os/os2/pipe_windows.odin | 6 +- core/os/os2/process.odin | 2 +- core/os/os2/stat.odin | 4 +- core/os/os2/stat_windows.odin | 20 ++--- core/os/os2/temp_file.odin | 2 +- core/os/os2/temp_file_windows.odin | 4 +- 12 files changed, 185 insertions(+), 167 deletions(-) diff --git a/core/os/os2/env_windows.odin b/core/os/os2/env_windows.odin index af04db858..2ce755203 100644 --- a/core/os/os2/env_windows.odin +++ b/core/os/os2/env_windows.odin @@ -1,7 +1,6 @@ //+private package os2 -import "core:mem" import win32 "core:sys/windows" _lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { @@ -9,24 +8,28 @@ _lookup_env :: proc(key: string, allocator := context.allocator) -> (value: stri return } wkey := win32.utf8_to_wstring(key) - b := make([dynamic]u16, 100, context.temp_allocator) - for { - n := win32.GetEnvironmentVariableW(wkey, raw_data(b), u32(len(b))) - if n == 0 { - err := win32.GetLastError() - if err == win32.ERROR_ENVVAR_NOT_FOUND { - return "", false - } - } - if n <= u32(len(b)) { - value = win32.utf16_to_utf8(b[:n], allocator) - found = true - return + n := win32.GetEnvironmentVariableW(wkey, nil, 0) + if n == 0 { + err := win32.GetLastError() + if err == win32.ERROR_ENVVAR_NOT_FOUND { + return "", false } - - resize(&b, len(b)*2) + return "", true } + b := make([]u16, n+1, context.temp_allocator) + + n = win32.GetEnvironmentVariableW(wkey, raw_data(b), u32(len(b))) + if n == 0 { + err := win32.GetLastError() + if err == win32.ERROR_ENVVAR_NOT_FOUND { + return "", false + } + } + + value = win32.utf16_to_utf8(b[:n], allocator) + found = true + return } _set_env :: proc(key, value: string) -> bool { @@ -62,13 +65,12 @@ _environ :: proc(allocator := context.allocator) -> []string { r := make([dynamic]string, 0, 50, allocator) for from, i, p := 0, 0, envs; true; i += 1 { - c := (^u16)(uintptr(p) + uintptr(i*2))^ + c := ([^]u16)(p)[i] if c == 0 { if i <= from { break } - w := mem.slice_ptr(mem.ptr_offset(p, from), i-from) - + w := ([^]u16)(p)[from:i] append(&r, win32.utf16_to_utf8(w, allocator)) from = i + 1 } diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 5b995bd69..463d27c54 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -3,7 +3,9 @@ package os2 import "core:io" import "core:time" -Handle :: distinct uintptr +File :: struct { + impl: _File, +} Seek_From :: enum { Start = 0, // seek relative to the origin of the file @@ -30,74 +32,79 @@ O_TRUNC :: int(64) -stdin: Handle = 0 // OS-Specific -stdout: Handle = 1 // OS-Specific -stderr: Handle = 2 // OS-Specific +stdin: ^File = nil // OS-Specific +stdout: ^File = nil // OS-Specific +stderr: ^File = nil // OS-Specific -create :: proc(name: string) -> (Handle, Error) { +create :: proc(name: string) -> (^File, Error) { return _create(name) } -open :: proc(name: string) -> (Handle, Error) { +open :: proc(name: string) -> (^File, Error) { return _open(name) } -open_file :: proc(name: string, flag: int, perm: File_Mode) -> (Handle, Error) { +open_file :: proc(name: string, flag: int, perm: File_Mode) -> (^File, Error) { return _open_file(name, flag, perm) } -close :: proc(fd: Handle) -> Error { - return _close(fd) -} - -name :: proc(fd: Handle, allocator := context.allocator) -> string { - return _name(fd) -} - -seek :: proc(fd: Handle, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { - return _seek(fd, offset, whence) -} - -read :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) { - return _read(fd, p) -} - -read_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) { - return _read_at(fd, p, offset) -} - -read_from :: proc(fd: Handle, r: io.Reader) -> (n: i64, err: Error) { - return _read_from(fd, r) -} - -write :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) { - return _write(fd, p) -} - -write_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) { - return _write_at(fd, p, offset) -} - -write_to :: proc(fd: Handle, w: io.Writer) -> (n: i64, err: Error) { - return _write_to(fd, w) -} - -file_size :: proc(fd: Handle) -> (n: i64, err: Error) { - return _file_size(fd) +new_file :: proc(handle: uintptr, name: string) -> ^File { + return _new_file(handle, name) } -sync :: proc(fd: Handle) -> Error { - return _sync(fd) +close :: proc(f: ^File) -> Error { + return _close(f) } -flush :: proc(fd: Handle) -> Error { - return _flush(fd) +name :: proc(f: ^File, allocator := context.allocator) -> string { + return _name(f) } -truncate :: proc(fd: Handle, size: i64) -> Maybe(Path_Error) { - return _truncate(fd, size) +seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { + return _seek(f, offset, whence) +} + +read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { + return _read(f, p) +} + +read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { + return _read_at(f, p, offset) +} + +read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { + return _read_from(f, r) +} + +write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { + return _write(f, p) +} + +write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { + return _write_at(f, p, offset) +} + +write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { + return _write_to(f, w) +} + +file_size :: proc(f: ^File) -> (n: i64, err: Error) { + return _file_size(f) +} + + +sync :: proc(f: ^File) -> Error { + return _sync(f) +} + +flush :: proc(f: ^File) -> Error { + return _flush(f) +} + +truncate :: proc(f: ^File, size: i64) -> Maybe(Path_Error) { + return _truncate(f, size) } remove :: proc(name: string) -> Maybe(Path_Error) { @@ -122,16 +129,16 @@ read_link :: proc(name: string) -> (string, Maybe(Path_Error)) { } -chdir :: proc(fd: Handle) -> Error { - return _chdir(fd) +chdir :: proc(f: ^File) -> Error { + return _chdir(f) } -chmod :: proc(fd: Handle, mode: File_Mode) -> Error { - return _chmod(fd, mode) +chmod :: proc(f: ^File, mode: File_Mode) -> Error { + return _chmod(f, mode) } -chown :: proc(fd: Handle, uid, gid: int) -> Error { - return _chown(fd, uid, gid) +chown :: proc(f: ^File, uid, gid: int) -> Error { + return _chown(f, uid, gid) } diff --git a/core/os/os2/file_stream.odin b/core/os/os2/file_stream.odin index 0962ed59c..7b68d0e21 100644 --- a/core/os/os2/file_stream.odin +++ b/core/os/os2/file_stream.odin @@ -2,8 +2,8 @@ package os2 import "core:io" -file_to_stream :: proc(fd: Handle) -> (s: io.Stream) { - s.stream_data = rawptr(uintptr(fd)) +file_to_stream :: proc(f: ^File) -> (s: io.Stream) { + s.stream_data = f s.stream_vtable = _file_stream_vtable return } @@ -20,66 +20,66 @@ error_to_io_error :: proc(ferr: Error) -> io.Error { @(private) _file_stream_vtable := &io.Stream_VTable{ impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = read(fd, p) + n, ferr = read(f, p) err = error_to_io_error(ferr) return }, impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = read_at(fd, p, offset) + n, ferr = read_at(f, p, offset) err = error_to_io_error(ferr) return }, impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = write_to(fd, w) + n, ferr = write_to(f, w) err = error_to_io_error(ferr) return }, impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = write(fd, p) + n, ferr = write(f, p) err = error_to_io_error(ferr) return }, impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = write_at(fd, p, offset) + n, ferr = write_at(f, p, offset) err = error_to_io_error(ferr) return }, impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) { - fd := Handle(uintptr(s.stream_data)) + f := (^File)(s.stream_data) ferr: Error - n, ferr = read_from(fd, r) + n, ferr = read_from(f, r) err = error_to_io_error(ferr) return }, impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { - fd := Handle(uintptr(s.stream_data)) - n, ferr := seek(fd, offset, Seek_From(whence)) + f := (^File)(s.stream_data) + n, ferr := seek(f, offset, Seek_From(whence)) err := error_to_io_error(ferr) return n, err }, impl_size = proc(s: io.Stream) -> i64 { - fd := Handle(uintptr(s.stream_data)) - sz, _ := file_size(fd) + f := (^File)(s.stream_data) + sz, _ := file_size(f) return sz }, impl_flush = proc(s: io.Stream) -> io.Error { - fd := Handle(uintptr(s.stream_data)) - ferr := flush(fd) + f := (^File)(s.stream_data) + ferr := flush(f) return error_to_io_error(ferr) }, impl_close = proc(s: io.Stream) -> io.Error { - fd := Handle(uintptr(s.stream_data)) - ferr := close(fd) + f := (^File)(s.stream_data) + ferr := close(f) return error_to_io_error(ferr) }, } diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin index 77f6545ac..5ff4a6b99 100644 --- a/core/os/os2/file_util.odin +++ b/core/os/os2/file_util.odin @@ -4,25 +4,25 @@ import "core:mem" import "core:strconv" import "core:unicode/utf8" -write_string :: proc(fd: Handle, s: string) -> (n: int, err: Error) { - return write(fd, transmute([]byte)s) +write_string :: proc(f: ^File, s: string) -> (n: int, err: Error) { + return write(f, transmute([]byte)s) } -write_byte :: proc(fd: Handle, b: byte) -> (n: int, err: Error) { - return write(fd, []byte{b}) +write_byte :: proc(f: ^File, b: byte) -> (n: int, err: Error) { + return write(f, []byte{b}) } -write_rune :: proc(fd: Handle, r: rune) -> (n: int, err: Error) { +write_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { if r < utf8.RUNE_SELF { - return write_byte(fd, byte(r)) + return write_byte(f, byte(r)) } b: [4]byte b, n = utf8.encode_rune(r) - return write(fd, b[:n]) + return write(f, b[:n]) } -write_encoded_rune :: proc(fd: Handle, r: rune) -> (n: int, err: Error) { +write_encoded_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { wrap :: proc(m: int, merr: Error, n: ^int, err: ^Error) -> bool { n^ += m if merr != nil { @@ -32,44 +32,44 @@ write_encoded_rune :: proc(fd: Handle, r: rune) -> (n: int, err: Error) { return false } - if wrap(write_byte(fd, '\''), &n, &err) { return } + if wrap(write_byte(f, '\''), &n, &err) { return } switch r { - case '\a': if wrap(write_string(fd, "\\a"), &n, &err) { return } - case '\b': if wrap(write_string(fd, "\\b"), &n, &err) { return } - case '\e': if wrap(write_string(fd, "\\e"), &n, &err) { return } - case '\f': if wrap(write_string(fd, "\\f"), &n, &err) { return } - case '\n': if wrap(write_string(fd, "\\n"), &n, &err) { return } - case '\r': if wrap(write_string(fd, "\\r"), &n, &err) { return } - case '\t': if wrap(write_string(fd, "\\t"), &n, &err) { return } - case '\v': if wrap(write_string(fd, "\\v"), &n, &err) { return } + case '\a': if wrap(write_string(f, "\\a"), &n, &err) { return } + case '\b': if wrap(write_string(f, "\\b"), &n, &err) { return } + case '\e': if wrap(write_string(f, "\\e"), &n, &err) { return } + case '\f': if wrap(write_string(f, "\\f"), &n, &err) { return } + case '\n': if wrap(write_string(f, "\\n"), &n, &err) { return } + case '\r': if wrap(write_string(f, "\\r"), &n, &err) { return } + case '\t': if wrap(write_string(f, "\\t"), &n, &err) { return } + case '\v': if wrap(write_string(f, "\\v"), &n, &err) { return } case: if r < 32 { - if wrap(write_string(fd, "\\x"), &n, &err) { return } + if wrap(write_string(f, "\\x"), &n, &err) { return } b: [2]byte s := strconv.append_bits(b[:], u64(r), 16, true, 64, strconv.digits, nil) switch len(s) { - case 0: if wrap(write_string(fd, "00"), &n, &err) { return } - case 1: if wrap(write_rune(fd, '0'), &n, &err) { return } - case 2: if wrap(write_string(fd, s), &n, &err) { return } + case 0: if wrap(write_string(f, "00"), &n, &err) { return } + case 1: if wrap(write_rune(f, '0'), &n, &err) { return } + case 2: if wrap(write_string(f, s), &n, &err) { return } } } else { - if wrap(write_rune(fd, r), &n, &err) { return } + if wrap(write_rune(f, r), &n, &err) { return } } } - _ = wrap(write_byte(fd, '\''), &n, &err) + _ = wrap(write_byte(f, '\''), &n, &err) return } -write_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (n: int, err: Error) { +write_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { s := transmute([]byte)mem.Raw_Slice{data, len} - return write(fd, s) + return write(f, s) } -read_ptr :: proc(fd: Handle, data: rawptr, len: int) -> (n: int, err: Error) { +read_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { s := transmute([]byte)mem.Raw_Slice{data, len} - return read(fd, s) + return read(f, s) } diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index cfc9feebf..a2ecaab2f 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -4,68 +4,77 @@ package os2 import "core:io" import "core:time" -_create :: proc(name: string) -> (Handle, Error) { - return 0, nil +_File :: struct { + fd: rawptr, + name: string, } -_open :: proc(name: string) -> (Handle, Error) { - return 0, nil +_create :: proc(name: string) -> (^File, Error) { + return nil, nil } -_open_file :: proc(name: string, flag: int, perm: File_Mode) -> (Handle, Error) { - return 0, nil +_open :: proc(name: string) -> (^File, Error) { + return nil, nil } -_close :: proc(fd: Handle) -> Error { +_open_file :: proc(name: string, flag: int, perm: File_Mode) -> (^File, Error) { + return nil, nil +} + +_new_file :: proc(handle: uintptr, name: string) -> ^File { return nil } -_name :: proc(fd: Handle, allocator := context.allocator) -> string { +_close :: proc(f: ^File) -> Error { + return nil +} + +_name :: proc(f: ^File, allocator := context.allocator) -> string { return "" } -_seek :: proc(fd: Handle, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { +_seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { return } -_read :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) { +_read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { return } -_read_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return } -_read_from :: proc(fd: Handle, r: io.Reader) -> (n: i64, err: Error) { +_read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { return } -_write :: proc(fd: Handle, p: []byte) -> (n: int, err: Error) { +_write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { return } -_write_at :: proc(fd: Handle, p: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return } -_write_to :: proc(fd: Handle, w: io.Writer) -> (n: i64, err: Error) { +_write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { return } -_file_size :: proc(fd: Handle) -> (n: i64, err: Error) { +_file_size :: proc(f: ^File) -> (n: i64, err: Error) { return } -_sync :: proc(fd: Handle) -> Error { +_sync :: proc(f: ^File) -> Error { return nil } -_flush :: proc(fd: Handle) -> Error { +_flush :: proc(f: ^File) -> Error { return nil } -_truncate :: proc(fd: Handle, size: i64) -> Maybe(Path_Error) { +_truncate :: proc(f: ^File, size: i64) -> Maybe(Path_Error) { return nil } @@ -91,15 +100,15 @@ _read_link :: proc(name: string) -> (string, Maybe(Path_Error)) { } -_chdir :: proc(fd: Handle) -> Error { +_chdir :: proc(f: ^File) -> Error { return nil } -_chmod :: proc(fd: Handle, mode: File_Mode) -> Error { +_chmod :: proc(f: ^File, mode: File_Mode) -> Error { return nil } -_chown :: proc(fd: Handle, uid, gid: int) -> Error { +_chown :: proc(f: ^File, uid, gid: int) -> Error { return nil } diff --git a/core/os/os2/pipe.odin b/core/os/os2/pipe.odin index c38f03f03..62f7ddf10 100644 --- a/core/os/os2/pipe.odin +++ b/core/os/os2/pipe.odin @@ -1,5 +1,5 @@ package os2 -pipe :: proc() -> (r, w: Handle, err: Error) { +pipe :: proc() -> (r, w: ^File, err: Error) { return _pipe() } diff --git a/core/os/os2/pipe_windows.odin b/core/os/os2/pipe_windows.odin index 5570ca282..ddb54f80c 100644 --- a/core/os/os2/pipe_windows.odin +++ b/core/os/os2/pipe_windows.odin @@ -3,11 +3,11 @@ package os2 import win32 "core:sys/windows" -_pipe :: proc() -> (r, w: Handle, err: Error) { +_pipe :: proc() -> (r, w: ^File, err: Error) { p: [2]win32.HANDLE if !win32.CreatePipe(&p[0], &p[1], nil, 0) { - return 0, 0, Platform_Error{i32(win32.GetLastError())} + return nil, nil, Platform_Error{i32(win32.GetLastError())} } - return Handle(p[0]), Handle(p[1]), nil + return new_file(uintptr(p[0]), ""), new_file(uintptr(p[1]), ""), nil } diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 7fc7a4ac0..db47e2f5b 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -46,7 +46,7 @@ Process :: struct { Process_Attributes :: struct { dir: string, env: []string, - files: []Handle, + files: []^File, sys: ^Process_Attributes_OS_Specific, } diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index 19f1453ff..aa60e2a62 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -24,8 +24,8 @@ file_info_delete :: proc(fi: File_Info, allocator := context.allocator) { delete(fi.fullpath, allocator) } -fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { - return _fstat(fd, allocator) +fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { + return _fstat(f, allocator) } stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index f46a9435c..5ee9e90a1 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -4,18 +4,18 @@ package os2 import "core:time" import win32 "core:sys/windows" -_fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { - if fd == 0 { +_fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { + if f == nil || f.impl.fd == nil { return {}, Path_Error{err = .Invalid_Argument} } context.allocator = allocator - path, err := _cleanpath_from_handle(fd) + path, err := _cleanpath_from_handle(f) if err != nil { return {}, err } - h := win32.HANDLE(fd) + h := win32.HANDLE(f.impl.fd) switch win32.GetFileType(h) { case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR: fi: File_Info @@ -130,11 +130,11 @@ _cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { } -_cleanpath_from_handle :: proc(fd: Handle) -> (string, Maybe(Path_Error)) { - if fd == 0 { +_cleanpath_from_handle :: proc(f: ^File) -> (string, Maybe(Path_Error)) { + if f == nil || f.impl.fd == nil { return "", Path_Error{err = .Invalid_Argument} } - h := win32.HANDLE(fd) + h := win32.HANDLE(f.impl.fd) MAX_PATH := win32.DWORD(260) + 1 buf: []u16 @@ -153,11 +153,11 @@ _cleanpath_from_handle :: proc(fd: Handle) -> (string, Maybe(Path_Error)) { return _cleanpath_from_buf(buf), nil } -_cleanpath_from_handle_u16 :: proc(fd: Handle) -> ([]u16, Maybe(Path_Error)) { - if fd == 0 { +_cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Maybe(Path_Error)) { + if f == nil || f.impl.fd == nil { return nil, Path_Error{err = .Invalid_Argument} } - h := win32.HANDLE(fd) + h := win32.HANDLE(f.impl.fd) MAX_PATH := win32.DWORD(260) + 1 buf: []u16 diff --git a/core/os/os2/temp_file.odin b/core/os/os2/temp_file.odin index 8ff0e1656..90131699d 100644 --- a/core/os/os2/temp_file.odin +++ b/core/os/os2/temp_file.odin @@ -1,7 +1,7 @@ package os2 -create_temp :: proc(dir, pattern: string) -> (Handle, Error) { +create_temp :: proc(dir, pattern: string) -> (^File, Error) { return _create_temp(dir, pattern) } diff --git a/core/os/os2/temp_file_windows.odin b/core/os/os2/temp_file_windows.odin index 43f9f43b4..17967393a 100644 --- a/core/os/os2/temp_file_windows.odin +++ b/core/os/os2/temp_file_windows.odin @@ -3,8 +3,8 @@ package os2 import win32 "core:sys/windows" -_create_temp :: proc(dir, pattern: string) -> (Handle, Error) { - return 0, nil +_create_temp :: proc(dir, pattern: string) -> (^File, Error) { + return nil, nil } _mkdir_temp :: proc(dir, pattern: string, allocator := context.allocator) -> (string, Error) { From 96ab17ecfcbdc2d820d1cc2c6d789b49be4abc10 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 5 May 2022 18:01:44 +0100 Subject: [PATCH 173/245] Begin mocking os2 for windows out more --- core/os/os2/errors.odin | 32 +---- core/os/os2/file.odin | 59 +++++---- core/os/os2/file_util.odin | 2 +- core/os/os2/file_windows.odin | 219 ++++++++++++++++++++++++++++------ core/os/os2/path.odin | 6 +- core/os/os2/path_windows.odin | 86 ++++++++++++- core/os/os2/stat.odin | 6 +- core/os/os2/stat_windows.odin | 150 +++++++++++++---------- core/sys/win32/general.odin | 2 +- 9 files changed, 402 insertions(+), 160 deletions(-) diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 69aeaee4b..6ddae74b1 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -11,6 +11,8 @@ General_Error :: enum u32 { Closed, Timeout, + + Invalid_File, } Platform_Error :: struct { @@ -24,36 +26,6 @@ Error :: union { } #assert(size_of(Error) == size_of(u64)) -Path_Error :: struct { - op: string, - path: string, - err: Error, -} - -Link_Error :: struct { - op: string, - old: string, - new: string, - err: Error, -} - -path_error_delete :: proc(perr: Maybe(Path_Error)) { - if err, ok := perr.?; ok { - context.allocator = error_allocator() - delete(err.op) - delete(err.path) - } -} - -link_error_delete :: proc(lerr: Maybe(Link_Error)) { - if err, ok := lerr.?; ok { - context.allocator = error_allocator() - delete(err.op) - delete(err.old) - delete(err.new) - } -} - is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) { diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 463d27c54..0ed08c850 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -21,14 +21,27 @@ File_Mode_Char_Device :: File_Mode(1<<19) File_Mode_Sym_Link :: File_Mode(1<<20) -O_RDONLY :: int( 0) -O_WRONLY :: int( 1) -O_RDWR :: int( 2) -O_APPEND :: int( 4) -O_CREATE :: int( 8) -O_EXCL :: int(16) -O_SYNC :: int(32) -O_TRUNC :: int(64) +File_Flags :: distinct bit_set[File_Flag; uint] +File_Flag :: enum { + Read, + Write, + Append, + Create, + Excl, + Sync, + Trunc, + Sparse, +} + +O_RDONLY :: File_Flags{.Read} +O_WRONLY :: File_Flags{.Write} +O_RDWR :: File_Flags{.Read, .Write} +O_APPEND :: File_Flags{.Append} +O_CREATE :: File_Flags{.Create} +O_EXCL :: File_Flags{.Excl} +O_SYNC :: File_Flags{.Sync} +O_TRUNC :: File_Flags{.Trunc} +O_SPARSE :: File_Flags{.Sparse} @@ -38,27 +51,27 @@ stderr: ^File = nil // OS-Specific create :: proc(name: string) -> (^File, Error) { - return _create(name) + return open(name, {.Read, .Write, .Create}, File_Mode(0o777)) } -open :: proc(name: string) -> (^File, Error) { - return _open(name) -} - -open_file :: proc(name: string, flag: int, perm: File_Mode) -> (^File, Error) { - return _open_file(name, flag, perm) +open :: proc(name: string, flags := File_Flags{.Read}, perm := File_Mode(0o777)) -> (^File, Error) { + return _open(name, flags, perm) } new_file :: proc(handle: uintptr, name: string) -> ^File { return _new_file(handle, name) } +fd :: proc(f: ^File) -> uintptr { + return _fd(f) +} + close :: proc(f: ^File) -> Error { return _close(f) } -name :: proc(f: ^File, allocator := context.allocator) -> string { +name :: proc(f: ^File) -> string { return _name(f) } @@ -103,28 +116,28 @@ flush :: proc(f: ^File) -> Error { return _flush(f) } -truncate :: proc(f: ^File, size: i64) -> Maybe(Path_Error) { +truncate :: proc(f: ^File, size: i64) -> Error { return _truncate(f, size) } -remove :: proc(name: string) -> Maybe(Path_Error) { +remove :: proc(name: string) -> Error { return _remove(name) } -rename :: proc(old_path, new_path: string) -> Maybe(Path_Error) { +rename :: proc(old_path, new_path: string) -> Error { return _rename(old_path, new_path) } -link :: proc(old_name, new_name: string) -> Maybe(Link_Error) { +link :: proc(old_name, new_name: string) -> Error { return _link(old_name, new_name) } -symlink :: proc(old_name, new_name: string) -> Maybe(Link_Error) { +symlink :: proc(old_name, new_name: string) -> Error { return _symlink(old_name, new_name) } -read_link :: proc(name: string) -> (string, Maybe(Path_Error)) { +read_link :: proc(name: string) -> (string, Error) { return _read_link(name) } @@ -147,7 +160,7 @@ lchown :: proc(name: string, uid, gid: int) -> Error { } -chtimes :: proc(name: string, atime, mtime: time.Time) -> Maybe(Path_Error) { +chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { return _chtimes(name, atime, mtime) } diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin index 5ff4a6b99..f82bf73d0 100644 --- a/core/os/os2/file_util.odin +++ b/core/os/os2/file_util.odin @@ -109,7 +109,7 @@ write_entire_file :: proc(name: string, data: []byte, perm: File_Mode, truncate if truncate { flags |= O_TRUNC } - f, err := open_file(name, flags, perm) + f, err := open(name, flags, perm) if err != nil { return err } diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index a2ecaab2f..880305830 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -3,38 +3,119 @@ package os2 import "core:io" import "core:time" +import "core:runtime" +import "core:strings" +import win32 "core:sys/windows" + +INVALID_HANDLE :: ~uintptr(0) + +_file_allocator :: proc() -> runtime.Allocator { + return heap_allocator() +} + +_File_Kind :: enum u8 { + File, + Console, + Pipe, +} _File :: struct { fd: rawptr, name: string, + wname: win32.wstring, + kind: _File_Kind, } -_create :: proc(name: string) -> (^File, Error) { - return nil, nil +_get_platform_error :: proc() -> Error { + err := i32(win32.GetLastError()) + if err != 0 { + return Platform_Error{err} + } + return nil } -_open :: proc(name: string) -> (^File, Error) { - return nil, nil -} - -_open_file :: proc(name: string, flag: int, perm: File_Mode) -> (^File, Error) { +_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (^File, Error) { return nil, nil } _new_file :: proc(handle: uintptr, name: string) -> ^File { + if handle == INVALID_HANDLE { + return nil + } + context.allocator = _file_allocator() + f := new(File) + f.impl.fd = rawptr(fd) + f.impl.name = strings.clone(name, context.allocator) + f.impl.wname = win32.utf8_to_wstring(name, context.allocator) + + kind := _File_Kind.File + if m: u32; win32.GetConsoleMode(win32.HANDLE(fd), &m) { + kind = .Console + } + if win32.GetFileType(win32.HANDLE(fd)) == win32.FILE_TYPE_PIPE { + kind = .Pipe + } + f.impl.kind = kind + + return f +} + +_fd :: proc(f: ^File) -> uintptr { + if f == nil { + return INVALID_HANDLE + } + return uintptr(f.impl.fd) +} + +_destroy :: proc(f: ^File) -> Error { + if f == nil { + return nil + } + + context.allocator = _file_allocator() + free(f.impl.wname) + delete(f.impl.name) + free(f) return nil } + _close :: proc(f: ^File) -> Error { - return nil + if f == nil { + return nil + } + if !win32.CloseHandle(win32.HANDLE(f.impl.fd)) { + return .Closed + } + return _destroy(f) } -_name :: proc(f: ^File, allocator := context.allocator) -> string { - return "" +_name :: proc(f: ^File) -> string { + return f.impl.name if f != nil else "" } _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { - return + if f == nil { + return + } + w: u32 + switch whence { + case .Start: w = win32.FILE_BEGIN + case .Current: w = win32.FILE_CURRENT + case .End: w = win32.FILE_END + } + hi := i32(offset>>32) + lo := i32(offset) + ft := win32.GetFileType(win32.HANDLE(fd)) + if ft == win32.FILE_TYPE_PIPE { + return 0, .Invalid_File + } + + dw_ptr := win32.SetFilePointer(win32.HANDLE(fd), lo, &hi, w) + if dw_ptr == win32.INVALID_SET_FILE_POINTER { + return 0, _get_platform_error() + } + return i64(hi)<<32 + i64(dw_ptr), nil } _read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { @@ -62,6 +143,14 @@ _write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { } _file_size :: proc(f: ^File) -> (n: i64, err: Error) { + if f == nil { + return + } + length: win32.LARGE_INTEGER + if !win32.GetFileSizeEx(win32.HANDLE(fd), &length) { + err = _get_platform_error() + } + n = i64(length) return } @@ -74,34 +163,93 @@ _flush :: proc(f: ^File) -> Error { return nil } -_truncate :: proc(f: ^File, size: i64) -> Maybe(Path_Error) { +_truncate :: proc(f: ^File, size: i64) -> Error { + if f == nil { + return nil + } + curr_off := seek(f, 0, .Current) or_return + defer seek(f, curr_off, .Start) + seek(f, size, .Start) or_return + if !win32.SetEndOfFile(win32.HANDLE(fd)) { + return _get_platform_error() + } return nil } -_remove :: proc(name: string) -> Maybe(Path_Error) { - return nil +_remove :: proc(name: string) -> Error { + p := _fix_long_path(name) + err, err1: Error + if !win32.DeleteFileW(p) { + err = _get_platform_error() + } + if err == nil { + return nil + } + if !win32.RemoveDirectoryW(p) { + err1 = _get_platform_error() + } + if err1 == nil { + return nil + } + + if err != err1 { + a := win32.GetFileAttributesW(p) + if a == ~u32(0) { + err = _get_platform_error() + } else { + if a & win32.FILE_ATTRIBUTE_DIRECTORY != 0 { + err = err1 + } else if a & win32.FILE_ATTRIBUTE_READONLY != 0 { + if win32.SetFileAttributesW(p, a &~ win32.FILE_ATTRIBUTE_READONLY) { + err = nil + if !win32.DeleteFileW(p) { + err = _get_platform_error() + } + } + } + } + } + + return err } -_rename :: proc(old_path, new_path: string) -> Maybe(Path_Error) { - return nil +_rename :: proc(old_path, new_path: string) -> Error { + from := _fix_long_path(old_path) + to := _fix_long_path(new_path) + if win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) { + return nil + } + return _get_platform_error() + } -_link :: proc(old_name, new_name: string) -> Maybe(Link_Error) { +_link :: proc(old_name, new_name: string) -> Error { + o := _fix_long_path(old_name) + n := _fix_long_path(new_name) + if win32.CreateHardLinkW(n, o, nil) { + return nil + } + return _get_platform_error() +} + +_symlink :: proc(old_name, new_name: string) -> Error { return nil } -_symlink :: proc(old_name, new_name: string) -> Maybe(Link_Error) { - return nil -} - -_read_link :: proc(name: string) -> (string, Maybe(Path_Error)) { +_read_link :: proc(name: string) -> (string, Error) { return "", nil } _chdir :: proc(f: ^File) -> Error { - return nil + if f == nil { + return nil + } + if win32.SetCurrentDirectoryW(f.impl.wname) { + return nil + } + return _get_platform_error() } _chmod :: proc(f: ^File, mode: File_Mode) -> Error { @@ -118,28 +266,31 @@ _lchown :: proc(name: string, uid, gid: int) -> Error { } -_chtimes :: proc(name: string, atime, mtime: time.Time) -> Maybe(Path_Error) { +_chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { return nil } _exists :: proc(path: string) -> bool { - return false + wpath := _fix_long_path(path) + attribs := win32.GetFileAttributesW(wpath) + return i32(attribs) != win32.INVALID_FILE_ATTRIBUTES } _is_file :: proc(path: string) -> bool { + wpath := _fix_long_path(path) + attribs := win32.GetFileAttributesW(wpath) + if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES { + return attribs & win32.FILE_ATTRIBUTE_DIRECTORY == 0 + } return false } _is_dir :: proc(path: string) -> bool { + wpath := _fix_long_path(path) + attribs := win32.GetFileAttributesW(wpath) + if i32(attribs) != win32.INVALID_FILE_ATTRIBUTES { + return attribs & win32.FILE_ATTRIBUTE_DIRECTORY != 0 + } return false } - - -_path_error_delete :: proc(perr: Maybe(Path_Error)) { - -} - -_link_error_delete :: proc(lerr: Maybe(Link_Error)) { - -} diff --git a/core/os/os2/path.odin b/core/os/os2/path.odin index ee7d6e6f2..eca8b518f 100644 --- a/core/os/os2/path.odin +++ b/core/os/os2/path.odin @@ -7,15 +7,15 @@ is_path_separator :: proc(c: byte) -> bool { return _is_path_separator(c) } -mkdir :: proc(name: string, perm: File_Mode) -> Maybe(Path_Error) { +mkdir :: proc(name: string, perm: File_Mode) -> Error { return _mkdir(name, perm) } -mkdir_all :: proc(path: string, perm: File_Mode) -> Maybe(Path_Error) { +mkdir_all :: proc(path: string, perm: File_Mode) -> Error { return _mkdir_all(path, perm) } -remove_all :: proc(path: string) -> Maybe(Path_Error) { +remove_all :: proc(path: string) -> Error { return _remove_all(path) } diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index 607f56968..0e77db4fd 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -1,6 +1,8 @@ //+private package os2 +import win32 "core:sys/windows" + _Path_Separator :: '\\' _Path_List_Separator :: ';' @@ -8,16 +10,16 @@ _is_path_separator :: proc(c: byte) -> bool { return c == '\\' || c == '/' } -_mkdir :: proc(name: string, perm: File_Mode) -> Maybe(Path_Error) { +_mkdir :: proc(name: string, perm: File_Mode) -> Error { return nil } -_mkdir_all :: proc(path: string, perm: File_Mode) -> Maybe(Path_Error) { +_mkdir_all :: proc(path: string, perm: File_Mode) -> Error { // TODO(bill): _mkdir_all for windows return nil } -_remove_all :: proc(path: string) -> Maybe(Path_Error) { +_remove_all :: proc(path: string) -> Error { // TODO(bill): _remove_all for windows return nil } @@ -29,3 +31,81 @@ _getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) { _setwd :: proc(dir: string) -> (err: Error) { return nil } + + +can_use_long_paths: bool + +@(init) +init_long_path_support :: proc() { + // TODO(bill): init_long_path_support + // ADD THIS SHIT + // registry_path := win32.L(`Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled`) + can_use_long_paths = false +} + + +_fix_long_path_slice :: proc(path: string) -> []u16 { + return win32.utf8_to_utf16(_fix_long_path_internal(path)) +} + +_fix_long_path :: proc(path: string) -> win32.wstring { + return win32.utf8_to_wstring(_fix_long_path_internal(path)) +} + + +_fix_long_path_internal :: proc(path: string) -> string { + if can_use_long_paths { + return path + } + + // When using win32 to create a directory, the path + // cannot be too long that you cannot append an 8.3 + // file name, because MAX_PATH is 260, 260-12 = 248 + if len(path) < 248 { + return path + } + + // UNC paths do not need to be modified + if len(path) >= 2 && path[:2] == `\\` { + return path + } + + if !_is_abs(path) { // relative path + return path + } + + PREFIX :: `\\?` + path_buf := make([]byte, len(PREFIX)+len(path)+1, context.temp_allocator) + copy(path_buf, PREFIX) + n := len(path) + r, w := 0, len(PREFIX) + for r < n { + switch { + case is_path_separator(path[r]): + r += 1 + case path[r] == '.' && (r+1 == n || is_path_separator(path[r+1])): + // \.\ + r += 1 + case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || is_path_separator(path[r+2])): + // Skip \..\ paths + return path + case: + path_buf[w] = '\\' + w += 1 + for r < n && !is_path_separator(path[r]) { + path_buf[w] = path[r] + r += 1 + w += 1 + } + } + } + + // Root directories require a trailing \ + if w == len(`\\?\c:`) { + path_buf[w] = '\\' + w += 1 + } + + return string(path_buf[:w]) + +} diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index aa60e2a62..63f5a17e8 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -24,15 +24,15 @@ file_info_delete :: proc(fi: File_Info, allocator := context.allocator) { delete(fi.fullpath, allocator) } -fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Error) { return _fstat(f, allocator) } -stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { return _stat(name, allocator) } -lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { return _lstat(name, allocator) } diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 5ee9e90a1..a79e5aae2 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -2,11 +2,12 @@ package os2 import "core:time" +import "core:strings" import win32 "core:sys/windows" -_fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +_fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Error) { if f == nil || f.impl.fd == nil { - return {}, Path_Error{err = .Invalid_Argument} + return {}, .Invalid_Argument } context.allocator = allocator @@ -27,10 +28,10 @@ _fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Maybe(Pa return _file_info_from_get_file_information_by_handle(path, h) } -_stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +_stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS) } -_lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Maybe(Path_Error)) { +_lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS|win32.FILE_FLAG_OPEN_REPARSE_POINT) } _same_file :: proc(fi1, fi2: File_Info) -> bool { @@ -39,12 +40,12 @@ _same_file :: proc(fi1, fi2: File_Info) -> bool { -_stat_errno :: proc(errno: win32.DWORD) -> Path_Error { - return Path_Error{err = Platform_Error{i32(errno)}} +_stat_errno :: proc(errno: win32.DWORD) -> Error { + return Platform_Error{i32(errno)} } -full_path_from_name :: proc(name: string, allocator := context.allocator) -> (path: string, err: Maybe(Path_Error)) { +full_path_from_name :: proc(name: string, allocator := context.allocator) -> (path: string, err: Error) { context.allocator = allocator name := name @@ -69,15 +70,15 @@ full_path_from_name :: proc(name: string, allocator := context.allocator) -> (pa } -internal_stat :: proc(name: string, create_file_attributes: u32, allocator := context.allocator) -> (fi: File_Info, e: Maybe(Path_Error)) { +internal_stat :: proc(name: string, create_file_attributes: u32, allocator := context.allocator) -> (fi: File_Info, e: Error) { if len(name) == 0 { - return {}, Path_Error{err = .Not_Exist} + return {}, .Not_Exist } context.allocator = allocator - wname := win32.utf8_to_wstring(_fix_long_path(name), context.temp_allocator) + wname := _fix_long_path(name) fa: win32.WIN32_FILE_ATTRIBUTE_DATA ok := win32.GetFileAttributesExW(wname, win32.GetFileExInfoStandard, &fa) if ok && fa.dwFileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 { @@ -91,7 +92,7 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator := co fd: win32.WIN32_FIND_DATAW sh := win32.FindFirstFileW(wname, &fd) if sh == win32.INVALID_HANDLE_VALUE { - e = Path_Error{err = Platform_Error{i32(win32.GetLastError())}} + e = _get_platform_error() return } win32.FindClose(sh) @@ -101,7 +102,7 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator := co h := win32.CreateFileW(wname, 0, 0, nil, win32.OPEN_EXISTING, create_file_attributes, nil) if h == win32.INVALID_HANDLE_VALUE { - e = Path_Error{err = Platform_Error{i32(win32.GetLastError())}} + e = _get_platform_error() return } defer win32.CloseHandle(h) @@ -130,9 +131,9 @@ _cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { } -_cleanpath_from_handle :: proc(f: ^File) -> (string, Maybe(Path_Error)) { +_cleanpath_from_handle :: proc(f: ^File) -> (string, Error) { if f == nil || f.impl.fd == nil { - return "", Path_Error{err = .Invalid_Argument} + return "", .Invalid_Argument } h := win32.HANDLE(f.impl.fd) @@ -153,9 +154,9 @@ _cleanpath_from_handle :: proc(f: ^File) -> (string, Maybe(Path_Error)) { return _cleanpath_from_buf(buf), nil } -_cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Maybe(Path_Error)) { +_cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) { if f == nil || f.impl.fd == nil { - return nil, Path_Error{err = .Invalid_Argument} + return nil, .Invalid_Argument } h := win32.HANDLE(f.impl.fd) @@ -251,7 +252,7 @@ _file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HA } -_file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Maybe(Path_Error)) { +_file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) @@ -268,7 +269,7 @@ _file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE } -_file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string) -> (fi: File_Info, e: Maybe(Path_Error)) { +_file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) @@ -285,7 +286,7 @@ _file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string } -_file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Maybe(Path_Error)) { +_file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Error) { d: win32.BY_HANDLE_FILE_INFORMATION if !win32.GetFileInformationByHandle(h, &d) { return {}, _stat_errno(win32.GetLastError()) @@ -318,58 +319,83 @@ _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HA return fi, nil } -_is_abs :: proc(path: string) -> bool { - if len(path) > 0 && path[0] == '/' { - return true + + +reserved_names := [?]string{ + "CON", "PRN", "AUX", "NUL", + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", +} + +_is_reserved_name :: proc(path: string) -> bool { + if len(path) == 0 { + return false } - if len(path) > 2 { - switch path[0] { - case 'A'..='Z', 'a'..='z': - return path[1] == ':' && is_path_separator(path[2]) + for reserved in reserved_names { + if strings.equal_fold(path, reserved) { + return true } } return false } -_fix_long_path :: proc(path: string) -> string { - if len(path) < 248 { - return path - } +_is_UNC :: proc(path: string) -> bool { + return _volume_name_len(path) > 2 +} - if len(path) >= 2 && path[:2] == `\\` { - return path - } - if !_is_abs(path) { - return path - } +_volume_name_len :: proc(path: string) -> int { + if ODIN_OS == .Windows { + if len(path) < 2 { + return 0 + } + c := path[0] + if path[1] == ':' { + switch c { + case 'a'..='z', 'A'..='Z': + return 2 + } + } - prefix :: `\\?` - - path_buf := make([]byte, len(prefix)+len(path)+len(`\`), context.temp_allocator) - copy(path_buf, prefix) - n := len(path) - r, w := 0, len(prefix) - for r < n { - switch { - case is_path_separator(path[r]): - r += 1 - case path[r] == '.' && (r+1 == n || is_path_separator(path[r+1])): - r += 1 - case r+1 < n && path[r] == '.' && path[r+1] == '.' && (r+2 == n || is_path_separator(path[r+2])): - return path - case: - path_buf[w] = '\\' - w += 1 - for ; r < n && !is_path_separator(path[r]); r += 1 { - path_buf[w] = path[r] - w += 1 + // URL: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx + if l := len(path); l >= 5 && _is_path_separator(path[0]) && _is_path_separator(path[1]) && + !_is_path_separator(path[2]) && path[2] != '.' { + for n := 3; n < l-1; n += 1 { + if _is_path_separator(path[n]) { + n += 1 + if !_is_path_separator(path[n]) { + if path[n] == '.' { + break + } + } + for ; n < l; n += 1 { + if _is_path_separator(path[n]) { + break + } + } + return n + } + break } } } - - if w == len(`\\?\c:`) { - path_buf[w] = '\\' - w += 1 - } - return string(path_buf[:w]) + return 0 } + + +_is_abs :: proc(path: string) -> bool { + if _is_reserved_name(path) { + return true + } + l := _volume_name_len(path) + if l == 0 { + return false + } + + path := path + path = path[l:] + if path == "" { + return false + } + return is_path_separator(path[0]) +} + diff --git a/core/sys/win32/general.odin b/core/sys/win32/general.odin index d53bf8a4f..1baad8b11 100644 --- a/core/sys/win32/general.odin +++ b/core/sys/win32/general.odin @@ -30,7 +30,7 @@ Monitor_Enum_Proc :: distinct #type proc "std" (Hmonitor, Hdc, ^Rect, Lparam) -> Bool :: distinct b32 -Wstring :: distinct ^u16 +Wstring :: distinct [^]u16 Point :: struct { x, y: i32, From 6f20b5bb59f61be1456bda60e5031f6a397639a4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 6 May 2022 10:59:55 +0100 Subject: [PATCH 174/245] Add mock for `_yield` --- core/time/time_js.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/time/time_js.odin b/core/time/time_js.odin index 1b801cdad..cfe54b86b 100644 --- a/core/time/time_js.odin +++ b/core/time/time_js.odin @@ -19,3 +19,5 @@ _tick_now :: proc "contextless" () -> Tick { return {} } +_yield :: proc "contextless" () { +} From 53c70da0b83f573d8c1d0572d7a57fd0bac759fc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 6 May 2022 11:16:24 +0100 Subject: [PATCH 175/245] Correct `foreign import` prefix behaviour for wasm --- src/check_decl.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 5acd56097..82ac6c677 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1018,18 +1018,16 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } Entity *foreign_library = init_entity_foreign_library(ctx, e); - if (is_arch_wasm()) { + if (is_arch_wasm() && foreign_library != nullptr) { String module_name = str_lit("env"); - if (foreign_library != nullptr) { - GB_ASSERT (foreign_library->kind == Entity_LibraryName); - if (foreign_library->LibraryName.paths.count != 1) { - error(foreign_library->token, "'foreign import' for '%.*s' architecture may only have one path, got %td", - LIT(target_arch_names[build_context.metrics.arch]), foreign_library->LibraryName.paths.count); - } - - if (foreign_library->LibraryName.paths.count >= 1) { - module_name = foreign_library->LibraryName.paths[0]; - } + GB_ASSERT (foreign_library->kind == Entity_LibraryName); + if (foreign_library->LibraryName.paths.count != 1) { + error(foreign_library->token, "'foreign import' for '%.*s' architecture may only have one path, got %td", + LIT(target_arch_names[build_context.metrics.arch]), foreign_library->LibraryName.paths.count); + } + + if (foreign_library->LibraryName.paths.count >= 1) { + module_name = foreign_library->LibraryName.paths[0]; } name = concatenate3_strings(permanent_allocator(), module_name, WASM_MODULE_NAME_SEPARATOR, name); } From 4b289f904c4b981b87fc55b8d8c73f785d23266a Mon Sep 17 00:00:00 2001 From: hikari Date: Fri, 6 May 2022 13:58:00 +0300 Subject: [PATCH 176/245] sys/win32: fix RGB macro --- core/sys/windows/gdi32.odin | 4 +--- core/sys/windows/types.odin | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index e728503d2..551d42417 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -67,8 +67,6 @@ foreign gdi32 { PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL --- } -// Windows colors are packed as ABGR RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF { - res: [4]u8 = {0, b, g, r} - return transmute(COLORREF)res + return COLORREF(r) | COLORREF(WORD(g) << 8) | COLORREF(DWORD(b) << 16) } diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index c3e461ba0..4093fd3f9 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -55,7 +55,7 @@ UINT_PTR :: uintptr ULONG :: c_ulong UCHAR :: BYTE NTSTATUS :: c.long -COLORREF :: DWORD // Windows colors are packed as ABGR +COLORREF :: DWORD LPCOLORREF :: ^COLORREF LPARAM :: LONG_PTR WPARAM :: UINT_PTR From 4cdc55af91f006999637fc786e6e3df5ea913164 Mon Sep 17 00:00:00 2001 From: hikari Date: Fri, 6 May 2022 18:23:52 +0300 Subject: [PATCH 177/245] sys/windows: fix RGB macro again --- core/sys/windows/gdi32.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin index 551d42417..898766361 100644 --- a/core/sys/windows/gdi32.odin +++ b/core/sys/windows/gdi32.odin @@ -68,5 +68,5 @@ foreign gdi32 { } RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF { - return COLORREF(r) | COLORREF(WORD(g) << 8) | COLORREF(DWORD(b) << 16) + return transmute(COLORREF)[4]u8{r, g, b, 0} } From 85e6efdf16ad075f92a61ce59afa50634ccadeee Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sun, 8 May 2022 10:39:03 +0200 Subject: [PATCH 178/245] Ctrl-C handler on Windows. --- core/sys/win32/kernel32.odin | 2 +- core/sys/windows/kernel32.odin | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin index 709964fb4..ca6122690 100644 --- a/core/sys/win32/kernel32.odin +++ b/core/sys/win32/kernel32.odin @@ -234,4 +234,4 @@ PAGE_WRITECOPY :: 0x08 PAGE_EXECUTE :: 0x10 PAGE_EXECUTE_READ :: 0x20 PAGE_EXECUTE_READWRITE :: 0x40 -PAGE_EXECUTE_WRITECOPY :: 0x80 +PAGE_EXECUTE_WRITECOPY :: 0x80 \ No newline at end of file diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index cb90f71da..6ac0fccf2 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -758,3 +758,18 @@ foreign kernel32 { UnmapFlags: ULONG, ) -> BOOL --- } + +@(default_calling_convention = "std") +foreign kernel32 { + @(link_name="SetConsoleCtrlHandler") set_console_ctrl_handler :: proc(handler: Handler_Routine, add: BOOL) -> BOOL --- +} + +Handler_Routine :: proc(dwCtrlType: Control_Event) -> BOOL + +Control_Event :: enum DWORD { + control_c = 0, + _break = 1, + close = 2, + logoff = 5, + shutdown = 6, +} \ No newline at end of file From c9e31dc90d4036a042840ba7cf2a04785d80c4b4 Mon Sep 17 00:00:00 2001 From: Aaron Glazer Date: Sun, 8 May 2022 02:34:01 -0700 Subject: [PATCH 179/245] Adding some proc bindings, struct definitions, and constant values. --- core/sys/windows/kernel32.odin | 12 ++++++++++++ core/sys/windows/types.odin | 28 ++++++++++++++++++++++++++++ core/sys/windows/user32.odin | 6 ++++++ 3 files changed, 46 insertions(+) diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 6ac0fccf2..d95ff91c9 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -238,6 +238,7 @@ foreign kernel32 { bInitialState: BOOL, lpName: LPCWSTR, ) -> HANDLE --- + ResetEvent :: proc(hEvent: HANDLE) -> BOOL --- WaitForMultipleObjects :: proc( nCount: DWORD, lpHandles: ^HANDLE, @@ -266,6 +267,17 @@ foreign kernel32 { HeapReAlloc :: proc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID --- HeapFree :: proc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL --- + ReadDirectoryChangesW :: proc( + hDirectory: HANDLE, + lpBuffer: LPVOID, + nBufferLength: DWORD, + bWatchSubtree: BOOL, + dwNotifyFilter: DWORD, + lpBytesReturned: LPDWORD, + lpOverlapped: LPOVERLAPPED, + lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, + ) -> BOOL --- + InitializeSRWLock :: proc(SRWLock: ^SRWLOCK) --- AcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) --- TryAcquireSRWLockExclusive :: proc(SRWLock: ^SRWLOCK) -> BOOL --- diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 4093fd3f9..d06cd287c 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -164,6 +164,21 @@ FILE_GENERIC_ALL: DWORD : 0x10000000 FILE_GENERIC_EXECUTE: DWORD : 0x20000000 FILE_GENERIC_READ: DWORD : 0x80000000 +FILE_ACTION_ADDED :: 0x00000001 +FILE_ACTION_REMOVED :: 0x00000002 +FILE_ACTION_MODIFIED :: 0x00000003 +FILE_ACTION_RENAMED_OLD_NAME :: 0x00000004 +FILE_ACTION_RENAMED_NEW_NAME :: 0x00000005 + +FILE_NOTIFY_CHANGE_FILE_NAME :: 0x00000001 +FILE_NOTIFY_CHANGE_DIR_NAME :: 0x00000002 +FILE_NOTIFY_CHANGE_ATTRIBUTES :: 0x00000004 +FILE_NOTIFY_CHANGE_SIZE :: 0x00000008 +FILE_NOTIFY_CHANGE_LAST_WRITE :: 0x00000010 +FILE_NOTIFY_CHANGE_LAST_ACCESS :: 0x00000020 +FILE_NOTIFY_CHANGE_CREATION :: 0x00000040 +FILE_NOTIFY_CHANGE_SECURITY :: 0x00000100 + CREATE_NEW: DWORD : 1 CREATE_ALWAYS: DWORD : 2 OPEN_ALWAYS: DWORD : 4 @@ -1365,6 +1380,13 @@ FILE_END_OF_FILE_INFO :: struct { EndOfFile: LARGE_INTEGER, } +FILE_NOTIFY_INFORMATION :: struct { + next_entry_offset: DWORD, + action: DWORD, + file_name_length: DWORD, + file_name: [1]WCHAR, +} + REPARSE_DATA_BUFFER :: struct { ReparseTag: c_uint, ReparseDataLength: c_ushort, @@ -1509,6 +1531,12 @@ OVERLAPPED :: struct { hEvent: HANDLE, } +LPOVERLAPPED_COMPLETION_ROUTINE :: #type proc "stdcall" ( + dwErrorCode: DWORD, + dwNumberOfBytesTransfered: DWORD, + lpOverlapped: LPOVERLAPPED, +) + ADDRESS_MODE :: enum c_int { AddrMode1616, AddrMode1632, diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index f83713a33..2010f0810 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -105,6 +105,7 @@ foreign user32 { GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL --- GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL --- ClientToScreen :: proc(hWnd: HWND, lpPoint: LPPOINT) -> BOOL --- + ScreenToClient :: proc(hWnd: HWND, lpPoint: LPPOINT) -> BOOL --- SetWindowPos :: proc( hWnd: HWND, hWndInsertAfter: HWND, @@ -155,6 +156,11 @@ foreign user32 { MessageBoxW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT) -> c_int --- MessageBoxExA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT, wLanguageId: WORD) -> c_int --- MessageBoxExW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT, wLanguageId: WORD) -> c_int --- + + ClipCursor :: proc(lpRect: LPRECT) -> BOOL --- + GetCursorPos :: proc(lpPoint: LPPOINT) -> BOOL --- + SetCursorPos :: proc(X: c_int, Y: c_int) -> BOOL --- + SetCursor :: proc(hCursor: HCURSOR) -> HCURSOR --- } CreateWindowA :: #force_inline proc "stdcall" ( From 6f1cc3946b0f187bcf2b61602f9f1a4d4d4cbbb4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 May 2022 16:58:34 +0100 Subject: [PATCH 180/245] Begin work on Event System for js_wasm32 target --- vendor/wasm/README.md | 1 + vendor/wasm/WebGL/{runtime.js => runtime.mjs} | 198 +++++----- vendor/wasm/js/dom.odin | 22 ++ vendor/wasm/js/events.odin | 320 +++++++++++++++ vendor/wasm/js/runtime.js | 154 -------- vendor/wasm/js/runtime.mjs | 372 ++++++++++++++++++ vendor/wasm/loader/loader.mjs | 63 +++ 7 files changed, 877 insertions(+), 253 deletions(-) rename vendor/wasm/WebGL/{runtime.js => runtime.mjs} (97%) create mode 100644 vendor/wasm/js/dom.odin create mode 100644 vendor/wasm/js/events.odin delete mode 100644 vendor/wasm/js/runtime.js create mode 100644 vendor/wasm/js/runtime.mjs create mode 100644 vendor/wasm/loader/loader.mjs diff --git a/vendor/wasm/README.md b/vendor/wasm/README.md index 8567f2eab..4a9345504 100644 --- a/vendor/wasm/README.md +++ b/vendor/wasm/README.md @@ -32,6 +32,7 @@ const runWasm = async (wasm_path, webglCanvasElement, consoleElement) => { const file = await response.arrayBuffer(); const wasm = await WebAssembly.instantiate(file, imports); const exports = wasm.instance.exports; + wasmMemoryInterface.setExports(exports); wasmMemoryInterface.setMemory(exports.memory); exports._start(); diff --git a/vendor/wasm/WebGL/runtime.js b/vendor/wasm/WebGL/runtime.mjs similarity index 97% rename from vendor/wasm/WebGL/runtime.js rename to vendor/wasm/WebGL/runtime.mjs index 3dc5186ca..4d34b9f4c 100644 --- a/vendor/wasm/WebGL/runtime.js +++ b/vendor/wasm/WebGL/runtime.mjs @@ -23,11 +23,11 @@ class WebGLInterface { this.transformFeedbacks = []; this.syncs = []; this.programInfos = {}; - + if (contextSettings === undefined) { contextSettings = {antialias: false}; } - + this.ctx = canvasElement.getContext("webgl2", contextSettings) || canvasElement.getContext("webgl", contextSettings); if (!this.ctx) { return; @@ -38,11 +38,11 @@ class WebGLInterface { this.ctx_version = 1.0; } } - + get mem() { return this.wasmMemoryInterface } - + assertWebGL2() { if (this.ctx_version < 2) { throw new Error("WebGL2 procedure called in a canvas without a WebGL2 context"); @@ -95,19 +95,19 @@ class WebGLInterface { } return source; } - + getWebGL1Interface() { return { DrawingBufferWidth: () => this.ctx.drawingBufferWidth, DrawingBufferHeight: () => this.ctx.drawingBufferHeight, - + IsExtensionSupported: (name_ptr, name_len) => { let name = this.mem.loadString(name_ptr, name_len); let extensions = this.ctx.getSupportedExtensions(); return extensions.indexOf(name) !== -1 }, - - + + GetError: () => { let err = this.lastError; this.recordError(0); @@ -116,7 +116,7 @@ class WebGLInterface { } return this.ctx.getError(); }, - + GetWebGLVersion: (major_ptr, minor_ptr) => { let version = this.ctx.getParameter(0x1F02); if (version.indexOf("WebGL 2.0") !== -1) { @@ -124,7 +124,7 @@ class WebGLInterface { this.mem.storeI32(minor_ptr, 0); return; } - + this.mem.storeI32(major_ptr, 1); this.mem.storeI32(minor_ptr, 0); }, @@ -135,12 +135,12 @@ class WebGLInterface { this.mem.storeI32(minor_ptr, 0); return; } - + this.mem.storeI32(major_ptr, 2); this.mem.storeI32(minor_ptr, 0); }, - - + + ActiveTexture: (x) => { this.ctx.activeTexture(x); }, @@ -180,8 +180,8 @@ class WebGLInterface { BlendFuncSeparate: (srcRGB, dstRGB, srcAlpha, dstAlpha) => { this.ctx.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); }, - - + + BufferData: (target, size, data, usage) => { if (data) { this.ctx.bufferData(target, this.mem.loadBytes(data, size), usage); @@ -196,8 +196,8 @@ class WebGLInterface { this.ctx.bufferSubData(target, offset, null); } }, - - + + Clear: (x) => { this.ctx.clear(x); }, @@ -216,8 +216,8 @@ class WebGLInterface { CompileShader: (shader) => { this.ctx.compileShader(this.shaders[shader]); }, - - + + CompressedTexImage2D: (target, level, internalformat, width, height, border, imageSize, data) => { if (data) { this.ctx.compressedTexImage2D(target, level, internalformat, width, height, border, this.mem.loadBytes(data, imageSize)); @@ -232,15 +232,15 @@ class WebGLInterface { this.ctx.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, null); } }, - + CopyTexImage2D: (target, level, internalformat, x, y, width, height, border) => { this.ctx.copyTexImage2D(target, level, internalformat, x, y, width, height, border); }, CopyTexSubImage2D: (target, level, xoffset, yoffset, x, y, width, height) => { this.ctx.copyTexImage2D(target, level, xoffset, yoffset, x, y, width, height); }, - - + + CreateBuffer: () => { let buffer = this.ctx.createBuffer(); if (!buffer) { @@ -291,13 +291,13 @@ class WebGLInterface { this.textures[id] = texture; return id; }, - - + + CullFace: (mode) => { this.ctx.cullFace(mode); }, - - + + DeleteBuffer: (id) => { let obj = this.buffers[id]; if (obj && id != 0) { @@ -366,8 +366,8 @@ class WebGLInterface { DrawElements: (mode, count, type, indices) => { this.ctx.drawElements(mode, count, type, indices); }, - - + + Enable: (cap) => { this.ctx.enable(cap); }, @@ -389,20 +389,20 @@ class WebGLInterface { FrontFace: (mode) => { this.ctx.frontFace(mode); }, - - + + GenerateMipmap: (target) => { this.ctx.generateMipmap(target); }, - - + + GetAttribLocation: (program, name_ptr, name_len) => { let name = this.mem.loadString(name_ptr, name_len); return this.ctx.getAttribLocation(this.programs[program], name); }, - - - + + + GetProgramParameter: (program, pname) => { return this.ctx.getProgramParameter(this.programs[program], pname) }, @@ -415,7 +415,7 @@ class WebGLInterface { let n = Math.min(buf_len, log.length); log = log.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(log)) - + this.mem.storeInt(length_ptr, n); } }, @@ -428,7 +428,7 @@ class WebGLInterface { let n = Math.min(buf_len, log.length); log = log.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(log)) - + this.mem.storeInt(length_ptr, n); } }, @@ -452,8 +452,8 @@ class WebGLInterface { this.recordError(1281); } }, - - + + GetUniformLocation: (program, name_ptr, name_len) => { let name = this.mem.loadString(name_ptr, name_len); let arrayOffset = 0; @@ -472,18 +472,18 @@ class WebGLInterface { var uniformInfo = ptable.uniforms[name]; return (uniformInfo && arrayOffset < uniformInfo[0]) ? uniformInfo[1] + arrayOffset : -1 }, - - + + GetVertexAttribOffset: (index, pname) => { return this.ctx.getVertexAttribOffset(index, pname); }, - - + + Hint: (target, mode) => { this.ctx.hint(target, mode); }, - - + + IsBuffer: (buffer) => this.ctx.isBuffer(this.buffers[buffer]), IsEnabled: (enabled) => this.ctx.isEnabled(this.enableds[enabled]), IsFramebuffer: (framebuffer) => this.ctx.isFramebuffer(this.framebuffers[framebuffer]), @@ -491,7 +491,7 @@ class WebGLInterface { IsRenderbuffer: (renderbuffer) => this.ctx.isRenderbuffer(this.renderbuffers[renderbuffer]), IsShader: (shader) => this.ctx.isShader(this.shaders[shader]), IsTexture: (texture) => this.ctx.isTexture(this.textures[texture]), - + LineWidth: (width) => { this.ctx.lineWidth(width); }, @@ -506,8 +506,8 @@ class WebGLInterface { PolygonOffset: (factor, units) => { this.ctx.polygonOffset(factor, units); }, - - + + ReadnPixels: (x, y, width, height, format, type, bufSize, data) => { this.ctx.readPixels(x, y, width, format, type, this.mem.loadBytes(data, bufSize)); }, @@ -524,7 +524,7 @@ class WebGLInterface { let source = this.getSource(shader, strings_ptr, strings_length); this.ctx.shaderSource(this.shaders[shader], source); }, - + StencilFunc: (func, ref, mask) => { this.ctx.stencilFunc(func, ref, mask); }, @@ -543,8 +543,8 @@ class WebGLInterface { StencilOpSeparate: (face, fail, zfail, zpass) => { this.ctx.stencilOpSeparate(face, fail, zfail, zpass); }, - - + + TexImage2D: (target, level, internalformat, width, height, border, format, type, size, data) => { if (data) { this.ctx.texImage2D(target, level, internalformat, width, height, border, format, type, this.mem.loadBytes(data, size)); @@ -561,18 +561,18 @@ class WebGLInterface { TexSubImage2D: (target, level, xoffset, yoffset, width, height, format, type, size, data) => { this.ctx.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, this.mem.loadBytes(data, size)); }, - - + + Uniform1f: (location, v0) => { this.ctx.uniform1f(this.uniforms[location], v0); }, Uniform2f: (location, v0, v1) => { this.ctx.uniform2f(this.uniforms[location], v0, v1); }, Uniform3f: (location, v0, v1, v2) => { this.ctx.uniform3f(this.uniforms[location], v0, v1, v2); }, Uniform4f: (location, v0, v1, v2, v3) => { this.ctx.uniform4f(this.uniforms[location], v0, v1, v2, v3); }, - + Uniform1i: (location, v0) => { this.ctx.uniform1i(this.uniforms[location], v0); }, Uniform2i: (location, v0, v1) => { this.ctx.uniform2i(this.uniforms[location], v0, v1); }, Uniform3i: (location, v0, v1, v2) => { this.ctx.uniform3i(this.uniforms[location], v0, v1, v2); }, Uniform4i: (location, v0, v1, v2, v3) => { this.ctx.uniform4i(this.uniforms[location], v0, v1, v2, v3); }, - + UniformMatrix2fv: (location, addr) => { let array = this.mem.loadF32Array(addr, 2*2); this.ctx.uniformMatrix4fv(this.uniforms[location], false, array); @@ -585,15 +585,15 @@ class WebGLInterface { let array = this.mem.loadF32Array(addr, 4*4); this.ctx.uniformMatrix4fv(this.uniforms[location], false, array); }, - + UseProgram: (program) => { - this.ctx.useProgram(this.programs[program]); + if (program) this.ctx.useProgram(this.programs[program]); }, ValidateProgram: (program) => { - this.ctx.validateProgram(this.programs[program]); + if (program) this.ctx.validateProgram(this.programs[program]); }, - - + + VertexAttrib1f: (index, x) => { this.ctx.vertexAttrib1f(index, x); }, @@ -609,13 +609,13 @@ class WebGLInterface { VertexAttribPointer: (index, size, type, normalized, stride, ptr) => { this.ctx.vertexAttribPointer(index, size, type, !!normalized, stride, ptr); }, - + Viewport: (x, y, w, h) => { this.ctx.viewport(x, y, w, h); }, }; } - + getWebGL2Interface() { return { /* Buffer objects */ @@ -627,7 +627,7 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.getBufferSubData(target, srcByteOffset, this.mem.loadBytes(dst_buffer_ptr, dst_buffer_len), dstOffset, length); }, - + /* Framebuffer objects */ BlitFramebuffer: (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) => { this.assertWebGL2(); @@ -642,7 +642,7 @@ class WebGLInterface { let attachments = this.mem.loadU32Array(attachments_ptr, attachments_len); this.ctx.invalidateFramebuffer(target, attachments); }, - InvalidateSubFramebuffer: (target, attachments_ptr, attachments_len, x, y, width, height) => { + InvalidateSubFramebuffer: (target, attachments_ptr, attachments_len, x, y, width, height) => { this.assertWebGL2(); let attachments = this.mem.loadU32Array(attachments_ptr, attachments_len); this.ctx.invalidateSubFramebuffer(target, attachments, x, y, width, height); @@ -651,15 +651,15 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.readBuffer(src); }, - + /* Renderbuffer objects */ RenderbufferStorageMultisample: (target, samples, internalformat, width, height) => { this.assertWebGL2(); this.ctx.renderbufferStorageMultisample(target, samples, internalformat, width, height); }, - + /* Texture objects */ - + TexStorage3D: (target, levels, internalformat, width, height, depth) => { this.assertWebGL2(); this.ctx.texStorage3D(target, level, internalformat, width, heigh, depth); @@ -692,18 +692,18 @@ class WebGLInterface { this.ctx.compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, null); } }, - + CopyTexSubImage3D: (target, level, xoffset, yoffset, zoffset, x, y, width, height) => { this.assertWebGL2(); this.ctx.copyTexImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); }, - + /* Programs and shaders */ GetFragDataLocation: (program, name_ptr, name_len) => { this.assertWebGL2(); return this.ctx.getFragDataLocation(this.programs[program], this.mem.loadString(name_ptr, name_len)); }, - + /* Uniforms */ Uniform1ui: (location, v0) => { this.assertWebGL2(); @@ -721,7 +721,7 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.uniform4ui(this.uniforms[location], v0, v1, v2, v3); }, - + UniformMatrix3x2fv: (location, addr) => { this.assertWebGL2(); let array = this.mem.loadF32Array(addr, 3*2); @@ -752,21 +752,21 @@ class WebGLInterface { let array = this.mem.loadF32Array(addr, 3*4); this.ctx.uniformMatrix3x4fv(this.uniforms[location], false, array); }, - + /* Vertex attribs */ VertexAttribI4i: (index, x, y, z, w) => { this.assertWebGL2(); this.ctx.vertexAttribI4i(index, x, y, z, w); - }, + }, VertexAttribI4ui: (index, x, y, z, w) => { this.assertWebGL2(); this.ctx.vertexAttribI4ui(index, x, y, z, w); - }, + }, VertexAttribIPointer: (index, size, type, stride, offset) => { this.assertWebGL2(); this.ctx.vertexAttribIPointer(index, size, type, stride, offset); - }, - + }, + /* Writing to the drawing buffer */ VertexAttribDivisor: (index, divisor) => { this.assertWebGL2(); @@ -818,7 +818,7 @@ class WebGLInterface { let id = this.getNewId(this.queries); query.name = id; this.queries[id] = query; - return id; + return id; }, DeleteQuery: (id) => { this.assertWebGL2(); @@ -829,7 +829,7 @@ class WebGLInterface { } }, IsQuery: (query) => { - this.assertWebGL2(); + this.assertWebGL2(); return this.ctx.isQuery(this.queries[query]); }, BeginQuery: (target, query) => { @@ -852,9 +852,9 @@ class WebGLInterface { let id = this.getNewId(this.queries); query.name = id; this.queries[id] = query; - return id; + return id; }, - + /* Sampler Objects */ CreateSampler: () => { this.assertWebGL2(); @@ -862,7 +862,7 @@ class WebGLInterface { let id = this.getNewId(this.samplers); sampler.name = id; this.samplers[id] = sampler; - return id; + return id; }, DeleteSampler: (id) => { this.assertWebGL2(); @@ -873,11 +873,11 @@ class WebGLInterface { } }, IsSampler: (sampler) => { - this.assertWebGL2(); + this.assertWebGL2(); return this.ctx.isSampler(this.samplers[sampler]); }, BindSampler: (unit, sampler) => { - this.assertWebGL2(); + this.assertWebGL2(); this.ctx.bindSampler(unit, this.samplers[Sampler]); }, SamplerParameteri: (sampler, pname, param) => { @@ -888,7 +888,7 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.samplerParameterf(this.samplers[sampler], pname, param); }, - + /* Sync objects */ FenceSync: (condition, flags) => { this.assertWebGL2(); @@ -896,10 +896,10 @@ class WebGLInterface { let id = this.getNewId(this.syncs); sync.name = id; this.syncs[id] = sync; - return id; + return id; }, IsSync: (sync) => { - this.assertWebGL2(); + this.assertWebGL2(); return this.ctx.isSync(this.syncs[sync]); }, DeleteSync: (id) => { @@ -908,7 +908,7 @@ class WebGLInterface { if (obj && id != 0) { this.ctx.deleteSampler(obj); this.syncs[id] = null; - } + } }, ClientWaitSync: (sync, flags, timeout) => { this.assertWebGL2(); @@ -918,8 +918,8 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.waitSync(this.syncs[sync], flags, timeout) ; }, - - + + /* Transform Feedback */ CreateTransformFeedback: () => { this.assertWebGL2(); @@ -927,7 +927,7 @@ class WebGLInterface { let id = this.getNewId(this.transformFeedbacks); transformFeedback.name = id; this.transformFeedbacks[id] = transformFeedback; - return id; + return id; }, DeleteTransformFeedback: (id) => { this.assertWebGL2(); @@ -935,7 +935,7 @@ class WebGLInterface { if (obj && id != 0) { this.ctx.deleteTransformFeedback(obj); this.transformFeedbacks[id] = null; - } + } }, IsTransformFeedback: (tf) => { this.assertWebGL2(); @@ -971,8 +971,8 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.resumeTransformFeedback(); }, - - + + /* Uniform Buffer Objects and Transform Feedback Buffers */ BindBufferBase: (target, index, buffer) => { this.assertWebGL2(); @@ -990,7 +990,7 @@ class WebGLInterface { GetActiveUniformBlockName: (program, uniformBlockIndex, buf_ptr, buf_len, length_ptr) => { this.assertWebGL2(); let name = this.ctx.getActiveUniformBlockName(this.programs[program], uniformBlockIndex); - + let n = Math.min(buf_len, name.length); name = name.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(name)) @@ -1000,7 +1000,7 @@ class WebGLInterface { this.assertWebGL2(); this.ctx.uniformBlockBinding(this.programs[program], uniformBlockIndex, uniformBlockBinding); }, - + /* Vertex Array Objects */ CreateVertexArray: () => { this.assertWebGL2(); @@ -1008,7 +1008,7 @@ class WebGLInterface { let id = this.getNewId(this.vaos); vao.name = id; this.vaos[id] = vao; - return id; + return id; }, DeleteVertexArray: (id) => { this.assertWebGL2(); @@ -1019,11 +1019,11 @@ class WebGLInterface { } }, IsVertexArray: (vertexArray) => { - this.assertWebGL2(); + this.assertWebGL2(); return this.ctx.isVertexArray(this.vaos[vertexArray]); }, BindVertexArray: (vertexArray) => { - this.assertWebGL2(); + this.assertWebGL2(); this.ctx.bindVertexArray(this.vaos[vertexArray]); }, }; @@ -1031,4 +1031,4 @@ class WebGLInterface { }; -export {WebGLInterface}; +export {WebGLInterface}; \ No newline at end of file diff --git a/vendor/wasm/js/dom.odin b/vendor/wasm/js/dom.odin new file mode 100644 index 000000000..9f9f2fa96 --- /dev/null +++ b/vendor/wasm/js/dom.odin @@ -0,0 +1,22 @@ +//+build js wasm32 +package wasm_js_interface + +foreign import dom_lib "odin_dom" + +@(default_calling_convention="contextless") +foreign dom_lib { + get_element_value_f64 :: proc(id: string) -> f64 --- + get_element_min_max :: proc(id: string) -> (min, max: f64) --- + set_element_value :: proc(id: string, value: f64) --- +} + +get_element_value_string :: proc(id: string, buf: []byte) -> string { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="get_element_value_string") + _get_element_value_string :: proc(id: string, buf: []byte) -> int --- + } + n := _get_element_value_string(id, buf) + return string(buf[:n]) + +} diff --git a/vendor/wasm/js/events.odin b/vendor/wasm/js/events.odin new file mode 100644 index 000000000..29104049c --- /dev/null +++ b/vendor/wasm/js/events.odin @@ -0,0 +1,320 @@ +//+build js wasm32 +package wasm_js_interface + +foreign import dom_lib "odin_dom" + +Event_Kind :: enum u32 { + Invalid, + + Load, + Unload, + Error, + Resize, + Visibility_Change, + Fullscreen_Change, + Fullscreen_Error, + + Click, + Double_Click, + Mouse_Move, + Mouse_Over, + Mouse_Out, + Mouse_Up, + Mouse_Down, + + Key_Up, + Key_Down, + Key_Press, + + Scroll, + Wheel, + + Focus, + Submit, + Blur, + Change, + Select, + + Animation_Start, + Animation_End, + Animation_Iteration, + Animation_Cancel, + + Copy, + Cut, + Paste, + + // Drag, + // Drag_Start, + // Drag_End, + // Drag_Enter, + // Drag_Leave, + // Drag_Over, + // Drop, + + Pointer_Cancel, + Pointer_Down, + Pointer_Enter, + Pointer_Leave, + Pointer_Move, + Pointer_Over, + Pointer_Up, + Got_Pointer_Capture, + Lost_Pointer_Capture, + Pointer_Lock_Change, + Pointer_Lock_Error, + + Selection_Change, + Selection_Start, + + Touch_Cancel, + Touch_End, + Touch_Move, + Touch_Start, + + Transition_Start, + Transition_End, + Transition_Run, + Transition_Cancel, + +} +event_kind_string := [Event_Kind]string{ + .Invalid = "", + + .Load = "load", + .Unload = "unload", + .Error = "error", + .Resize = "resize", + .Visibility_Change = "visibilitychange", + .Fullscreen_Change = "fullscreenchange", + .Fullscreen_Error = "fullscreenerror", + + .Click = "click", + .Double_Click = "dblclick", + .Mouse_Move = "mousemove", + .Mouse_Over = "mouseover", + .Mouse_Out = "mouseout", + .Mouse_Up = "mouseup", + .Mouse_Down = "mousedown", + + .Key_Up = "keyup", + .Key_Down = "keydown", + .Key_Press = "keypress", + + .Scroll = "scroll", + .Wheel = "wheel", + + .Focus = "focus", + .Submit = "submit", + .Blur = "blur", + .Change = "change", + .Select = "select", + + .Animation_Start = "animationstart", + .Animation_End = "animationend", + .Animation_Iteration = "animationiteration", + .Animation_Cancel = "animationcancel", + + .Copy = "copy", + .Cut = "cut", + .Paste = "paste", + + // .Drag, = "drag", + // .Drag_Start, = "dragstart", + // .Drag_End, = "dragend", + // .Drag_Enter, = "dragenter", + // .Drag_Leave, = "dragleave", + // .Drag_Over, = "dragover", + // .Drop, = "drop", + + .Pointer_Cancel = "pointercancel", + .Pointer_Down = "pointerdown", + .Pointer_Enter = "pointerenter", + .Pointer_Leave = "pointerleave", + .Pointer_Move = "pointermove", + .Pointer_Over = "pointerover", + .Pointer_Up = "pointerup", + .Got_Pointer_Capture = "gotpointercapture", + .Lost_Pointer_Capture = "lostpointercapture", + .Pointer_Lock_Change = "pointerlockchange", + .Pointer_Lock_Error = "pointerlockerror", + + .Selection_Change = "selectionchange", + .Selection_Start = "selectionstart", + + .Transition_Start = "transitionstart", + .Transition_End = "transitionend", + .Transition_Run = "transitionrun", + .Transition_Cancel = "transitioncancel", + + .Touch_Cancel = "touchcancel", + .Touch_End = "touchend", + .Touch_Move = "touchmove", + .Touch_Start = "touchstart", +} + +Delta_Mode :: enum u32 { + Pixel = 0, + Line = 1, + Page = 2, +} + +Key_Location :: enum u8 { + Standard = 0, + Left = 1, + Right = 2, + Numpad = 3, +} + +KEYBOARD_MAX_KEY_SIZE :: 16 +KEYBOARD_MAX_CODE_SIZE :: 16 + +Event_Target_Kind :: enum u32 { + Element = 0, + Document = 1, + Window = 2, +} + +Event_Phase :: enum u8 { + None = 0, + Capturing_Phase = 1, + At_Target = 2, + Bubbling_Phase = 3, +} + + +Event :: struct { + kind: Event_Kind, + target_kind: Event_Target_Kind, + current_target_kind: Event_Target_Kind, + id: string, + timestamp: f64, + + phase: Event_Phase, + bubbles: bool, + cancelable: bool, + composed: bool, + is_composing: bool, + is_trusted: bool, + + using data: struct #raw_union #align 8 { + scroll: struct { + delta: [2]f64, + }, + visibility_change: struct { + is_visible: bool, + }, + wheel: struct { + delta: [3]f64, + delta_mode: Delta_Mode, + }, + + key: struct { + key: string, + code: string, + location: Key_Location, + + ctrl: bool, + shift: bool, + alt: bool, + meta: bool, + + repeat: bool, + + _key_buf: [KEYBOARD_MAX_KEY_SIZE]byte, + _code_buf: [KEYBOARD_MAX_KEY_SIZE]byte, + }, + + mouse: struct { + screen: [2]i64, + client: [2]i64, + offset: [2]i64, + page: [2]i64, + movement: [2]i64, + using pos: [2]i64, + + ctrl: bool, + shift: bool, + alt: bool, + meta: bool, + + button: i16, + buttons: bit_set[0..<16; u16], + }, + }, + + + user_data: rawptr, + callback: proc(e: Event), +} + +@(default_calling_convention="contextless") +foreign dom_lib { + event_stop_propagation :: proc() --- + event_stop_immediate_propagation :: proc() --- + event_prevent_default :: proc() --- +} + +add_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="add_event_listener") + _add_event_listener :: proc(id: string, name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool --- + } + // TODO: Pointer_Lock_Change etc related stuff for all different browsers + return _add_event_listener(id, event_kind_string[kind], kind, user_data, callback, use_capture) +} + +remove_event_listener :: proc(id: string, kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="remove_event_listener") + _remove_event_listener :: proc(id: string, name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool --- + } + return _remove_event_listener(id, event_kind_string[kind], user_data, callback) +} + +add_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event), use_capture := false) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="add_window_event_listener") + _add_window_event_listener :: proc(name: string, name_code: Event_Kind, user_data: rawptr, callback: proc "odin" (Event), use_capture: bool) -> bool --- + } + return _add_window_event_listener(event_kind_string[kind], kind, user_data, callback, use_capture) +} + +remove_window_event_listener :: proc(kind: Event_Kind, user_data: rawptr, callback: proc(e: Event)) -> bool { + @(default_calling_convention="contextless") + foreign dom_lib { + @(link_name="remove_window_event_listener") + _remove_window_event_listener :: proc(name: string, user_data: rawptr, callback: proc "odin" (Event)) -> bool --- + } + return _remove_window_event_listener(event_kind_string[kind], user_data, callback) +} + +remove_event_listener_from_event :: proc(e: Event) -> bool { + if e.id == "" { + return remove_window_event_listener(e.kind, e.user_data, e.callback) + } + return remove_event_listener(e.id, e.kind, e.user_data, e.callback) +} + + + + +@(export, link_name="odin_dom_do_event_callback") +do_event_callback :: proc(user_data: rawptr, callback: proc(e: Event)) { + @(default_calling_convention="contextless") + foreign dom_lib { + init_event_raw :: proc(e: ^Event) --- + } + + if callback != nil { + event := Event{ + user_data = user_data, + callback = callback, + } + init_event_raw(&event) + callback(event) + } +} \ No newline at end of file diff --git a/vendor/wasm/js/runtime.js b/vendor/wasm/js/runtime.js deleted file mode 100644 index 42ee257eb..000000000 --- a/vendor/wasm/js/runtime.js +++ /dev/null @@ -1,154 +0,0 @@ -class WasmMemoryInterface { - constructor() { - this.memory = null; - } - - setMemory(memory) { - this.memory = memory; - } - - get mem() { - return new DataView(this.memory.buffer); - } - - - loadF32Array(addr, len) { - let array = new Float32Array(this.memory.buffer, addr, len); - return array; - } - loadU32Array(addr, len) { - let array = new Uint32Array(this.memory.buffer, addr, len); - return array; - } - loadI32Array(addr, len) { - let array = new Int32Array(this.memory.buffer, addr, len); - return array; - } - - - loadU8(addr) { return this.mem.getUint8 (addr, true); } - loadI8(addr) { return this.mem.getInt8 (addr, true); } - loadU16(addr) { return this.mem.getUint16 (addr, true); } - loadI16(addr) { return this.mem.getInt16 (addr, true); } - loadU32(addr) { return this.mem.getUint32 (addr, true); } - loadI32(addr) { return this.mem.getInt32 (addr, true); } - loadU64(addr) { - const lo = this.mem.getUint32(addr + 0, true); - const hi = this.mem.getUint32(addr + 4, true); - return lo + hi*4294967296; - }; - loadI64(addr) { - // TODO(bill): loadI64 correctly - const lo = this.mem.getUint32(addr + 0, true); - const hi = this.mem.getUint32(addr + 4, true); - return lo + hi*4294967296; - }; - loadF32(addr) { return this.mem.getFloat32(addr, true); } - loadF64(addr) { return this.mem.getFloat64(addr, true); } - loadInt(addr) { return this.mem.getInt32 (addr, true); } - loadUint(addr) { return this.mem.getUint32 (addr, true); } - - loadPtr(addr) { return this.loadUint(addr); } - - loadBytes(ptr, len) { - return new Uint8Array(this.memory.buffer, ptr, len); - } - - loadString(ptr, len) { - const bytes = this.loadBytes(ptr, len); - return new TextDecoder("utf-8").decode(bytes); - } - - storeU8(addr, value) { this.mem.setUint8 (addr, value, true); } - storeI8(addr, value) { this.mem.setInt8 (addr, value, true); } - storeU16(addr, value) { this.mem.setUint16 (addr, value, true); } - storeI16(addr, value) { this.mem.setInt16 (addr, value, true); } - storeU32(addr, value) { this.mem.setUint32 (addr, value, true); } - storeI32(addr, value) { this.mem.setInt32 (addr, value, true); } - storeU64(addr, value) { - this.mem.setUint32(addr + 0, value, true); - this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true); - } - storeI64(addr, value) { - // TODO(bill): storeI64 correctly - this.mem.setUint32(addr + 0, value, true); - this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true); - } - storeF32(addr, value) { this.mem.setFloat32(addr, value, true); } - storeF64(addr, value) { this.mem.setFloat64(addr, value, true); } - storeInt(addr, value) { this.mem.setInt32 (addr, value, true); } - storeUint(addr, value) { this.mem.setUint32 (addr, value, true); } -}; - -function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { - const MAX_INFO_CONSOLE_LINES = 512; - let infoConsoleLines = new Array(); - const addConsoleLine = (line) => { - if (line === undefined) { - return; - } - if (line.endsWith("\n")) { - line = line.substring(0, line.length-1); - } else if (infoConsoleLines.length > 0) { - let prev_line = infoConsoleLines.pop(); - line = prev_line.concat(line); - } - infoConsoleLines.push(line); - - if (infoConsoleLines.length > MAX_INFO_CONSOLE_LINES) { - infoConsoleLines.shift(); - } - - let data = ""; - for (let i = 0; i < infoConsoleLines.length; i++) { - if (i != 0) { - data = data.concat("\n"); - } - data = data.concat(infoConsoleLines[i]); - } - - if (consoleElement !== undefined) { - let info = consoleElement; - info.innerHTML = data; - info.scrollTop = info.scrollHeight; - } - }; - - return { - "env": {}, - "odin_env": { - write: (fd, ptr, len) => { - const str = wasmMemoryInterface.loadString(ptr, len); - if (fd == 1) { - addConsoleLine(str); - return; - } else if (fd == 2) { - addConsoleLine(str); - return; - } else { - throw new Error("Invalid fd to 'write'" + stripNewline(str)); - } - }, - trap: () => { throw new Error() }, - alert: (ptr, len) => { alert(wasmMemoryInterface.loadString(ptr, len)) }, - abort: () => { Module.abort() }, - evaluate: (str_ptr, str_len) => { eval.call(null, wasmMemoryInterface.loadString(str_ptr, str_len)); }, - - time_now: () => { - return performance.now() * 1e6; - }, - - sqrt: (x) => Math.sqrt(x), - sin: (x) => Math.sin(x), - cos: (x) => Math.cos(x), - pow: (x) => Math.pow(x), - fmuladd: (x, y, z) => x*y + z, - ln: (x) => Math.log(x), - exp: (x) => Math.exp(x), - ldexp: (x) => Math.ldexp(x), - }, - }; -} - - -export {WasmMemoryInterface, odinSetupDefaultImports}; \ No newline at end of file diff --git a/vendor/wasm/js/runtime.mjs b/vendor/wasm/js/runtime.mjs new file mode 100644 index 000000000..c9d0a4e34 --- /dev/null +++ b/vendor/wasm/js/runtime.mjs @@ -0,0 +1,372 @@ +class WasmMemoryInterface { + constructor() { + this.memory = null; + this.exports = null; + } + + setMemory(memory) { + this.memory = memory; + } + + setExports(exports) { + this.exports = exports; + this.listenerMap = {}; + } + + get mem() { + return new DataView(this.memory.buffer); + } + + + loadF32Array(addr, len) { + let array = new Float32Array(this.memory.buffer, addr, len); + return array; + } + loadF64Array(addr, len) { + let array = new Float64Array(this.memory.buffer, addr, len); + return array; + } + loadU32Array(addr, len) { + let array = new Uint32Array(this.memory.buffer, addr, len); + return array; + } + loadI32Array(addr, len) { + let array = new Int32Array(this.memory.buffer, addr, len); + return array; + } + + + loadU8(addr) { return this.mem.getUint8 (addr, true); } + loadI8(addr) { return this.mem.getInt8 (addr, true); } + loadU16(addr) { return this.mem.getUint16 (addr, true); } + loadI16(addr) { return this.mem.getInt16 (addr, true); } + loadU32(addr) { return this.mem.getUint32 (addr, true); } + loadI32(addr) { return this.mem.getInt32 (addr, true); } + loadU64(addr) { + const lo = this.mem.getUint32(addr + 0, true); + const hi = this.mem.getUint32(addr + 4, true); + return lo + hi*4294967296; + }; + loadI64(addr) { + // TODO(bill): loadI64 correctly + const lo = this.mem.getUint32(addr + 0, true); + const hi = this.mem.getUint32(addr + 4, true); + return lo + hi*4294967296; + }; + loadF32(addr) { return this.mem.getFloat32(addr, true); } + loadF64(addr) { return this.mem.getFloat64(addr, true); } + loadInt(addr) { return this.mem.getInt32 (addr, true); } + loadUint(addr) { return this.mem.getUint32 (addr, true); } + + loadPtr(addr) { return this.loadUint(addr); } + + loadBytes(ptr, len) { + return new Uint8Array(this.memory.buffer, ptr, len); + } + + loadString(ptr, len) { + const bytes = this.loadBytes(ptr, len); + return new TextDecoder("utf-8").decode(bytes); + } + + storeU8(addr, value) { this.mem.setUint8 (addr, value, true); } + storeI8(addr, value) { this.mem.setInt8 (addr, value, true); } + storeU16(addr, value) { this.mem.setUint16 (addr, value, true); } + storeI16(addr, value) { this.mem.setInt16 (addr, value, true); } + storeU32(addr, value) { this.mem.setUint32 (addr, value, true); } + storeI32(addr, value) { this.mem.setInt32 (addr, value, true); } + storeU64(addr, value) { + this.mem.setUint32(addr + 0, value, true); + this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true); + } + storeI64(addr, value) { + // TODO(bill): storeI64 correctly + this.mem.setUint32(addr + 0, value, true); + this.mem.setUint32(addr + 4, Math.floor(value / 4294967296), true); + } + storeF32(addr, value) { this.mem.setFloat32(addr, value, true); } + storeF64(addr, value) { this.mem.setFloat64(addr, value, true); } + storeInt(addr, value) { this.mem.setInt32 (addr, value, true); } + storeUint(addr, value) { this.mem.setUint32 (addr, value, true); } +}; + +function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { + const MAX_INFO_CONSOLE_LINES = 512; + let infoConsoleLines = new Array(); + const addConsoleLine = (line) => { + if (line === undefined) { + return; + } + if (line.endsWith("\n")) { + line = line.substring(0, line.length-1); + } else if (infoConsoleLines.length > 0) { + let prev_line = infoConsoleLines.pop(); + line = prev_line.concat(line); + } + infoConsoleLines.push(line); + + if (infoConsoleLines.length > MAX_INFO_CONSOLE_LINES) { + infoConsoleLines.shift(); + } + + let data = ""; + for (let i = 0; i < infoConsoleLines.length; i++) { + if (i != 0) { + data = data.concat("\n"); + } + data = data.concat(infoConsoleLines[i]); + } + + if (consoleElement !== undefined) { + let info = consoleElement; + info.innerHTML = data; + info.scrollTop = info.scrollHeight; + } + }; + + let event_temp_data = {}; + + return { + "env": {}, + "odin_env": { + write: (fd, ptr, len) => { + const str = wasmMemoryInterface.loadString(ptr, len); + if (fd == 1) { + addConsoleLine(str); + return; + } else if (fd == 2) { + addConsoleLine(str); + return; + } else { + throw new Error("Invalid fd to 'write'" + stripNewline(str)); + } + }, + trap: () => { throw new Error() }, + alert: (ptr, len) => { alert(wasmMemoryInterface.loadString(ptr, len)) }, + abort: () => { Module.abort() }, + evaluate: (str_ptr, str_len) => { eval.call(null, wasmMemoryInterface.loadString(str_ptr, str_len)); }, + + time_now: () => { + return performance.now() * 1e6; + }, + + sqrt: (x) => Math.sqrt(x), + sin: (x) => Math.sin(x), + cos: (x) => Math.cos(x), + pow: (x) => Math.pow(x), + fmuladd: (x, y, z) => x*y + z, + ln: (x) => Math.log(x), + exp: (x) => Math.exp(x), + ldexp: (x) => Math.ldexp(x), + }, + "odin_dom": { + init_event_raw: (ep) => { + const W = 4; + let offset = ep; + let off = (amount, alignment) => { + if (alignment === undefined) { + alignment = amount; + } + if (offset % alignment != 0) { + offset += alignment - (offset%alignment); + } + let x = offset; + offset += amount; + return x; + }; + + let wmi = wasmMemoryInterface; + + let e = event_temp_data.event; + + wmi.storeU32(off(4), event_temp_data.name_code); + if (e.target == document) { + wmi.storeU32(off(4), 1); + } else if (e.target == window) { + wmi.storeU32(off(4), 2); + } else { + wmi.storeU32(off(4), 0); + } + if (e.currentTarget == document) { + wmi.storeU32(off(4), 1); + } else if (e.currentTarget == window) { + wmi.storeU32(off(4), 2); + } else { + wmi.storeU32(off(4), 0); + } + + wmi.storeUint(off(W), event_temp_data.id_ptr); + wmi.storeUint(off(W), event_temp_data.id_len); + + wmi.storeF64(off(8), e.timeStamp*1e-3); + + wmi.storeU8(off(1), e.eventPhase); + wmi.storeU8(off(1), !!e.bubbles); + wmi.storeU8(off(1), !!e.cancelable); + wmi.storeU8(off(1), !!e.composed); + wmi.storeU8(off(1), !!e.isComposing); + wmi.storeU8(off(1), !!e.isTrusted); + + off(0, 8); + if (e instanceof MouseEvent) { + wmi.storeI64(off(8), e.screenX); + wmi.storeI64(off(8), e.screenY); + wmi.storeI64(off(8), e.clientX); + wmi.storeI64(off(8), e.clientY); + wmi.storeI64(off(8), e.offsetX); + wmi.storeI64(off(8), e.offsetY); + wmi.storeI64(off(8), e.pageX); + wmi.storeI64(off(8), e.pageY); + wmi.storeI64(off(8), e.movementX); + wmi.storeI64(off(8), e.movementY); + wmi.storeI64(off(8), e.x); + wmi.storeI64(off(8), e.y); + + wmi.storeU8(off(1), !!e.ctrlKey); + wmi.storeU8(off(1), !!e.shiftKey); + wmi.storeU8(off(1), !!e.altKey); + wmi.storeU8(off(1), !!e.metaKey); + + wmi.storeI16(off(2), e.button); + wmi.storeU16(off(2), e.buttons); + } else if (e instanceof KeyboardEvent) { + let keyOffset = off(W*2, W); + let codeOffet = off(W*2, W); + wmi.storeU8(off(1), e.location); + + wmi.storeU8(off(1), !!e.ctrlKey); + wmi.storeU8(off(1), !!e.shiftKey); + wmi.storeU8(off(1), !!e.altKey); + wmi.storeU8(off(1), !!e.metaKey); + + wmi.storeU8(off(1), !!e.repeat); + } else if (e instanceof WheelEvent) { + wmi.storeF64(off(8), e.deltaX); + wmi.storeF64(off(8), e.deltaY); + wmi.storeF64(off(8), e.deltaZ); + wmi.storeU32(off(4), e.deltaMode); + } else if (e instanceof Event) { + if ('scrollX' in e) { + wmi.storeF64(off(8), e.scrollX); + wmi.storeF64(off(8), e.scrollY); + } + } + }, + + add_event_listener: (id_ptr, id_len, name_ptr, name_len, name_code, data, callback, use_capture) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let name = wasmMemoryInterface.loadString(name_ptr, name_len); + let element = document.getElementById(id); + if (element == undefined) { + return false; + } + + let listener = (e) => { + const odin_ctx = wasmMemoryInterface.exports.default_context_ptr(); + event_temp_data.id_ptr = id_ptr; + event_temp_data.id_len = id_len; + event_temp_data.event = e; + event_temp_data.name_code = name_code; + // console.log(e); + wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx); + }; + wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener; + element.addEventListener(name, listener, !!use_capture); + return true; + }, + + remove_event_listener: (id_ptr, id_len, name_ptr, name_len, data, callback) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let name = wasmMemoryInterface.loadString(name_ptr, name_len); + let element = document.getElementById(id); + if (element == undefined) { + return false; + } + + let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}]; + if (listener == undefined) { + return false; + } + element.removeEventListener(name, listener); + return true; + }, + + + add_window_event_listener: (name_ptr, name_len, name_code, data, callback, use_capture) => { + let name = wasmMemoryInterface.loadString(name_ptr, name_len); + let element = window; + let listener = (e) => { + const odin_ctx = wasmMemoryInterface.exports.default_context_ptr(); + event_temp_data.id_ptr = 0; + event_temp_data.id_len = 0; + event_temp_data.event = e; + event_temp_data.name_code = name_code; + // console.log(e); + wasmMemoryInterface.exports.odin_dom_do_event_callback(data, callback, odin_ctx); + }; + wasmMemoryInterface.listenerMap[{data: data, callback: callback}] = listener; + element.addEventListener(name, listener, !!use_capture); + return true; + }, + + remove_window_event_listener: (name_ptr, name_len, data, callback) => { + let name = wasmMemoryInterface.loadString(name_ptr, name_len); + let element = window; + let listener = wasmMemoryInterface.listenerMap[{data: data, callback: callback}]; + if (listener == undefined) { + return false; + } + element.removeEventListener(name, listener); + return true; + }, + + event_stop_propagation: () => { + if (event_temp_data && event_temp_data.event) { + event_temp_data.event.eventStopPropagation(); + } + }, + event_stop_immediate_propagation: () => { + if (event_temp_data && event_temp_data.event) { + event_temp_data.event.eventStopImmediatePropagation(); + } + }, + event_prevent_default: () => { + if (event_temp_data && event_temp_data.event) { + event_temp_data.event.eventPreventDefault(); + } + }, + + get_element_value_f64: (id_ptr, id_len) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let element = document.getElementById(id); + return element.value; + }, + get_element_value_string: (id_ptr, id_len, buf_ptr, buf_len) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let element = document.getElementById(id); + let str = element.value; + if (buf_len > 0 && buf_ptr) { + let n = Math.min(buf_len, str.length); + str = str.substring(0, n); + this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(str)) + return n; + } + return 0; + }, + get_element_min_max: (ptr_array2_f64, id_ptr, id_len) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + let element = document.getElementById(id); + let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2); + values[0] = element.min; + values[1] = element.max; + }, + set_element_value: (id_ptr, id_len, value) => { + let id = wasmMemoryInterface.loadString(id_ptr, id_len); + document.getElementById(id).value = value; + }, + }, + }; +} + + +export {WasmMemoryInterface, odinSetupDefaultImports}; \ No newline at end of file diff --git a/vendor/wasm/loader/loader.mjs b/vendor/wasm/loader/loader.mjs new file mode 100644 index 000000000..1e4acbdf3 --- /dev/null +++ b/vendor/wasm/loader/loader.mjs @@ -0,0 +1,63 @@ +import {WasmMemoryInterface, odinSetupDefaultImports} from "../js/runtime.mjs"; +import {WebGLInterface} from "../WebGL/runtime.mjs"; + +export async function runWasmCanvas(wasmPath, webglCanvasElement, consoleElement, extraForeignImports) { + let wasmMemoryInterface = new WasmMemoryInterface(); + + let imports = odinSetupDefaultImports(wasmMemoryInterface, consoleElement); + let exports = {}; + + if (webglCanvasElement !== undefined) { + let gl_context = new WebGLInterface( + wasmMemoryInterface, + webglCanvasElement, + {antialias: false}, + ); + if (!gl_context.ctx) { + return "WebGL is not available."; + } + imports["webgl"] = gl_context.getWebGL1Interface(); + imports["webgl2"] = gl_context.getWebGL2Interface(); + } + + if (extraForeignImports !== undefined) { + imports = { + ...imports, + ...extraForeignImports, + }; + } + + const response = await fetch(wasmPath); + const file = await response.arrayBuffer(); + const wasm = await WebAssembly.instantiate(file, imports); + exports = wasm.instance.exports; + wasmMemoryInterface.setExports(exports); + wasmMemoryInterface.setMemory(exports.memory); + + exports._start(); + + if (exports.step) { + const odin_ctx = exports.default_context_ptr(); + + let prevTimeStamp = undefined; + const step = (currTimeStamp) => { + if (prevTimeStamp == undefined) { + prevTimeStamp = currTimeStamp; + } + + const dt = (currTimeStamp - prevTimeStamp)*0.001; + prevTimeStamp = currTimeStamp; + exports.step(dt, odin_ctx); + window.requestAnimationFrame(step); + }; + + window.requestAnimationFrame(step); + } + + exports._end(); + + return; +}; + + +export {runWasmCanvas}; From 205aa10b88c7e089dd6ae4bd76a768f4de682fe3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 May 2022 22:08:14 +0100 Subject: [PATCH 181/245] Improve events handling --- vendor/wasm/js/events.odin | 2 -- vendor/wasm/js/runtime.mjs | 39 +++++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/vendor/wasm/js/events.odin b/vendor/wasm/js/events.odin index 29104049c..93ea94ede 100644 --- a/vendor/wasm/js/events.odin +++ b/vendor/wasm/js/events.odin @@ -182,7 +182,6 @@ Event_Phase :: enum u8 { Bubbling_Phase = 3, } - Event :: struct { kind: Event_Kind, target_kind: Event_Target_Kind, @@ -231,7 +230,6 @@ Event :: struct { offset: [2]i64, page: [2]i64, movement: [2]i64, - using pos: [2]i64, ctrl: bool, shift: bool, diff --git a/vendor/wasm/js/runtime.mjs b/vendor/wasm/js/runtime.mjs index c9d0a4e34..4306c0f32 100644 --- a/vendor/wasm/js/runtime.mjs +++ b/vendor/wasm/js/runtime.mjs @@ -94,7 +94,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { const MAX_INFO_CONSOLE_LINES = 512; let infoConsoleLines = new Array(); const addConsoleLine = (line) => { - if (line === undefined) { + if (!line) { return; } if (line.endsWith("\n")) { @@ -117,7 +117,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { data = data.concat(infoConsoleLines[i]); } - if (consoleElement !== undefined) { + if (consoleElement) { let info = consoleElement; info.innerHTML = data; info.scrollTop = info.scrollHeight; @@ -165,7 +165,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { let offset = ep; let off = (amount, alignment) => { if (alignment === undefined) { - alignment = amount; + alignment = Math.min(amount, W); } if (offset % alignment != 0) { offset += alignment - (offset%alignment); @@ -207,7 +207,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeU8(off(1), !!e.isComposing); wmi.storeU8(off(1), !!e.isTrusted); - off(0, 8); + let base = off(0, 8); if (e instanceof MouseEvent) { wmi.storeI64(off(8), e.screenX); wmi.storeI64(off(8), e.screenY); @@ -219,8 +219,6 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { wmi.storeI64(off(8), e.pageY); wmi.storeI64(off(8), e.movementX); wmi.storeI64(off(8), e.movementY); - wmi.storeI64(off(8), e.x); - wmi.storeI64(off(8), e.y); wmi.storeU8(off(1), !!e.ctrlKey); wmi.storeU8(off(1), !!e.shiftKey); @@ -339,30 +337,37 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { get_element_value_f64: (id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let element = document.getElementById(id); - return element.value; + return element ? element.value : 0; }, get_element_value_string: (id_ptr, id_len, buf_ptr, buf_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let element = document.getElementById(id); - let str = element.value; - if (buf_len > 0 && buf_ptr) { - let n = Math.min(buf_len, str.length); - str = str.substring(0, n); - this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(str)) - return n; + if (element) { + let str = element.value; + if (buf_len > 0 && buf_ptr) { + let n = Math.min(buf_len, str.length); + str = str.substring(0, n); + this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(str)) + return n; + } } return 0; }, get_element_min_max: (ptr_array2_f64, id_ptr, id_len) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); let element = document.getElementById(id); - let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2); - values[0] = element.min; - values[1] = element.max; + if (element) { + let values = wasmMemoryInterface.loadF64Array(ptr_array2_f64, 2); + values[0] = element.min; + values[1] = element.max; + } }, set_element_value: (id_ptr, id_len, value) => { let id = wasmMemoryInterface.loadString(id_ptr, id_len); - document.getElementById(id).value = value; + let element = document.getElementById(id); + if (element) { + element.value = value; + } }, }, }; From 0d4e710b965cb0808f99f6d0fa769f554000c20d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 May 2022 23:32:23 +0100 Subject: [PATCH 182/245] Add `vendor:ggpo` --- vendor/README.md | 8 + vendor/ggpo/GGPO.lib | Bin 0 -> 3403590 bytes vendor/ggpo/LICENSE | 21 ++ vendor/ggpo/ggpo.odin | 526 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 555 insertions(+) create mode 100644 vendor/ggpo/GGPO.lib create mode 100644 vendor/ggpo/LICENSE create mode 100644 vendor/ggpo/ggpo.odin diff --git a/vendor/README.md b/vendor/README.md index 14e91ca89..628ea2727 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -119,6 +119,14 @@ See also LICENSE.txt in the `portmidi` directory itself. See also LICENSE in the `ENet` directory itself. +## GGPO + +[GGPO](https://www.ggpo.net/) GGPO Rollback Networking SDK. + +Zero-input latency networking library for peer-to-peer games. + +See also LICENSE in the `GGPO` directory itself. + ## Botan [Botan](https://botan.randombit.net/) Crypto and TLS library. diff --git a/vendor/ggpo/GGPO.lib b/vendor/ggpo/GGPO.lib new file mode 100644 index 0000000000000000000000000000000000000000..70feb57da1965de1176af8f87d21b35295c86fa8 GIT binary patch literal 3403590 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%0A2T+3(9M<4!8LlG0!OO+R*VoU* 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

Nd!lVgGiX`O)H-AP4Q1rWjDrP=6-4lGe$N6-R z@#!9gA+j$HTRLH@G zo(j)`t-pxVdP1oX=H-hp>jOcN&>+vqz1@N)a7U5e6Df zTBqRc&zKFey&;+z?5(8=JD>4&G%16f{}dF0;DYECIGT|>;sf!5Bgi-gtCyf8nG?dK z31SfK=r?@+j18bMOK49PX%3=O8B5rK~8%?hBRX0yUhcm5U4+du<# z8^9tP6n47tuV~&568XpjQuC3=#}Ta6$`kC~zmVPmh(nrtK}}MB#s*N!796%9elUZY zFTb0vH@~hI+`U|k3=Fv4>kSTca8T~_;s-e_6hy$>=m&NqH>9Be;*jP>876S^U788n zdIs@937Fqa_Zh$LQ@9&tnHU(<)`IHr4GIhmmY~>v#^0h;7}}y#xbrF4SvsKD1_j^- z1yJ(*2=3;8#39Xz`Vc4T!JG)<2Q#Ss<#*Hl&9D0l?nDES6Su;g2oA^J zNa6Skza#&F9cc)0B#1+_Bg;YMQ8}dfTnuYIgZQ9oN5D<@jDYTG0a$rd0ct^?7U*c+ z3o4KHD!|I4Qv#6k$R3nJ&j`TEBZ$gSkaDE*=$rtkJgS7`9T0~!xBi5<^#{zYAbv1| znwX%Qu85$nuprE>zd-qWAt*riDljxSf?Osd2%231H+6&G> zAHX^20}q3hxFE=(zab6!5j+W2Q#S23cBe^3+hV29m)WT`3C}fLBYh( z06O?&r?lXT=A+0C+bMVTcf3vnulL$p)lL3s)^kL}OcfHJQg%%J8a=%(u_sOtfDDric3r-xui z^9fLdFX92u?}G^z@FahmlhRI4ywdU*+8IGJM!2=3O3TY&=x4&OA5|KQerEjoQKjXP z=U%-aYzev(4@LQV*|=0doY7qn4p_(sGx2LJkUY&>);k3s3qnAoo!(O z6$&6x2&1D(SpeK3426aMQgAV`RAFZbx`+>?6AtODg@gS7nz0XI(gblx^TR>N=;{I3 z@Fs{K%%B!6=%yPbs2d6Q18Cq~EldzH5flI_-=e_I3hihVZV6ch- zI}9{7AHt*w;*jRBV-SZOg*gnw2Tg1Xy6MIV>c+wyb{sS{6fL+HWM@Ml$YF5^$Lx$n zuzjHJN&vg-1f<0W;t=gFM{a+{hMU~r*3=blXln|@4`xuCB;=+$QAl@!5UfVH#SNL* zY5)xrIkY(n?VKpo<|q^jVoeb0Xuhlv3L<%tAHdY?6 z+ZcGDZUgay8Pt{tx#=zz(p?018ygSQZIR%fR-^FF#X=p8!l50F!aElUbu?cEx$UZg z4@8*B5j3e{wG`|&b{??XKpfKCCdUVMn*<-!Z6JOygPOjuo35U)uCB1Ijxa3f6d+0! zA(Rq?Qif0}5K0w7sq--~s2K}`vJv<^WrvPNVKpP+(2nNGJUexTVSdtqv3!g=8ihgA z`x+pPCc?%|LJAB@)>g1ul@lmV#J5;DJfkDB-4(={9hz&apL7~P0 z(`OEIh#k}+mV68h5H*l=W*`j816CkqOqw7LY3a-bk}~YT&huw%0P%wv)SQIfbRC6t z9fWo5;pxl`qSPHic|a&HkgMGw;qnC|rb)SR(NTX>@^Tga@c2 zD0sjD>I&1a(+$RgYxMyIfeT0&(usBk2Z1jn2tXXtg1|}+oYlTO4LnPPgGYI?z%{jwYs7m%{LWx>Va(6nIw2afx!qw zf+Spv({^O^^U-?kRw{CkN&p5I>kf%}mry*A(uUB8Z|AP}Et7?lcwcXuhpr zuto8f0(d&os6|l_6h@^WH(Q9dC<;O*D9ypnD}zKGh(nsw>L9jO!JG!-2Q#QyiMr`p z!kyLtQPc!-nvLjAOB_yX206_J;WTTo(^?=-193=mS}(-b4w%zG{9pz(dr>!CJ5gO* zxa;~s*4m18G~ZR&X$P`hXNuw-1qLG!2@0_Zpr~^IyJaGj8N#Fq5+Kbzvmox73Ud#L zAIzZUEb6A~B&zEOch4M$_!!B1PPGlo@EgCEP}ZQ#1Cdr za}#ybb%i@-1w_#*P}F&d?sOIHXuhvtu+8xvXhE_NgHfBK5GagRgWT*P+U6((X-&C< zowo)Obs!FDPTK;pbpy<4AU>#1CF-W@33u8yh@u@Jr}>EP^u*z`ogkpqy%K>T0^HGfezT|ZG>U%2azf~@rw1vNBx`hjfMndW#&fx!qwfhZaEHRhA?S@1W0qw1&Di2!`uVn2Q#Pzi@NCsiRuQz-E#@#o4o@j*Q^Q8(RCxMS`?6g>b%U4-b)P|=R&hYAKe8XrJb z5y2WP4?%8@5bbCbhO|$@!OnXGi8>I6G^f3S*!m3SG!Q?SK`lzuO*azmv^Nk%??6tA z5#1Sy!)fn9PK!Y}EgI~!4-lt;IHWo4C&bn-FsFg|pe~oFn{J$_ZY&$4pqQGDTB0;I@4=Cyqz;5{qWri?mf&@r&51Tx=9m6OOZO4H4!3=82qHelL zqPmH2_i)HFFzif(xF-pVdpPA87_3sj?%{$mLzpx{0;IV|2I3wGn0r9{Up+TAa2^34RQm_ReGS{$pt$_AIc12(gX>R z<{Wc~bBtlm0r7(w)Cxr1bo1eEv4kkH28C3S=+1m_g{;%jJduaNphZy-)>g0qIk^Z_ z1wq;hg<$8|LP83}APubxYu`^8i^}0T0^wFXf)-Fi{oI=JhS zLDtrR3w4N_cGiR30CQCeD0mvdPDzC_Lzpx{0;D-77vh{um~%kL8C-DcfQADY3_2QxVP$#|$jNP>q5@K;w}PEl3<)U^hcu_vKx{3CISs@Q zW>D)Ab<^z>)$M@0t`1~v2e_buxM^o6$PF-8)q{ek8|;(@C^Ljf6C^;Ib9x}o>3}&0 z#1Cdr>l1a;?S;Fg4-`adqI*HTx`t%XxLL1gNApwAuS1|3jukRcRA`sjcLNgP3h zRX^Bq{g7}1aY%F6bcn+y!yE?U2Q#Qm7Io8|1b5g>ki)c)9X5%u!=`{8HVfh~5Qj8} zErK{~9?W4NelUaD3{f}T>2QZF0XYmM#HNdOG(X25Vl%-GTMBU)h(nsg)b_C+E{V<1t_`wWnD@5INmy7BygS+h*$Zh(fkcDZP zp!C07v`Gju_z~J9Sg>=MXh-vFMC9HC569nB0Id&eI1b95E5Qyu0cD0TX@UeubL>Tk zW6!`G3*rYesI3!q(_Jg7y9Vyq%OJ-ZBRh62s$npy9w^t2O!6ygzRQi$8HksXnu<$WFLZDxE1W!M^Gkc;k+mb zD|Nub^sga~eFk$Zh!0vRDe9)XQ&e{c+_7&#jztOCov4o8fyc4$KrY-3cI7mS>ZW@H?ou`d2GG#ZUeNOMhI~-&IwIQ9{1FuC6T!91 zZE$wFt>A;SQQ#QZaqJ47mX>ZW@R?l2jU!wQfcc8;*aE`S{-3vn2TLz=_X zAP!T6ISj-PW>C8->ZW@|RQEF6Z5klA*+bJ^F(@{#h_)yxf`{}%TNDL%UKZ_W{)&j) zyWq&Z3n?o#6&M(-u7Mq@1!aaXX@UeubF4AMv3fAag80Dp!QJIP4|JQ?tQppoj{H) zLw4)~RL9=O<5*{q3m<_U>jGtlFlmAWNOPBIVcT0742yL35xVd;2eD)9O?HJe85ZpA-mt6gB|A&NuMANX$}jAI4l_EFc3eO zLG87uo9-*P!y-Wr^FnsmE5Z(Y19n&x#9<%~X%0(*I4ln4Fc3eOLG6R6o9=tK!%{#F zt3r0zd%_O;2zFR1#9<%~X%5SSI4l$9Fc2TKMorXB_p7Mx7r5IBKyLGgrn_oTYp(923wCThlo`UL2@)X9u^kY{Hp3hX;s-OR zF^Re9GK%Rkh{5L7xH$6kEmUh#hOY1B z06T6vBz=N7q&aLp#9^~x4g>Ln8Ps^h+;q9&4qFIvSQN6uxCuLq7woV_5Ql*{q&aLA z#9_-|4g>Ln8Po*D+;j!t4qF3qSPQbl1PD7!2<))65Ql*{q&aLG#9Ln8PvqZ z+;qjnbVcEA+W~T0JT%=kgJM%mtfNU8JZB#YTG$~f*3sOGh}^5-9DNm%qj!Q5n*`XQ zyP(VvCQXn4X^uS%aqK>rV?lh-Dnv0iT^TW5X}DvLf*hNS>{uC8$4cXI>@koF<-m?T z4rPWgX@UeubL<6(V^6~z3*rYes40uN=_-loD#9Im3FO!=WXCF@I#v;nV=seTr~-EE z6(}==NfRVMnqz$w!L4o&MQE!V#1Cdr(-3phRfoIOPmzH^4JAjbi*+=&BO?7FIMTs6 z8flNVCfIrYir{uPh(nsw!XZuzhB*zy4`xu)6?4}8wuB%uwwYK*b0;E>Q8IR+A_Ie!CD^4!P-X~|CP;uZ z*H%MZTLyD2h#${r3BhiEu}>2 z_z2umT_rbN9VK0DsHNIU9nF29#Po%SVW$qlR!Pvw9>|g|Iv|ChV;=ey8Lafc&d?*@ z874|@y2eVnMo?!MA#C1hj9_!4_}vt2sVVuES}D2dS}N&UKrOXE_PZs*R&kKuktI?6 zZVh&ZHTlkPP;%3?hq}QYVJ#nuXC1+|IFfIRtCE|pi;}K0)FNkuMLS&(Y+e*g-N2T* zk#DKDlAErVlCCGzQcvU%_CnYy0SaMcNz@Sb0XxHoWM?SpLvvP!lACUtl5Q&08L3Kb zjuW9dD-FR0<*bQ{pqw>Pk-;hxY-uL>mewk{=~gT0RzWSTQtD`)49i*72wTB93t1B6 z_sNQ&oHa#}!Kx1Ij5_k2(W>O8+pMJ91a(Fe!seaL2sS8ZA^hG3wzQ3WOM8^ubi0&v zJE4|#BKy4yVJkRiAxonAy%+3^Uh<3eH)`lBglP5bTVF zBs=4kFSt4S)EAV&{23cS{9p#POQvqR7fp39n1X9Cf5wK_z6=aIFPMV1m0Sdophdz$ zoJ>eVM3+rLz1=sy;KnD2Lt5o&;Rkkzi67JvS|P z0PiDRzyqER3ie}QfSL^5u6qOQs}Mi1uRt8qeDyj2?5pPiP+x)gpc5v{+;l&i>3%YU z1@D^xsKZf?Jm3ItErIPQ0R=hatbQH8wLl2^=06BD||s zR5b$X9nIT8YL|N1 zpfEX#szyV-qj?ud%}S6t%`3s?979!Opx)8E8)VlykeZftU^T~4)mW%^H19aib!m5r_o2>kO(I2Y8fwz)ZOi&cI;BYXgc+UK>(l^9Cd~ufSpx z#0QO~*tqEm*y!@ZBlIT78T{}Fg+$j*0UJ<+8G#6pTW^6}A_R7c5Xmli3~|Xlm`gx> z(DqFmH(gO1T@f2yVYp+SfE*(XcMK$5>=d!-XkG$Jc;Le34t(}rK9nC92&V{6{ z4Rcl5D5y8pCDJrfn6a- zvMU%Oz$L?9m@7bh(BTC(Zn}zaS1?8}Fzi%>y8<S1hB_a@)2*6wd;)C{A*tqFx+URP)T_Or{i3Z#ykWy!-rcFo7Iz=N80dk2L z$R*lfmuQph5(S7$WMD1<@q-!E^laR8b!~KY;4V=FxkLx<5=eQqQ`ZJmR>2D_C6G(> z!7kA!*(KT#muSFT0^$cVs2SS0=^DVDp#yS;0o)n*lMo}QPQ^$Tf62uQ?P&2V{(=~=W(gx&6W3VGZ@nZ|J&=hQ;DajV5Lo7^&SqS0>GpGgGxWVe% zj0kAsf`J9HJq(m#3_{zSlt5=coB{Vx&L}ci1>1mHaG4R{who9xT3e?O;*eaJLqL4c zxzGrQ6k~IU0?Z+ZvnHd!4k>{+1jHfDAvF+(RKOep;s-ORB_JG97s0@w7HP8=lvNoT z&Vo+4(g9Wb3ai)X*Rxu z*!T=)BZv>0OLK$!@fFO*Ur-yF-9UbP4Y3i#A=*YY4}ZpnBh27xWH&Rkga+|JOUXUm zbdx-F6FqekJayweb>lpBV?A|aJYiYjC^G|tTC^uL!q0<_nQ3!UY5?5~0ZM*5lRVp; zl)$V+I4i*u+I83&?+J<}@Tp=u3&g_F?!1G_;6;syzr8$kSE1~tWSH(iBrU3s`OWI@glggWCg$QcUZpk`kvh}bEQ z<|H|gla#JTR>!JGu*gKFq-H(k|mU6pWMWw@&}K&}#ly6P&(RjT2jrd=qA z*r^f@Y7mBkh@Hx4F4P3MP#x?-b&_3Z0CAx%%!MF+FoT+AxSOs9+--&+w<$s0297ul zG&dN5+@J+^gBHndu!6Y34CV$9A2gE_?xw2~uB#1qhBe3;YEWlf2L+K%I3lTQqdCb2 zzoduvW2DEn~+)cL> zV(ZS*aL8f@4$!II91My`0uUys>D2K5KLZ0dn8m=r&Hx&1CP`eAsJvNRYRNv;*jQ~7KoD?VNL?^K^G!KyXj`bozx0*k_^a6paV6s zu|=E`=p1%f?B#*o)dq1Fh(nsYdLi!Wg1HOC2i++U?WS7@cUK>Vy9)8eUJ2Mq{SYUC zIHWmgCd5h8U`_(@gBjE+quq4N;ZB+bb5b}cs6eq-jxYAAz)qSCaT16_nv<48oU|C` zBoH68V<_59w=P<@7VfGQFjs-jGY03py685iQpD=BT5RzNi^@i@BUeHk3F46E$c+$3 zu7x=g#1Cdr>xg#KZHv}zg*$Q+h9ldeA!VBoXgF19XDhzQ?F2h=GsKY~4rz|u3vuL5 zm?J^_Ud@kRGcup>`H90}r(=E%zsN1lf{62uQ?P@5m^ zraLcMcP`wKS1=qo5AI0NfV$Amx%gbU0PM=E5LbdYq`C4g#FaN;t_1Oe8Pt|XyXh{C z)?EU3fipj?B`l^ejWd0 zvjtz)*#UOsSBN7)9MT;57vjjDFh_#;!3=8qquq4(M(gf@JMtffBlp4`$q@=F&-dVS z&%tAY*C1_1z^qw@j;W5(QdjIqIJ(l>z;!C4*b=WC2bUH&MAa@FkMFU}vj9oDJfT=4>5^vo&DO2JwR#)SgDW={}CueFS&2 zF3in3;B$~0g?Bzib>t&_j(i4oq#nePAP#AcG=n(O2uB9qa7UWM z9H|9!PO8+M2(@%#Wk>T9P*()BT5S@-R`8k{ zWJ%DfhbQ0>>!*qgR#U;wm`c7g=2W`r&Z^X%33bLygv~o=A=scbH3+}Y1zS3od`lNs zy6G;g)Lj6zbOEy87b0v0uc<+nMD_a;urrpB?~GNIZn`U=Zdie^7PO`Y;n~$-TUL{A z%Z5rf-F20^YoQjcMOd_R9fA#7Q-iQ{BiPc7F($nNy zdcV?5_im-`9jK*uDm$8A!gAJKgstG5g)9m3`%7@ndZox<^#JUQ2jn~Bd8M1~(@NbZ zP-i?r*u3*8f(^=92*1AoTl#{0OW#$x>AtDdeGRqrHL~B|AZ!KaEM!SkzrP1N<30J# z_*&_v`x)wn&j@QlISb+0Z(v)#k#EcIN;ln~mAXHm7X3h2wDTu|4a!*vOaFi^{X@Q` zOjT~W3{|@Sp_cwf4q=8Wc=`tCEM!U45N56dRUgb%q*fniY@u~lO(!FRn{HJnBZF>b zCnE!-<^r+W9N$257)TP%1Ld(d;5_z5k-@6A6Egh-ris5f0$hW^oiGvXgnp0{`ru9g zu{xUH!SWkO7VZXcjzd)d3YB-@JojFa!D#XHqXDx-h z2*iRr0hBip!LR~qADAZBzO`WcR)d0J72Hw~3vTI7kR+T3%Bct^tb;lMOq1(`Enp{X z0y$wL+zB8SQcQqk;cfuuTT}(8F|ifuEHF)?vmV28?;)_W4uG7sAMPv=tIhEvH1~oe z;XF|8{Rqyz9~Bv_4nv&)rpa}}b+8kzf}C&#?gS94qxmx|_kv{MZUE#rR47Tqh zC>TD#Ed{aQmhJ>e!g-+Fi*Ujhs1v|6xlZ^6cES&k6TZWp0AeA<1V|R{25|00Re%~3 zzoE_o)5JR~?>-}F%Iv8icogZ8AgB`dXKVoRgBjFVUV`dk=9kcF*q^cCnIHqhPLM!H z^EXBCLTfk=wBVNqyiC;qGzQ<%q|CsCaz7F)Xbp)!W5Y{9@SqWdOLWf`>e7!8m%f9! z6vPi^P~!x@!>e8^$L@j10O$AVLtyq1-|Y3~FL88NtgkWnjxPdBG;^1gUOwQUWbNV^FY= z0XY$R#yUSt+fI;P&^`l@p&iYQN+8dIF1TLA14=TW$!11ork&VjS#gN7z}z7Kw+8AI ze(2hGK~OM(&Q%9H3Uq~GgD}L+Aa5evEQ{o3QMh4HH-pnUC??pMKqLn%m}CLR3d{v! zFijvift^s(!8%!BjuD4B25cMHF_J5pqZotP1jgGI|87gH6~8(t-#qO^_3z5v&Q*wiBcm6u}@v zaYrzAS=OD{#o-aG1-Az36j+#QgMtYZ!C*&$!&Dcp7V0E$EP&z#PyFe@HGx6~_KVt)kAIzX;0FF9+P^{^J z2wf1N10u9Rgcedv+Jn4egdUTQLeLoil)Wh6+f85LpsNHxxe+vpTCx*lIH+iX z6z1Tya^MAM&Y-}6NrJL61GwDU39`1$NePxKT+o%VK$L-;3riyqouEPhrppyw7o?on z3Gy?N;qKrd+6f91SlX1gFa^Z{G;MkaF)&z}fds5fK%_rogC{6zK*g_;~w=F;daBl~}ybV?d_I3y?J%BC)#C4q`atuQp0tyLm>IbEhoiO{6?nMMQ z9H1*Q*+8`$%#2V_I`Tmzp$L#O!SSMr6i1p!4%Ye$>0TOjU7tI8T zI)X$yn*V?{3pM`%Zx+e|i93PBK}UAN?j6YiJ7p)xGEgvqauiz10cnStT7;<{5$jO(en{#|Kz@OR2fR^G z266~T2)mU(NU0{Wh6p5dd-rG!|MxaT^E{fX8hc%uuj8u%R6gL$Ny&8dpIeL!hR1f(jN))jOfCfrW4v z%qFm2uuVOn5CNrRa7%kHI5{`4gR(ZvI7rqu0?B|jKJ1B-fS z8?7JYGLZQo{X0SWz_HjU48HhG0Ce#gC_gZ$gU$)w3CfvBM+HwHPBUop+G3uapuFAD zqzt*kYjr7K+)pQ*f0|m)=ZiZE~#bMVn`V_51b7A85=-+&>8yRGAtBSa)p41V5H(} z3CJrEprQv9C9oJ@3KES(7hMJtjRJ`x7gH<1w(SHNidlW{1X&0xy&x4mC{HU`#DV+^ zO@=E$0T&Mvu!;tepbKz8!2qh0!Ro+CZVjeAh(ZFKxD_lCK-!_Et^>Ii<_CB|v>qf1 z^6ySicp$YLHiC`!XKdI6iW_8SBW&3TGOo=@Ny#z^WD$zzkW_(;Z*x*o!LJHAz!2p+ zn?)kXXicyM{)`Q9XKjYLZwn~2l0k~#p|uqhTA-_=z<$!Fh(Z|=K&c=H;!*{&4-`NaDIisvV71`8cz1&h_h)R_1M*}V zNEYtNy)aLLHGw_344%t^XLHqDK9~}9FZDwL9RkE5=j-vT5v$%RRwZ#o0AfoMGnX;O|V*j#s;`MF2Edg z5flu0AVu(CxC9FZuwHO5TmdUb$s8=|P0b5<44Q-#Eb>9xak&@j5~wP0y1fcE&7ZO1 z8p!ejkZ!o;*I|}}4Fy|%6C?y`YGi;^Y9gn{+hCJWtVX06P?Rw!SQdeFp(sIwCPaxv zAxMcPSRvSfcfiK_GdA1>Ij|Tc3wPi>kZVAR1gr_{!22K}P{sl~5S+0df=xiN6;Ya? z2qWC9WKjaL2}Kr%CPW#+grXc_mvRM9c(w)?a#r= zahQuDjBuTjMH$Fg6j_90P=pbokLq@WVJZ;Az;1sDb`0nM4v^c+L6*SX{u<_Xu-#y{ zzXjz?SfvYZYrF^P1y`1uNEN3hQnjFoRC;P6l?s|jSwj;krD`H23QeRC)kJckCfG)Q z#)gleOb>Dty!{dm@`pcT!zYjrm^2|=Qrj=TAnlj$un+?ALF?ne?UxFqR?BaY{UCvk z<}M|08Mzb212x%X!2M%T5d@Y)9d@pQy7Vu^r4TNuE@cx2kCrkCLq|(Ne9!_buuJPe zjjUQE=duekFsLPOBkQ2 zJ3#>eD$y-EK;}RV76CaAB!l8(gj-+^7KPac)(o~y9HbQ#emg+~sK109Xoy@1uHTuN zP%J>mvf>bj564KrtpPc+%}EK?-j@P}2{`06kzzp;DU>w9vi^(>GQtcDFjqnbZyP{i z;Lq3~3-T9}CWK3BdQ*d>Hzjbe`!hCx_`wWn-Qe`r1xjz7Na;--g$%N_h~x!JeAs1KQ5=iV1y6jo zaBDze0I~*Z9lXh95Ap=q`I<;x(FBY5Gd4JaA`hwulJX`(z3K$=Dw8IJOKNoaLZZtZ z9OC|r4Iq9ngW7Cxbj<=q*Gv#G14K+mia0-zf966X4jz~R!k|>>Ski!H#2I7`xR>9g z%m5lm1O+H$#2I8bq@)KOfr=O|3<7x>CJ9Oeka6RkAZwAjcERY%ARW=2Am_r84@4)Z z%7A5t5OiITe#B0YpOFj?0|yL>S!hX7!D2orBA`hz0v0YXSE6V|Bn*)6K|{;Pjzq|^ z;?M<8PEqKtht!EMOJSajMpvc)t~z%@;{v7}o(5w;NePr|z+M99nmAChoCETqKVw5Y zoD;&N2@xbU!DT`cTnac`{TUlT{9p#P#oz?D2$akgf`|o3X)OyBrc0q|4L$~&4H8|3 zE}8=pT@DgO9>mB4+qM&AC}xV-39=BB{y<3#l6F7|MZsbv$k)(#%?J5>6-dBp1&H)# zY$$*Q7FZoPu!=D4L8|jtgET_TD+Zaj1|$GCuLNcuSRL5BGEDO@Qr}vTAy88*K)#2C z2|QO;fFQUx*|)F!aR zs|q;+5UHKbVm-)cO|Vvf#s;{vYGLlH1BKQ`kRo_!)q_F{)U5&Q1$S#2LH-0e7bT(* z0S3zzO(1n32gAYxho|7#q6O>@6jhLngc?AbK@P;F3S=KBfGjqFRB3|Mf;$YYV8i_x z8`?mg+yat?d$JwoNw6lcCp$qxpw8twkV;MD*zX3LgyH~141udn1f5wJhkOQ}aWZ@3%1Gxqi3t&xP2lj)6KxGKnf#7635ftFCObPGg zOa>VT&PQ)nVZxh7J`Xd*d66KsM%W5ZNX8U|Sc@3brdIn|%BVH(IqOqvib z(d8BAR3^|`nGDFuDCw}1Q9%4)1~tFwObl+iKGT^XOIASz8R&qNHpdcv@b+1d%reL2 zkn3{4(Q-eNiUkXTe zMdJh|9nc*Epp8jBko)$6q3+6uxC_E1)m=ppcNN0i1>y%YsD*>w6*`@XK{o`+am9=b z471zXCMrcvXM$||*U|)S`)`}5v=gKlCHQuNbfSp(7=iS{4KM)lTpU3pgH;67Hzg3? zK)9s(rX1p%GMH~b{9p#PSg>!RLB5GX@=XQEH=S(Ll;Tl*0}|N@Qj8MlJ3%^8M0|`u zDrbWTkO2lDhKnPJWUz{Z`lb@%8wi(Z-|RmNPRC1G!0B!Y3$#lM;s-ORT{#O%$Cu9{ z((y7DY;8EuF3}RuEQtha+YO|%qj|Ox`f7pYEDQ`*SI;tmmn?y4;#aA8oddhr8+8($tzImc?B~b%0n~wJJeuJu)*M9`vDSS(u7z|YOpaw zN}>PY@bG7B0P#WR%7BB-3>0jpNWsPeF03HIW)1QgG}u@f85q?5AO{;rD_Rik1et^; z2KAi<$Si-x1~yO;1PV4Akbow#73?4@#886`VhJ>$pvFUaXa;jY4b}u33=TF_Phc85_hwE(V2;6G%W4**FQ1aT4&*DL^(b6l5wiJYYsiLXFY{8wCyzDUcA8CPW3P z;o$=b4-c?!{TUlT{9pz(H*k2kf|8L7QlR*Pl|cf<3*;AQpnx_vtF7hR+tIv1fuX?? zbf^ggAiIz>9_i z9_Yjta3KWZgW7=L!1DzKo)1#s#UKS<5XgVfz>5X>Y$HnGf%L)x4`c+$OFH1d4F!>? zzVio}<OjZZ1iTR(VAeR!2!4hB*df%v7FQZJOBy6-QbY%XKVoRgBjG~!2uWt3cy$p z5rY(p2f=C~p_mNvAT$&YfxPyG4^pUAfcyp0j~<91<6tKyf=mT@5;;IYpDd7oCbDs$!$#GV!D+BbnW3Qy6jd+-!NG%O z)K#canqZ^A;c*Ql#H0zajMVS|oi7TSP6qqdpRobN2c7x_4v!pAa?3^v6wtAw!3>b( zRtWM7G*BLcVmX~3lH966egJ7j3zVH8lhDMVm0=#pEKs`^9AF%o1=w!Hoy=&C84sYk{mEeh%A~UC)i4mbs&>bB_$A&Aib!P8c321{~1svEs!M{{&Vx_tZ4e9 z#9#y>L5l^G*cljhg1iqB08imU@`dXYNCzyL9o%b#a7l}T3`i8D!=eDh4`xvF07rp4 zQWRu@qQDCj1t3veQGg_e83jm^m{EWvi5UgRl8CT^Mgfu}W)vVvVnzXyB%vtC0!0DH z`)E<%35|kmNEAT0q(wmiBnt9jQ2^oxGpPB1qre*}3JM_#iy%}nC_?<6Ffpis)aZ0H zf8}8?XmctxYI7g3GwgQ3#x8xOXCnb3nwQ=@wan6Rd#& zl4g-4Bsf8%pP(ZzLFu*4sT4HN0JgXk6jUIK+nh=rK@wKJ&_F7K1QLWxS|C+JJY59~ zBoH4of(H(yK%_vb0eL$F#@%5~$u@=CneA!3acxLcA8@#yXG- zLZ2`(K;mR4$T1)#;Db0}u~QEUB#@#uR|m&7R|f{GU}zvUKmrNEB`uIzAr5GP1rmrK z%%Bzl4y16TKx%_1Y==-CAO}Z*QW8jwPDk@%9tH!XCBU5^`Djp(f)wG(`bct^SszIf zGwUNsVrG40NsO$IB#D{zkt8v*K9VFx)`u;9?gGUT$lo1J%8&v#5*kO{kT`;HNsFTi zkTCCu#Sw@f%%Bzrj-yzlIGP9w^#o9;gG6zKI+7e_s3S>YhB}fYW~d`eVuU)9Bxa~1 zNn(aNk|ai`qt$tnAmKC_6bgxu%(R$?VJ9d+;6*SjqNac%3Z$r`)zPt|)sev}9vV?o zArS@P5*<;h&%i^Ipuuo|#s<)^JGd7M;)Bkye+Fuve1FEop!@9^qK#4tX%T})zx^2- zK%?7gzn(EM>;$RlX#NlCO^vOPYjJmiOu(l=9>oaoZUKBoU{fG3gS6!3=QBu?qXyFIgK$X=*fvN| zwZa<9Abv1|8pCr?!2U-H({4~0fCNC{1M)tDdP{RBI5a@4i4Yb@f(aZhOO*PR!M9C< z>N*DborJW4gA}V)8G?G5a9T@PFEa&tSt!uUN`YQB3iPt$){B(37@tGZ)?`T9f^bPq zTQeYOYdS1#f%u@U`rx$1{2Y;A=YrA}NPx_=MMx{Yv_(iSzO+S1FTS)zNH4y$MMy8c zv_(iSzO+S1FRrxJz`)4BfKqm`Letk$Ncw_sNljm?An9u*EPa9a!3=5~;Pl0gl)hGj z(icbod-|G!D7zRTWtY$-MA-#yq01xX4Nj=r*FfA3;gah1tq`|^2G_t98i)_NqYmtL zZX~zw1i2j~K$hDdfO_NL5?BEoE_*>MiyEeZhBIJhhJpd+u%`YH%L?nST8B%USm6b*+ z%Os&L2dy>=VbX+fNp<-cDWRi%in{_GLQhsshA0fKso%6fq_AO zCn4?Nx*l6GegIY!Hh@M-P~uMp8VVmFnGC`uH59%o(bv27te(B;)-Vmd6}Jr^x|p`Fv#Q43aNS|ffKbpQli!XC2EiWnTeW^R(y$?kY0R= znvh<6iJFjJT!|Xi)+D4KPr^njybPi7tOto_2$$4&HipEr5iFiT{9pz(6L35mBgL}` zs9pwjp^@5;AbC)#dDTW&)Gpd2jPY99z z&W`5kkP$icmgbpIR#WpVWu1=Z1w5ds+-C4f@@5|J*?x&k3=CGDATNb5X@Y6uSL;J( zm(n19Nrm|Z#0O3LgZ<)-#ICLBgRB77ieOFoRkEI2`3(ps`D2t2xx$ znwKhvf&v8p#K*I`5lN?qZkg#fpg%yYo zT1E>Ft5Bq{>ICJlCU#~9P{enEJOi4DL~4nE6n8W)2d6oZXI6kB{=bqB7gu*_+t zGI&sBCrCdoNqMy&&tN0=Yd~2NSus+~>_oN!N!$l{7$yN46muX!0pXGw6bm6iu>clt zAbv1|S_(KQl957T5ppOj289Ah7MDlC<%T?XLL4a_BJ05At5m43mO^|5;S%jD70AMe zbr4^zf%yu=4`xtX^a3_Eh|Nf$^9W+XV+aLZmIGQu63nm@q!)I=1*lop z@azA7d(h%q6^mma*MmzJP=W?CKq6`zpMVMgP@TLD6vSHW$2Z`3)%4_Pk(X0NE^n;T9GaCU8Q8?SX#_QoawQ z9AxJQDFz1Ufxu3s4ci4lE^sPUJL3#J)%PH%bOIR;^B$zZ2|aE`?KVu^AwdQP=y|`8 zV?1;^nhz_3RtX&juM&C(4)~oQdqEP$Ac8^O;yB1#&^6=lK@KAnEFZ83%STwSfDHr( z%V$v8gs`ts7<3ZIQRSVW*lly$p=<;qKw0k#xSXe+&v=fx3JDSgen*B?`JF=E4AccOTFz8&ib0FCx${3x3U$D>wI|dw@ ze?XD5`vnt&n(tHamfI4BhO3~2+tG3vRJ65RRyOWvz5rr2Ur<)t`+^Cy2WJtuU<8+# z#-O9CL1N83JE7?bR5ZffgtUzq6cP=!B`ghK1)w|#-IL;D)aFqsqY_?f}G0ocL2nEe?WK>T0^ zwe#Sz<{YS8ISV4rfQZu|;uMHDiB#4IKui#XP(lz&1Z>_;klv1F$W03HNJlDg?m!Zd zKVyR^Sc5-fgBWP5G@+a&&J5{kLJOP=AY=R)8zev>0V;67=7Q6L6v((spc15`Nm&59 zgV0MIX^@^PAU#BvIv^V;EOlhSA+QrVIvO<8?b@k zuu%jhDTICSQU?^zD20g+WhFxL;2c{6%dw!8jGkjPATa@Q8))bPRHw;X+(U{7O^5VgqU6u<^?MR8LQ5X^>pfh1$ zF`)}e8XO_)nqb$1k4Mo1MIFGd6gD)q<{n00kGJob830vtNLW@n>uRoj?H&eXzOU&<7n3q4o+?f^{@0H%tIo z%fP^Z=_b(n2#_RNv&#?Unl~Wrm<8Y+?9DEaWiao8>U8{33vYHk0yn!Jfty{RJ&C~# zJ3;n#G(Q4W(T|iFm?@uuDXc)}gH4N~Etz!ujc)YaD zu>@?vPEhg#bxlBfGC>yX1SQ3e=C>fz;H3azyTZ}E+Ry=VG6MssrFmL;Cn%|-Sa~6de017T=JfE()t>!F~i4l3)f*JG>x-2Q8$X2+Elq&7X04 z9iGzFJDR_MR6WLQFUG)<0oZZiWDo~RRWFIIiC)8MBCsz(#TRmW5th&{zd^(=5b+a4`~VT(kxI^Dh%qG)suV(%gALsYG61vD2rE8S zEVx14O>pP50<6KGv7r(aW`xRxDrgFXHX8qf5+~>!H&AeZ$_22w-~>?%GLG>jq?Za$ zR5%=lqYSMBnZXP)gXl68WFv)TXgxSYc7p6hE<<@BK?V-A29U!Dg;gW=uxf&Z71%&< zShaxC8Nxnz848MWq%yP>Y9MK4D6+ZO%g{EMx%kRZP(nm0LqUlWy$mI6S39~_8&Hcx zTB<58?+is7Zo-F9Gts zIEWBK3W6OFExRy-U?)feXm}|UMC=6V1dT9-f(SKf`4e_P*X*+C()lVNlgP`j~c|D6sbmx3=C>BU&00oe+V)#>;x$X&1!^#h@BvP zE1D-N=yWu9fQKhL6n27)S<$==BnCS~YA49l70o|ErP4R>;NmxBaM11rZ|-gYU8(8= z+Tsmr#zT+zSPk)YgE3?!HiS#6&+Q>TH;4Hg#1CdrTMzd6I*@6QmpD*H93#6J!j?m!Tj6>WvLhZ#Y7{0pXJB4bZV& z{)`Q-FmHhP!3=6!!QR*c^1)^hu?a+MMDh#hm@c*Xs1XQK4)@DWkUo%4kRuRe49Gu7 z2U+a|nF{iiPDeAb5x5QNbI^fcAxxSOE~!2Tot5R!*boNuIfx(3ptcL_^PM37?f?T0^wF6*p><9T^ABflsBK9Epr2v!|m!d`>NIBduJ3;!;BM@W^$WzD>2r?DqH4-B5 zAk^oe<6uLWG$CA4eO?R6fuP;!pt7z3#1CdrI|}ys5s-fmgNQ>&o~{FV8Wc205eQNV z_cU?@f^>uY3W-3FF(6+eN8mB2H|ild5W*$Z8=#%v{)`RHum}Y4gBjFLfxU4OnXQ2deC?-GDPw4xQ>l**$bX>X z=ch8Xh&c`QU@ydj5H6`61no=qXKa`V^B{;H%%FA-?7_1jznwwy+e|Ee11W<04LOQH z8p-n5d8o%`K|BWGlIpQ#kOVjn<}naIm_h9_*khMK9=ix4E+F|1biy6Da79XhAeC_6 z?F4B-#2iR3SsuIs^&sfbybvZ$2$xh3f_BaNGd8S)c@V@8W>C8h_TV*;->xG0Z5t@& z&`L*;BDmj>V-BQ|ERWrQdTcu+<{(^BJqFqn>(AJ*7v?b#KbS%74%lP2K_0sWB5or2 z4s@&>xKu@oIgm=Y?{#a^Neog44>^PxAcJ;-90w1) zogi0&%3MgD0-L)ApIZkq#291>XobWF9>h8z(7x53AZy`6jL)Fq3fj0D!lVh|k{Yg` zAmRENmS8~qUMsxqv?mi3aG)UVP|<`0X%9F^J5(y1|OpmKtiLKuMp6|HOrse=dV zPPiE$gLZ-(2MSV1+Xv)I%y8ub84NN6Yq)~;YwiSD3lCRAXt;tlaDp!D26IUbSJ37^ zf5rwO@X8o}#s&~Sm_f}N9IjTNAhkpaQYlDGN<%0aq#*53aexFVj&uq#3LF67bZUnh zq_QBN+hPe)kUDsfA{Ux)<3MKa1UV5iJmo;9f=s{~p7Nk2Lm)fh;b{X7K*k0I&|(}W zO$e9N@C5C80^KSG3r`R~m_f}Q9G-5V@N@+cE=Yl@4+%{J2xW*AsLd)qkU+(ePC@2@ zk{2YMdZ7j?Xz!GoCn!+S8t5Q(@Ic)OHv?qQPLSh3K?+HyAXj3BD`+p48psf=;R@Q2 zwG(75JX}4X;c5yAR|uEXaCLx$jwLKyL443De&BEo1O;gTQjj`ARD(7l`7<_vwjd$O z({Mfo6oMs4LF(W^ikwd2#(~V-334K4c)EhpDaZt@;R)KW zv=d|}JUoM;;pq+uPY9RP@C5Dh0ZqHZ!V|;?-M9e`&lpg6Mk9qMXe*FEV*_a8k3VBW zC`uAdf`liIBnmPLl(Ha6Gyyd{K|6ZX;z8kwR^@}#!NYSW+zgOGJ3;OOg(f(O64&{H zwFJUJAq_GcYe+|cN(7K=;2|9c4e3ZoNJF@!hIBF{Eylt^8pID~P)i4gbQ)41r$7{f zw)KDpAdmvNLnQ|i$T$)$$P{ppfD>&NY9ObBJe`RpkU{F;fsCAJ;l_c?BrSw9K$d|F z#u~zzpb!Q*1s=i~&=AgogfN6lY6ye2<@hr;9EDY0z$%5GG9sm(-A63kkI4u#g7vgBjE& zfpqISJwiGpMZu`+Nn+zso_yG9*uf_Q!yO2C174 zQVI7oa!LT{2Kg17*LH%80r?U#>;aiwUIq0AXcJ8clO}{qsy9FzMEn^WAbW2785=-+ z(3~9D8|y$mSPLT7fQZ#degW+nL61O?a=2f1g7l$BAjlYyr;sBMWGcvOgdz~MIF*qH zX-;wj)c>GODIrXn5H6|y2W?mIXKeThOTZw0FoW6_u>UuMe7y-oY((-pXdi>xdU)Ce z&q;z*!o7|hjUe41A48%MWDLl!$kDhJ>J4VdBsqjjsyCpU8#rK#1VDVyRxGeLc7S}a z9YkzH@&;%l1bS)&sf2rDCrAq@1|c&dAiZ#(U@MwHs{^pji0p!T5VYkYgh>;^CDntV zEd|hB7vSs$;s-OR?FD;q56Ex3k^BbQTY&C2kRrI>kfR8skt~nxgL(|SWr0Z(!X?#X z+K{yxpdATdkAe8X3~GnK9y;t161)M)h-})@Q~XHHv?qQPLSi^fwvRnN<_&7 z>rI1}x~qW3|G+lY&DP}Si=>xYzLW zq=suVBy?(E;R@mhGpM}%{_8v=+g4Dr-6gi#3jRTpv6XZn9@azDkevk=R!xOYtcqhnCczC{phG!Qf zJRw|C!xOZ6)Ss~dv^Ex8QGocM8x_Fe`5hFV-;lx+w4&6Xv0)}85@sQVXS2#*NO>}?fx;85Chz=u4x1-VdsGC1DTCA zr00T41dwasA^j5?((@o84dId+(x3&j{)`QaU?~^G4`xtfdJUSnWPFX7w1lpuT?Gkb z(2`nMInbfP{u(?Fj3d#4OaTW8IMK4cMwzr+1M)P>YbHoX5vjfcse=bHa-xMB2Qrhi z5C$#2RRbA}HH6oJLKx%}cnCAUhV<;#LqZtBB{hUWOK<%d8#cp27{m`|P~!!MFwbiy z23>BXVBQT0-#ritv|1Jx%*`r7kYL7STTmuhjK4?fEgoHGNOKM1;g#_AhSV)8T!3=8R z;E)zW3gmMTh36sE1*8I_Lq!G>$T-q6$P{ppfYY)RY9L<(d0G-nAcNGw0~t9j!;J%( zNm^RI1hNcdFxC*h3<_b8Q{W*i0S)0RkPwD&Ney8o$X(|Wu)EGd{9pz(CvXTmg3_`B zh_D9{b|AtQDb$r&7#P%CK*6K-8aCR)C&a+86QmIyJUc-qfRZ2bXb;FhP!J&x7J$rO z(bTU3-kbp%3)l&=Y(?{S&;n=JnJHKoGb0Tj=qz(=0Nu>x*Z@AJOr3>+VJFCmAYsG> zF-o93_#aim*@=MxGWg;Q4OtBq@a=jKE}oEOZ&(T1mdKYQ6w1Kw&jeiyZVd@q16a_4 z_`wWn-r%710)?d~i0}Xr?jXVqM7Sb_uMH@CeL>-C3J+gFQ22s$Bf=MC40`y2Ohpf0 zkR_<$3$hVa1Y|uiAr6WjAGEM`0EIQkxmd#*MFJ7lKG3jsgoHJOOLABTK*HJ$7S

*$s$$J22*ZC~?Frs3SDNjsT}V&|JLcT9BJSp%=^mi*#@RG6;Yw z;Jq+eVk=;fnOG~}eUN&T^a^+#L?ek6FhbW5t$>j|K&S!+txpHX6ljDggjsVnDAphq zFgSWO*MI~-$Nhpz;e6z7%FK@Di;#XLLqi~_PXbG0pn3>ARt8?HVbu*XA%sa2Op`WN z)vy>e8P3?S2weMvE=~b6)C@uHIDmEBs$mJpp@(2YR!3osBhV%(UB<3JmVpP7AVGmN zb_JJ#3_>A|UBP9rk6p177`p;_6l^7Y?5bfYsEPoE1olCrHPG>LSQP;-bU|~fJ3%1} zAJihYidY5;cW?rMX~#$)FtgVjN30s+$`CXm&T1On>rf_nxaelUZY z4Jd(}KqQbopz-Qsi1F$MP$3`8pr!;GR|Bbodl$ZPp#!pV;Wcaw?=^VP3p6?)Z*dCb zVo=HF&j>Dl!5Id!`1>SC%Ac`e9jwp5WQyo!ji z0kpJ7tpMgkkp0+(-Wv{Jx)Im3h4rQHkWF+Apw&N`cc5+rt>{s^0E#GNk0REqfmU+B z+Fo0rnG&?}$^bkq?o`Su53W|fFhVPQ(3#hu&H#A066UGHSe%KnjtgX(#a)n-P{O+b zL(xuyFfbs6)B})VnqVWL;dKV&S^VJz3rLU?8&G;GAQ429 z9Mn2Obts;~8KhY45th(D3vv*6$_ZvK)^vXkRC~ZwfZTyS!6FAIEWyCikZ5|rj1o>=RDA-Cwv*9u*;z1#Sz1eU8oPQW0vqtD8 zEVQ3{g%~41{hkjzs4-y|(DgGMx=iTODw{h@jtPhv)B#G06&feh0G8wpL! zw?JW(K(K(lO-iUh9DyDxcVM9cb_6(7?qLZPj7rAh1<28;A%LL>;#;&57OWBK&-);M z;w@X%UScT$AAq#sO+w)5;8(Ch;08Sl0gz?j90^IiNQD4g2BQ#w%U~}A*a-9;Kpq8K z=>oA6lw%&kA{HFp;D~(;j#z)jh9?;51~z-I4r{kqyvB@Ql(p92suznQly%hxO+p5i zSQLrCRyV_}Lrq8+79my8VAK2=8&Et0?m9dLr3$=>iGVHO_RbqD>FpWFWYCU2wVNPW z(1twFit0&fp!E`y)fgIhg~3g`4mH+L(7rwJIPr6kCXjkiaRthJ)4&_(K!wwBa1jh* zeL*WfG2(%MlTi*nXm|m#G6}8NI0ftDdx7STK@JM-Xg;9^cH>Kogn$x#;PyIXp9^Ed zD_DX8#{f7%y#XgER3~Eiz~U`tN+J;d7-k^FKiD*A@$nXm{U}=yK#A1y9msyDj(4CC zA|Z`nxCER=-h)y>M>9&B_&vyE{9zADL9@Z#zgrLkCaWQm5vZF8Pe!0xze5eQ;078| zA21>c#h;)-YDQSA?IS3nxI#EJ!5#+>>wf|Xfm-6=&;!TaXXKXnS5Qm*11OyQ85_P~ z300IGA)ru&)gww4A3@rn!TTK)2zY~6?Gwc7C}H;l-FJ{qBK1a;CFY{8vA5R=Ik+%*9)nQg&g~FlwedtYZ5~0@D5=H1}0eGvNJL; zSbYUWdkB*zm?m-1ha2KYE|?!d{9pz(aF6mkc0clfTn&Pyupn(m>C%Df0!E}p#e&? z0-z-K1DfQ(G>J)01d`;0VMz|e4`xsUyW>A1$z24EaQ#IZ;SvS8HWQTjK&n8AZ)QjH zSy+|o3mP^DDF=lZ*tKd*Kfs%2QOY-QP{6|UgEJ_`CQZn43V+512@JI;&1&@Q3Coj` z7}`*_bE<()zk<1RW=HcZRp`=2@Yz<-1CJV{L8ib|fgB3z<3Y}w0_qkjWOX%Y zjkFPTnotI}ekSm7ODOsqFt*Y$nzkq@!VHrG1^rs&pa;1qLcIgBRdz9Kk?vwpy9Tr) zeRc<%!cjFwNCfnQH@)?NhhQ&iFf=q`L=}o#Aj{!HJDM-4q6aZ}ViLS2A+)1;A$SFF zgFMJ>;IT(ofM6YiQ2-@dh98hqX}~mz$yODTY?Wcj7Q_!`P%{CA3fm9R=@N563(q%$ zk}b;*CI(&RAMhh48q~nLc7oJ_5-uq8AQdZkUAH9%$X(EiTOBku2|9ZdG6>ENlJaM4 z&|qX>0FTas)q-n0O;8jg8wm+Hkl~z1d#Q_&6 z4mgqGzyOp`_vCY@I)2gCm%M!xWH%kq%Vb2?`rn zx`S-AhsT_Pg*3=H(8T8i@;|tYg=xVkV_^XUDPv_ISsbN|bp~ZMUXZE&j14ZJ*aj`q z2U`PP4dM>6L=+Urppb^`>p*d21Ii9vxMP`-_lq=mLV^Hf63h@#2sbb^FfgcC$buXI z^_CaNMsQ;o$y+EZd5N(dGz`2G*~uUQH90IH;EfytKCln~y9gWtz91pi5Ee~vQUGUW ze^6$Ixek=*P=f$wFD%&wfP6$sM9E`uW*{U0VKEA_6_j!yNgXNeg4VNw)@yJmTPPrf zY7oc`<*>X5N?$WOny-K=WY99Q5Kt)(%7kr>C7>c3o>ajJ2i)fkh6aO`BFI!tWV1s+ zW`i=TnlLD#5OgAFG7)~t6bERRtHFwvD;n@;;vp4I!XyP`F(N>t%;RU8f0l z9XOK0AOQw)SCf!|g%Zfw&?FX)5q~H>YxJ57)>w#un1~YbC>?*$xQ&G}$RfC3K=IUo zX8{kBJVXQ3Ws#tu1b2sFwt$+cplAXeMhzZ{Ky-&CA;|=1cNjGOh0-04!tghW^FiYl z@Uk`<6r!NA0PG)dPKW^sfpP*kEWv>s3(q{DD}zBkC$XkZgp}n8;Gp$qYyk0t8Pvdo zxN3-60=eIo1PUXKA50AB@dU2jz-!q385>f-Chi280ZQ%QctAO71GYVaLEgdu?c@ z8LI^{7U~34ofv*&*6C<pP`zF57(a=;BMtZHim zg(-L-31%hMj#)dbv;(^oT-tSjg3%J>@DL_VFim1G_CSKM8yqzLj13@uFoT*lC>ZS! z!MF~TmTW-%1Z$)O)eG`BNEEy>9i$usLm$Wj za?J$=vSSH&ff;C3FKF+a6r_J;4+=1U#)f`SfHG-9xTN*3CPTt)5-i+6e9(o$pm1|S zgxhIQxH%vN*%XMrsSs)!gqi`0|EnKB>xLXl9KZ)6?*thF3r)y2dU&Cd2G5ol#~m}U zKuTlCamOwYh3HFB{TUl(f^2jJRVtv%H9!mE96Fkm)sQqG%@i1QG%15BtXZJ`HmLbH zyGiVpMiRvE`x*=eAg&9zLva_hjJb)Oc_+xvAR|IMK-;3+exO_cG#g~Q9@M`K4bGr# z6d)y_4fCNO0g}ObHQpsYr2})nW5)HgS5hr;6y3g=Ydp%yn^+zn)#sI z>I_PJAxxTJn#A0?7?NHV!BQQFAIzWz?%iY|Qr%fls>=Z7)^wz#w*;(fCrBK#yN=X{ z0mZO&?hojqvZag+44OqCH~TX-ECYEDT&06-10_$4DjnH))cwN9L$RRD2%44J334DJ zofJdT6iSe;00mkO)B!6&t|@_XR#D=bM@R$1I9yYT#Wib?U9%SCnlh+s))96Ms%Oiw z7{4Cb_zfWAE1<@2B-QvzEXHp_Hhwe6_$sLJTSzs&8jJB;k&WL5GQI|C{C2{|<4!n` z)Ab=6JwO9W;8rH6d4-aeQ4M98e1cvQd@Mq7f!Q>~;o_F`$r9L*MP)gyb4fiA?lH)k26y^g2Wh zZz-UL(1mw91Flj;4aaV88mdRz?TzdKLfaWQLpU_SF$Fq!KZI2?4-{+Q?z|;9Mm6(6 z0{)B*`#|jt7Asg`1}c!%Km{#mHW!=_Ky@giEx5D=F_~<^MIDIAYzxjxASR0~xX1x9 zS#80^1Bl6H3(m?QCc7;-(Sl}vK{jfF?E^O#_k+@3Hpn$0OqyVt#0uyzqyjnwu1fqF z8$kSE1~qV}q76|2od;DwEuadh8L0v~0@k$?Bo69hfa+UNWB84R!7|6!8sJ=Q-3hCA zj)F2o7s#ppj19-&nGa+M)_MnI5uzgLhNN1QisU%R^BqtVPe7sq#sxV|4P-YcD!_uE zfMl`-I{*}rAoZGH32;E31ew(iGAo2h6HJpBkY^zQc?KLL{)`PEelUX?c#NJ!$spU23yY~R0b&aakTF;bi)l!qM^a%i1)>pqVFB_Mwy0A>=)zlA z;M9+!u%MxOw88?}1B40-(1I3lOo67TLYOrtf?^F)Sb$?xa}r3vpRwUQsI?6mg@yE4 zCP0NRfD$f~CWK2`pXCZ9&0U72IS@aXL9GhZXPJeT=4OD>+;pTgcNMH_CrBMA5c0)n|)P=nZjYjB(9#}Nq14Sc~CWK2`rg{X)R1d+~ z!=JGM#1Cdrs|97MrD&OIF(^|lLdsN+!Mb*W)WI?p>Od3fRRIhN7OOxB51J{SfI^*pcyX9bx0n55Ara0+!v-8lzCwzx@Z$t z%OQ@!Ibj7lP9J5$>H{dDzzhZ@0f;L=l@%jw>hB}W`Cw;(o&Oo+D7?v%=vV+X4pbcul3?!NeT6W1O0Nv@vAaAh&DNMf-biUdqEbjOQ(nf4ltbiDRGb%uZ zElN~;M~@2BVgfuK4VtThj7R^#P>o~D7O2Yp51ZopiLMJ$zwbm&`=9~>y{LdqwEu!8 z1*?sq(9}c@)8C-L0ZpB%tpxcT&sucQ3cwD?I`2OqO(6B4qzB6Kh_&dSpo2G{sVI;i zSYdwnOGppMoG(1!$um|G6AfrRAnMZfe<0iN$2rLTh^6cQK^njV{jh9>b)cUCwDt;A zn1VwRoT(U@K;x3|%Z6d42NOsolO}{qTE)c%z6i2`l?l3L7sL-{P-_5HT-(qpt}UR7 zYco>C#l^(Hptb`vcL@@ORV1jzJ7fq3%lR6h5q?mtF(~MO+PAQxgd6OVogh;|O9q~R zQW3OZ=YdFpoJCAM$*f@U45WJ}iUyR$=b*^61S^7C!3**cxYUAa!l+E2gVHXjj|n=H z40H{kKVt(QNEg_82SZ`I#6P@OT1TjKL<61VBjvv}6G6 zEAWy5L68vWFqx;I(9lEpydD zYBA_=-v(8X_T$88N4N?+xC`@>8pwbX#2A2>zdGAvMf} znvhT@HnPBt86}I?NFlF9*olzHCg?;&7=Wx{L~Vg;gVGwP(g)iOPJTLIw`-mRIc6s) z?m=fC+VCj!U40rbOz6 zWnMFo#>*g$k;GXF(`XKM@J^85K^>5H5T}40V*!x@Ij7CB#Ns`YlqJYI@YT7vGtSJ8 z=Fgx*LqW@kKZ91gfSdH7Wc@-q!&)DD!N$s$V z@EIfwih6&>22aSSffp!A+=htY`En zPi%86QMUXE(@kvI2(lCGNA!WGUr2r?Y2fK0L?el1BSO~@EgO+NK&Wg4E$9Hp6m&ty zJy5Jc%0_VXYu*P5_%k+Sf@@XHM<6cb_70Q=9sIgp=zUIT_xL;pYXe`HgI62g3v&o| zHW8!s@Uy!?V>e0`VC%t6;Ve+bz?(NASL~4QN^lbX4M}+@MNBqE;fZv8(P4F>?QKwl zUMGZlBzq3XXFp)`AMl9=^oRl7qYOUVbO-Eg(_B#YXR!jutR^_5z(qhF>YUAXPz?Gr zHspg;GigG&q|MosKw4kL;FRRg*Z|@OGpIF#-25MH&gL&@&gKu&oJ|E-mnP#+kT=2i zNP)EA^d?&RV*+afr$4;f@TWhJd$7+I;XD`^lK#NfgVSFn$ob&(2XhC;L=A@w@29%;$tiUm=2@WZ6`m04ve+-}) z^k;0S1F2@xgm6hqe@&3|*9cBYpqp2~47D~;`eXYEKiL7iYLVq9=wyeVh?5;!K;Gl{ z30)Y)4P$WqWCHKeq01TBAj`n3lpsrjkQPS4WiS>-!DT>eD=-&Eflg1ucV-R9qhKo$ z3!_>==?D}O*t0^DCMa!z=H0&X>}3AQ#DHBH@|l>R2?W@}s5VeIgBM1Dq6Cz`F&0L_ z?1qE_Xkk;|LV^ zsKc@oP`xbx_4Y)Fw;^28yge1-?I|#CgZRM=YCRxti=cU12;^-+ByUecb&e?1InyD| zfpAH4&TNQtX2F~T;s-ORS%I7*fpE@F(DG$5B$vzqMF2>kqj@|0WWio=dIuej{Do&H zNH_M_0X2?c-Nm`M&4IL}Aq^}P!_doO)Cvw}@;uxo^MEh*LvwqKYz^U=)_P;YCV z1okPYr;6@Vl-!2w(*?NAf%p{FJs4-%!rZfviGjgN5)|_xOqyVt#1-pHAyK{r7Udv* zFoT){D9U9JQGNgv)Qef8d+%2fN2tgW(Oo_ zw!?x3#1Cdra|8vA0wQP*g08@Z+@;*G3lu6FKtl~61@KTYfSoZ4y>_~6pu;*r zt7Sk#4L**bk#s9Xkdyrx8+JqTF@#H6K0W|(`F@zoLHu9_HD{2^RS+%*N2(H1q#gtX zHAn&6%2};DL2A(*djjNGO{inRG>MKq199wWm}5cwU z3s$SC3$j&hJ;+xeg)m3M&k$P*+FB1fH)biQ|6!>IQVwnzp97^S{hv$>YAbMRo(n!( zY?>xR!(5PVqmJh3nxMRM0c`h9WD9k`#T_WeS=d1A0NZjIWQzePKVw%6%9u>x?8(fE zewrZ;^VvXpm=PKI3fM8|wK4I&LMu){j%{-+f!wsJWMPZsnX8~^28SSMlL06nfzBWW zs{oGzT?Yw)didZF03XSD1MD~ypBNxQ$_`{Will{lNAnc$`C$_39nF)}!EHfHusZbM z0R=+}8;Wj((MlFzJ)qGf(8dE$EEs~~8ttBN6y1m@1R2c*jumjB$;1Y$7jA(J0(Yli z(TU!j+6l4-JXyt1vJ;fNI-2{@{R0W{re?_6P{i3^;Km@hKjrWf^N7LQpo|H#7Gwk> ztRS@kdJ=#+g$Zmf%nNsL8v_Y)T&@N!X#n40dKb3|pvt;a9mNEY&-HH0p_gMm2p<5-18L-lB@(2zYqXfO~op9+pC=oFg~DApi@ zf#4LNX$%tZXKZ)~%68$P`XA;IQ2IwYjs!Gi3|q)w466Lw97_bir-LD9K~SRURM+Wf z{-_3;Wca8C%IBbk{3VdXGm+Io@&dT{!8l73!(b%EkdqF;=Q4ojs-G}1K(1)F0967w zYyf91A}(A9nE`f^PDgVy56BPAJU%X<9Q72Mqcp)e3S9I)0|nY@oORoLP{jzEVxJGH z+CXMJ2bsZQ1+Gyw!NojyVB`g65soN%kbG|842mt35*48iQbK{MNAU7H^rA`$q8XIs z{TUlxf?STblvQ(q1N<##- z6PubqreRM_?{Js!5Z@Vt`uPlCi$E#oJt*aXW^}+w0Gw(*fZ7T=pcE0pqzR@;Y!ZHf zGzmY0Q=dO$1Bf5Ypq2tk&~Dh9gkQmGH9bJKLYjmig@l@fo*?Dm#@aVnID3Jb3gBiT zRs+zQg`lzs5-i}*1cwR{nHgjWSOZ381|5Q|2F|%yt;fu{pt1507AvsFHNpM?#{tM= zR_-7&gh>-j6CVfSUzr&E8FfK95^@EbH#p26f~Is|t24OyK)PmnJ3-W46CLYPGNyCBX`13LqJj+QUN8L!kC+;kNXCpoKY27>GXsSRe> z2~vpLU7(WRUcoXLrh&+If;za35Q0?rfZ7D1XndlNiwJ^f#AqY9pq`+EP=>2ffTjVn z6+pQHw0a)dO@!)sP?rE4($Gmie^97H>UnUCX$F7<{24V+A`Mh!%+f>=YG6Q5U+}Xz z6+mZm?gXU<&}j*17xCdUg@6U1gu=)KA{}7804-E4C}|#~5VDEGpHbV&59F^9CQUF+ zYTi=-C1l9$fnkV5{|u4$6g8tj=7W?4GwcMZ!Jpn86f9$48i-8qidfToEF{^2D_>Ch zCpx`HLo^af?+9gsC%q%PiJ0^b4ryq5j{t=_B)x-UOfwQB;LoUp8fh%Zi5rg;s9Xi7 zGt^|MjH(4QS(>#uf=2LEtinOohcIb^X;PD=7%06#uEvZ*B+Dm=WGSwh1Tr6_ESO;@ zNDaYcnF7;5WU>^eZn8`!E?FX!4W49)>?UH8B{-y^$ua>H>X2j!jxo(dkbpm<1WKeq zi(!;_L`kWjT2}^QD1aC{VY)%hH3sz+%?mV<8(!Z2jOPA~f?!qf^omm5fU+E9>z+TOg+HSZ zs#267K~`$%&nS$l6eDNCOck+80|i+KlO~u3>srzLP~8zkFp!#2A#FGC(uE9gz-K+X0ngfsSl z+HOC;!RNcxHS<9BKno3!Lfq~Gg|5AVWdTeBk%b18+iv;96&eU-gQw6yb`vp$1~{al zg+>l2)FFiiIL0({K?0z*8*-$93XO%DJCTJN7|_!fywH#Vx7|Rgp`*D$4P}`TJ~Idy z4@xE&EjJVwaUi=0tQ@*>QQImT_&^&w1}V4BoqDGf?*YTrR6aRnk-ZU>db-w-9S zjAjkU5|G+phMgb@&@3=W1MW1cWLXE(LuB%l!PN_3d1 zB32zBpN24Lg6W+gT`QV5gIfHX)k$vg8-g+pWZ=6K?B7|S7XMO2{xaGL67Oi90d4Uk z4>*7d0kAKiXO(q<9Olnx9KxgtVIrb{gmyppa<^`TV-|yIn>C2qMqRTXWDm&U!3;Y= z3h}$nUcquAOaqZQp33e13B=`igtEbtL8%O$;~`_Vpw!UOyj0Twe7BzwnDq8%#AgZt3qZ*jqven6Ow@S_ zuyT0IzX#;65GGA9O==Sh(((sS-AqCx`uT_)sHiy&WIi;#gVf+p?+yx-)1)R#NW%*}p*a(gEaxJUrMTu?konML2~tBaSX@xRo-tdPZrGUZGOS~^ zAXV`6ic;NxvK*|f1#ZEiC`AbpWToI19EwtmoCz~k#A+cZ$U>Mj!Sqg$t`*I*KrOgg zq_p4^7(kg%4K#qgb1^u~+CbO7_Q6&`tAVzABg;%uW7rGc_}u`%Q~rNwn`4KX4`lMw z+iD5aVPKm0A|vn<=rWUF1~p9vH{F$>-4V+{#4-@E6t++}m_c(5$apo79B7Q4(X69M z8N^^vu~-X|31-*{(%jLqTyrmYwNk@!(EW%Y6F}Th5aHvk2IB7o5gFZ>N}_NniH9qR#ib+(t|S4Ml2o{oWOzUYgt2l&1#Ywn|<2Y2DgR3}$L&X)iic35UnHbrQ zjhXQ#T*Y-BhSE$1M38}Q80BSRV`jVuS8|7kAqUA2c#u7Yt9Z!6P@02e2t3?hz?D1$ zxwQ>cVt@-CO<1_UgR6K0ju}i9U*IY}fy_XZI`9;-iw}~B_wj*p3Ny=o2+e!|N*@H# zOw8S`(}Wb9!KZ+Ynehc5tS))V#}My_NCe7^ zj8FI&;+;Ve0;w-c7#Sb)F~kRyAvu_t4OI6rGQ9*#B!gt2Dp%*`xGEkaUi22PT$AX7?;GV{`r zq|Cu7jg6Vn7jB9d4pTrDGBSE%Go=vhNl;+HO?k=>3Yr#Bj$vY8WGG~0e1cc!d$`Uw zAf5SnB}Mr;NDhVA{u-|t-{59^2ARQtZ2Kp?I{(6T{sO5hO$shS4nT|pmVL?!X3z4p%?JyxhEZUu5+GXL|r9j#-0?-wl z2qf{Ep#nEU5oAUNh7%OAGcqtTC@?bW z2s8MW=9FX>{s zh|K^4f(DquU2lTL_0eE^7@5prhPQxx4yv&P*_auv;Ce0a=(WbG*Bfj zj5fF&9t(C68#ALb+yF;x1~?Ejzzyzt7c8!i2iwEQsyG8nb8Zb*8`7U zZ>)O#;STpjl7}>rgcuopa5)@aas|T;2*hSU06_!7;I0qB;`&6W&%%3;9-db-aaj(}s|9e&^RQSB%W8!%!%?zY8Qk&`BzbstDaK_vJiAoEEw8|0 zIV`nT!wg4B?G13t>yYH(DYh1uS#iGvj2qvWfVV&44SLhDBLA%(S_1WwY@qTLf3O0E;rX+g8BCU>Ph7 zklPhYafLxP%sK1e2CTtmz-od9Y=IlF37Y{MaT$;cbHOgS0Xwi6u$`a*2jB+m!)Cx< zTn50y;3zz-4`T`ILYPBO!IhoBr|djj*;#zbuEJe?8Rlwuw@ZHwHYG;J z&$wJ&3vAe6DOtrZ+mwwkhw{Lcap6-Y z2v^3BPnkH})uJ$0!-wUR85u>ya5N}eVa}0-8z7C%04ah7D8mg<#Abj3K?5}4K2^iw z({`9cb>Ygi@hLNcD>J~S%mVIeGq|fkgQ=iqPXlO>ijmP2m&-e0PO^g=VuQ;NYl4Qj zzzuQ2Wr!m|LnM`8X-`~_QGmsO&wpqcoSzyy<4$_9jHV3#iJCF)22D`#lIAb%|35PasxHeC0+B`to zu(&4!t}PW++eC0!r+~B}90?Kx`@R;gtqPmAN{}{$ZBt-j-3r&%giTu`NE;U0df?hR zv1#i7X~SaMWVp5oAQe~)o(Wem4V%GJacElr*EScMwmBeeSln~T6qc?pm@|D1*vC#!MQfLFN{} zn894}$&4YSC^J1hwa62BkZBe;=0BP-IOpf3Wg-tK&w#}vj}6QWE*l2t#GIU@#N=$( zyt2%q{5+(N{sNeKLAZK;8-{>LcVC(pZGDi$_@6>FMQQ(}hu0BRO#iSYC)I+oj;POV}_tCYNNEf#-jm^YcnlD@u?IT?sZ+ zoG3$O;f6{RrCtfHUV$j}YH;-`HViH~IUb35DLKf4nxF*3$f!(|VOns*G;A2$GV>C1 zGOHkA08Il(A-@hB2}<~QkZhJxfI z=3Sd_sn zt%NHp!=emsX#-qYZ8Um^sg#kiCYm86u_zssQ{WA2xJx?VdRsB{Dlsy)V9^VA-UPVb zUYK6wE>8~@y>K_rfa{$K(+lt9l`=9;!Qx-Io9Dyz&c&v84nDoh;d+-~=v885T#Q98 z+`sGLde>mnyBeR~?Qp$YV0w|mYBLtS@UYqs*SiOs-re~0o`CB;8qMIGpIeYx1eyRt z4(lV)46YT)8Hsu6NX@rWM#jU@IJ&Ixh`0nd{5)2}l^7Y%VKZEbk?|}p!{MQQ2X6RH zWW$j|?FN$J$l}*=84eH9r*Oj`VGGiS1Pyo#H{caE16~p|;49pKPuL9jNYH@#N?7?; zQ;E{kdICV;dd+W${s1=}3Bwwc(p%>ZdbbW-59Erx4b zfKA(ckTxu~t%7S?4pM=|;0ti5o z2uFeh!C`$LuI&ysZMQ+%5VpO7h4pi|wkO!MJqBsRV%s~ow%6FSy#i^&V%t}^wof1x zSPcFRSMdXz!QXLcW2%BB(Er%9{R3&k;+~pLMh2M1%1%ZGl(hW@9NrZmVdQZXkT5vJ zCn9O?1F1qDf&r;wWb6eACnEKD-owIuCX(i9AXS)}r-FpB+PnZs^IVWBOwDsZ!dPuy zj-+`BL=_?)K+XnxZY`3kRUlQER;&aGV|CvaB+VN^sxUQg010Dt-ytN;`$4LZHGc%h z$v%)Uvdti2u(PitX}$tdg{k>6NEq4XFR(bdkEHnyNEN2$+aO`AHa|ns{1~JPQ}ZK` zFjkx2B58gFQH6*TxaU42srmp?g=ximkT6#F{X)|G9i$3V^EZ$%R`;>IMC22umy8Sy zo_PhO$UXUQurTCAQpt{2B_EPX9=s|=pemV}rC%~KfEVL1%RpJ6RTV-Y-F~IHNvTEt zX)cK+iNUEQL7*l^F;Y97kx>w&EFiHcF*mg&wa6(aKRMecH7~s+14WepNR>-!T4r7* zxO0gpH5dgUs~AN=Dx4}yQo+VUmZ2&^SI5BC#VEp^tbycEd5}(mE|3GM0tYY_=gER3 z@j6clqyoG1*q9j&zz$<#WM(o3se_IUf!DX2KwZkrWcrek!JUDTk(t>HE@loD0|mGq zNGm~q=%T2?>{aW4(17R=1vFfnEy7>msp&hmq?nEhcarU1C!K&Tif zM6E%VL8BYFb!i0>hmAeJmy0nnT7txJ1(F3^5-pHGxSD75a za;YVyMR^QOpp{dg)lUkHOm-k~^nhbzvIhx!=B1>9`@>i=0%QjRc)=KGEiyQBz(YC= z9@0@DbC5$i78)|lOmXngiie4@CBRvUU=|Y-GgA^w9a}P3jFFL3zP zeG`#mlaVO`ESQ-GDkO17F=WFEB!VGqWD*ql5I#f&m}FyStb`^3kZ;RD_V|~Upw=r~ z;4+tunXw+Kl$og!q!2l^G=oDAlx16>p~uYJ3KwgGi?u_=K(^I_41w5&t0JfYDZv|z z4ImZh*#eTjkx4dY#%`$VK~{HybV00!W_Wl9S&5Oc10;*r)*g@wbX(b&87DyPU}l;G zQh^*oQ=mR)W||5O4Uj|nK+14Bq!%QM*C7)@D$pGQ@i-eZ<7}{VK)dVaL2U=wITNG@ zv&^3X62|G2=?Gb*#12XtjEvJja(JCN2c!b0GZ%xM2}(T6LF$l0Z3Wcb%uFkxp~lR- z3NE%9F17|H#=I8BVp|7itp~F}rN#!B4z`V8F;EGy3BqDxX4(vw-2xF~WMKyGCR3xc+yy27M=Qq$07!A{Y*0kQ#<^|WpLEn3j1a=@K|AIDEu`x61!woWmYG-CPhO$5g=^_k5-d&IhcBT$O5_y9GND{WK z6>5z++!`yW;mpj|P!`A&lm)WJ24NCX&cWhdH@HEb zQ0>gjUQiauAQzB9pv}UdMfpW2J8+yqQW)D`vM__*4{k>w)MRGnASerDhY!dg>~?sA zq=>O23~omx)MRGnC@2eLM+n#;@YX-100B9ckuew~hke<45vFhA;Wi~f&1Ys#hO$65 z#ez)3SdkC0DF!5mWD~~ZT{M~kB)4L5N*dfL8Bhl>GiO3sAg82&Od}@ra^VIQK(#Y7 z7eZMegR&6@A*Wi1r?L=|$f*`2iIzEBo`5nlWFxl|=#~)34ww#<{SvMqiJ;Vyvcw$F zra9AwB-of4 zK{lASSw^+y8&V*8#5yd zk}4+9oiA8baUiK;!>Nh~Nfj4PRRTz=_;9KcK~g1zQ)rf;#4J%q)Ha2 zDrF>9ir7^#GO2(hJTlY4V@{y7%*dd`#>}XJq*o231Z!C9AgR*AsmcIJl^#x2CP=D` zaH_IEQe}oyl?{?AE1aqvkW|^>RON!C$_b|`4mN2|Mjs?qUN}_+AgS_0 zS2Y)ARxpyPK%A<=kW_`Bt6B~-D+)b4a|@hHiiZ!4zM9x1Q{6CzF=Yiousf6YzXL-jiWDMP1a*@ z)^R8cRIP3YSpjJ(_+%C%w|~!q3O&Yc2zkgR@-|T64606)7#X*MB;7J|N>Yn_QGD94 z3#@qyNFKaUj-gEqRJk!VGBhwWoB&I121$B?&MZkwOisn3U=v6|aDH+&X!!%kR(O@L z8!Q7lJ^@|HkL1Nt*GD4ChRz*%3REKu-11sRStct3+f=Ltd{61>Q%_c2Hk z;%acvBBqESsrL~`9vrl=fhEw0F(~PmFfu-bOM-k1Ek@pgEqwrzLJDKVr0Az zlENC^FTpbC;r#+6iW%OoLBbH1gKUR3M;?J}XL<#aBPzVvm>K`ULz?R)teoJ6vv^=E zHeM(T6y|?G7GMqY#~=qV{zk|{!W@xgAxZidNCCw4;BZICLz47QkUXw%{{fc-`5YzO zzk{T(hx<2>6xMKO0Nr{A?gJqgCI3O{F~gk+q!{9IknJep&IpntD%|1eT<|5LzTgLG zFYpX@0vQbT79_a%Kr+Rkeh5TZ8Pr4-0tqG|Pns!$TRxIVMv8;f5K%e_3i#PGUhpD)OSj3t$zZAQk9tkOB!}af1Tf4WRl?@g);O zyng}6{^H=0{G!Bk@S!&xEDXv@AOqN#8C6jkt7AQq8`gr=;&Q_p zuq+O1R)ZyRTeB6(n$2LfxUAU(mc`-KjbKR}ZrA{p#O;P%NN(5xR*TCG+rhFptl0*Z z#BI$1By0A8)#9>dFIX0bSNDJ=akybOSQ57zjv~3?Fjy@vHyi@X;;`l*SQ582r;w~U z0alC4n&V(u99}&Jmc;4?aI^Isk~L?*YH?X}8Z3+3q{~PqT?DJeWzq$(EDi^s2TS6% z<~ou!SHWs=S#t#}i`%3-NG9C^tHou~O|UEu2j2io;iu(~2S_D+<6$adEiW?YHnhUH+j zNX|uZ!!oce4r`WzC2?D`9?6=uV70icSp$~E;nme(NgQri1(w9^hAl{L*aTLK%MBaB zvN){S0G7mU%}yk1wu9B;vSu4t7Kc~2f+exK0o>5ri)77iuv%Q!>;lW;Ht7(ONe94c zahbFqEQ`az`@oX8tvQBd%@MF#T-F>0%i=caG?Gat!D?|h=>%93t3iy6$H9^~;*pW* z3|JaVralXnKyo{3yXhK|NwLmEs7T`(Q~N zj=Kkz#Ob)lU}-Fldjgig>A1H@j(ZJOio^a_U`d?zzXMBSvHv|-0;l~yknH~kR*EBV zzJevOIu6t{_z9NAV*f9&1Wx;zULzXS46m6O7_c|0K~^w>rLkDS0+zsO1uv2n++d|R zyvPNX#OXyourwC?`N0x6?H5O~Ulgnqrxg-lX)IPqf+cWT;e=#`1G-X_I?Em`iz5K+ zz>-*9$H-_4mUJpjOG_<+j%k7hbwTqH4g5l&VR{=R6-c8+kfU%JnViAW=$-?g!OF(W z=#AtBPq0cP-=cWI11yWf3+`Y^9A0n(OZq0F9|a6`zbjZ8pATJ-RABL;4_F$P4}+0> z7zkF0%ZCAASsb452TS7ggdbQMpC^2gRA6|5jhQhC$(;#cwYc0F50=GnC*)M$IItvE zhbS{L#v;igIRbv_Zvm1c^1y0wIU*Mi^G-0U`c$gEJ9L&;Yv1U#yTX2)PU9Ea!55;7DrfCfhBRc zvJxzb&y^KODzLe-1<937V70hh*$9@!;mQWEBo0^BgC!xZ#O8)BBsX+`)#7qPJ6INn zHEm!?+}2D)vZf!b7MC@BU|Ag2^nxWJ)?hD@dyrIM^Y08KhfD*j#pRHxU|AetJ_Rg^ z!m9vmkV7QWvnQ;x0 zLso&+;&RAJuq=+STmhEE;mYM;NqnwchNJ?+m5fYl!P2IPL#{WdA#`QXKZb1xrHg#~wm&kW^rC;YYAE78ia3OW<@N?;Avak^2p(zlbA( zxxkV*oX-iC#OHhtBo$bk&j*&q;(UIv1WxBmA~|0itQ3a}#lVvITqug90*ec!z|vS; zC=Hgt=|XKJ7ixl);s{_3up|!WtAi!+IbRJ)1s3P)fTgiGUl%Na)A{B|&Nl@s#o3YiO+>TNGhKaDF6M z5})%UkW^rCejHdDi}T~b5;&coiRAoruu=>cLOR%KU`eblRAyvMMUq8w9i)TJ$dm<^ z#^Sncumn!mO+<2CKUgV_!0iJ|VmKYr^X>&p;vB>10ZU``8MI^Gjids}cd(B6B(O9V z-%SQf;Pl-*B;U;eE5+e~*X$vDm*6EP>Phok;d?2P?&C#V)Wk7AtmxC2(4C1j&j+V5K;`cn~a! z)BdAiX)N|1154nv{~VJ2XTVBvT5%pMjm3%!U0hIQ=_V5{J{jfhBP`9kk-;Euyi@@fOtB zMRG2R8`#0JINZPnmc-!(Rzb+B4o)~JDHad=e~EQ!MnDqu;78?g7!l#x^*6&>)vFhFvp9#}0dSL%Xgakx?k zEQ!OF+F(h1uGB(Ofz6esNUk&ntHp2!2k00YMkBB!4tE%WB_Zy>u!WJy3@nYM2r&ms zAcYI+U_=y><08OHao8UYmc(g)G*}vo{V`w(oc5<7*`ESdiV--FHQ>o$NgR$#0!!j_ zTsl}9i{moD5;z@Kh~&6@uu>fM=Yb`0+Ft~g#$talSOTa0bx8KtfR*A1oNBNn4#!o2 zB_WQ(p3f?gRA5P4^6VGu(+@rERDs5Jzxo( zE}V|!!l_`TI0ASISQ3ZxCxa#NIe!w83M|f_0hY$%{Fz`0oX%g2C2_1e0bLS~ zhGk$$+-}%_#!LqnbI*DY`aj;rk zCLIII;&AX$uq1A4&LUZJ8mtzVHK)L`xJ|l*WYPt&T3jZb2g~Ac@Hwy~ZfmX~S#t%f z7MC@b!Lqnbx{YMgO|V)VPPze>#A*;D<8`nkj)cd^bO$VrrNF%lmOyelYJ2V(lH;C$ zmEy4fF<26({m;SDSnPiRmcVJhz;{rX@@oc0@orLov=0+zsOzb%se)?lSL0>=t0iPdqSVL>~vG#2~q z!4f#_cSo|{6|5Ae6&_$|ELM1eC2(31gk(hkSSb!K`hz8L+8+#-#$ta6SOTa0F-Z1D zftBL4A{H!-#fmtv1Wqf`k*r7sE5+f(6tE;t`!m4OSnSUPOW?G>5Xt_0uu_~>6oI9& zSWyg?z-dJbk`+zpN>SRAjbK?E0nh-J#OgXm#(J>JFS%zfI60lla)+`3g;x=hDl1VGUYH>Je1y~ZRL5z&c!IC)Qk&$T)SQ<;FUJI5$ zayx3fX&aK`wt$u5uzxdH5~uy!!O~dl-vO4uY5yT4`wxJX;s~7mU`ZT~+Xt4!>A1sS zX)KOA0+zt(xU)!(I}KKf!~RoXNu2hd150DE|2$X%r~NmO?7s$9iX(8Yf+ev!4%9Tb z36{oU|1GctPWvAr+5Z5n6sHxB!O~c)cmkHdX~kP4D_(<@;_%`tuq00V-+`sE*#90Z zfz$r)NcMjPE5&KW53n>AD}I6{a9W}C0ns&3_yFn}ASp$uv*f|DI08TpEQ!^1jEu5i zNqhrcGDs?r2D+RCAeS5{gQd|u2ipLmiR1-!uu5EBPy@^2aHT3(5}zwokW^r}5_Cc> zl0$UCYH>M42P})jA=+R`d=AkLvp1FSS2o38iQqV#JCYy5{DNI z!IBU!U^tMCnb8Kx4OU>axZGd~mc?O>1y~ZdH7-cjIDysTvc?fCi^Ho9U`ZTqum?** z+<<)`-wsIyMqn^9xq_u}#g;dc7d*i#ae2W5EQ`aH?qErLu5?3Ef#FKfA*M(U2?MLe z<&aRYERL`Y0ZZa=WiVJ0pDTlqRA9K0ktq@^jVmnUk-QKKR*B0CF<@C7u8amt;&Wvb zk_rr0vN1EJBRM1$tQMC;Qoyn}!ZH~wiNlpiU`d<{jS|7q_&kw-qyobej7%9|X8f+caf zvjQxQ&zq$~O$4jOWzqz&EDqoFgC%iT!^kuRERD-IGmzXc4XhHE8>WI~aahB~%s3y( zq`6?VxJ;S@mc`+l*80!!jcK{Jt5V5A^MrUhVWT!FC+$qP%sDsg#XF<2Id zD;I$!@wsv#k_rr0g3fP6a>z=sS{$LZ0xXHc9m~Oz5O-kM!pO7+ER7x(C5%jK!4gPb zN9&FvIc^JBDGvKLgC%j=za1=%#r_>&37qzyLbCq^SSgOcIS!V@;kaX9Nr>aHH&~7$ zslXC^r@_)#oPP!^fz$cdkeq)7tQ3a}FM}oVx$qK_3M?+X4wlB^!W&=-oGyHU;9V5K-*_z^6L&xIe5RA6!8 zSFkh|7k&dv;B+D5M?`P)KUgV_0R9J-#NqtEU`c$=|AV9gi}RU2f;zfboX-rF!0CKm zB0XfzySaNG@~-E5#AOZeU3q&UXb%;%w2nfTi*I&KXGs z7TfM?*~ibwEr+z8jJl$z!Es^KZj)h8L(0u zfpZ!xiNkTHz>+u}cOEQ_#c>zF5;z@q6UlMc!Af!1e+?{&)BamvX)N~N220?y{~40~ zPryoX1kPiyBo4B9d=F8m8tiX(vkfF*G_|2J3?pYwkqsleiVhEF(p4vb(4 zoX+R|gy{Hif|cTMAqQ9zp9|TMRA6x-4_F#Y0P}(+aJtYA?m}?oVh`ssGU|eK<`$0AO~g%149Ed z_!5E&kSww>3=9o$W2%viNdhUvX-pMJ7MC%#NXDds6vB;xUTea@P{PQVf+7RGcmwXv z8jvh53+j<9NCzo|TYzp%9Y_|JF-=fon3J(B#i7AMurBsu|JTE z{f!TEfV<9wdb6q;()+Oeg&W38Og)Zqt;{h+I1PGZO;? zn!-siCrtw@1lm?pavi=0O!QGv$9pcrxcJ zjzpe|&#ZY+vp|V_E*6DPV3saGQrHAih?>aegM`ph!$+9jMM!#EKnhXyE(8go>4n?7 z1W9ijNFl1;#ULSEdY2*TU5Zbk-FHOL3w{FyJt7A+a0r8r;I#b?5=MzJ9-zcVrLfO0l-#&;$LZU#n1X6DTAObi?hki3$L#TZC{ z@iH?qXMtqFaSpmX4U{=q*q9mfVWu+`d`Dz~-0wKDKpw~tv{VAIf{mH62x=B63lw5e z2(L>^krb9-Q3yA&4yuruss1~xq-*#NE9n})LrOZ3ebpdiic1npN|8%qO>l~<0?8HR z7nLCHBvxc(tOSW>79iCypr!^RV+BaOur#$4HIB+b!Ug#`@MZ%eLxTp`_%e`8X$rDQ z>R^dlkObDi0+oww%#3X??=iPS1D~0#1IhwNeO*1%+$*1}|&H$X#!nRz3O#jy#@Vq#?G z*a~JbGBWdSgR%H`z*xMyU@Yd{aMm6ei*+xQ1q$aboPo*6)B}=(Hc3IIVs-WLS7j%FDsa$;-vWH3Osse|-u{2#oA=Knjyfi;7b7 zz-b9;Hz+MZ%;M$d<>BS!<>TdN;$Hw#Ou$sQa$W&mK_`d(I2phr1%y8K^UxQi9jLfWW!7NZF zc?V`OGBUG#fZO&FDh3M0(;zP<=jUf0KeVf73fGvf~=h2L>1WMujYlEZW*=z8fNh^Eh9BvsJy zQE;Kb_#Y&J%MI*c6F@1G;|HQHX8FOyzyP%oWEKOo0AgeYNu(9!BR4-FtqeAh3|3np zfzQUw$P2a$lvbs{b}=zBvq^(ljEu}|vM?620-U7?XDPv0Y|3C36C)@cae*w&NzDV5 zVUV_Z2_qvXND#^Ku+o!}2PA>jiQG(rKbRQoT{4Rc5=)XZ-0~b8i~}q}Qwjo#@=NlQ z^K%>=Tpbz{teJU;qhnMpjXfg5vB<@WqWSAO&EZ zpz@iQ14=>)cotq(h$e_A8#ALiIJQ9TJp*uvLlU$a$V9AR$jGDtk^|>XcxQ}}Ned)c zoSK}Umr~5o2D+mibl<51Bax5T9R`T9lER zn1Z5T2PErMfNUtl2W-rYrck$o(ufgAU1}M)3Ie5NMur9ta5-xNlECT}HfBaks0qx> zR!F|Lz^MgpwLMfL$Z8vq^0cDFTzDzR$k0#%s(Tr&K~kA1C<)gNB!oP zoYnAyi9rN3D8b%{6iFE%Cu7V1=^%-MqSUm^3ZzOG5^`A}IjkWEiCIXt;N@iEECi{< z-%?>?W^9KCP6s@2I^luS1@!_bk+gu!!0CBu#tAU{nI^&_f@u;g zBA6z_B7$`)Qo!|s3`HtU!NY<*AVH+igjWUqAPJmKfK;1I>{CFh2!_^duxmlJ(0s6a zAf@{ZkY056Oa}=fxd&dl&jLwcbq^!c9FSa5YC%pVDB__FQBds&iCi{j#${j^fa<1I zU>AVOy)|&wIyh?soV5|k0>$BCkoo8?T?7)u=F+7g39K%KI0p;K!pq9Yx)P)hlv3Kn z7?2tvY|Mb|Y_DM~t~YSjI~a@iJ)HFc z#^U-2V{v?jv%bJsykB7~)}K%oC`D`m#T9yr*bEZHmLj%+B(SCkMy4Ggxs=S}1}_^U+dhyYl)fQ5wB^gq%frNT2qcX^r$a1eWIYa2 znpc|Z1nQL{)%dI@KoZa{qZ_#1M3y}Ql7-e_P;pT2m-Q$}97_)uT4uBHvNN)u2dOD7 zPW1$hY!ow~G?u^}TTo||iRTvYC zi6l_iF|j`+LJKo5XiSgcC!{CB%*^-`S^_aM{REXjkh1(Q$Rzaq@CPJ_EkFDRNnp(n zAlI=mGqOXi17$UqpG*u4=teVx1hE;-29m&PG$RuSNDf;y!N$xefMg>tNFBP3JRm`A zHu8fcu-eGR%qWUvtPn^cy0L;FK_p}0^{)s>0@+vwh6eZ`rX-TFVjzX!_8YYMYYuMy zN`Qos^)n*rmqpSq1yY!kpPZNj&yw)ImJCP^t09a`av(WKp#s+k%`0rojEYD$D1cOA zH3f77Jd#2su)@sT)cjKL02tgIDqsoJ0e*O3Xd;=Q23Cm01P!nR4ij{sCNMMW!c(^% zG<7qx8~ubfb=i%7LYunmCO@G~T~?c)kbX5Yhb@f7Y6oV4#!T$NEJj9VE=L%P*%{1& z}v5pv6Bx(EXUqyfgrZU9n{m041PS_MGLJn)bOBfB9;O-gD` zVkM|Q0*xb334mNynSvA%C_cb_Nj7FicX)Vtz{ATE9A1!Kq#MXAtPu|K6&o|757Yoq z{`SVA_#tTUg^7)s(GRMSnaLj(3rqp9SYQf-$3ieTOd+-_fCofCEkS68cmd83zBugx zISLY#R+`=dds2-+VHw?6@H ze(OEd{K@RAAkSc;6ErL6%81AeRxU)*(&MHT8Rw2k_ zv;cwl6WRVUkSc=qSHkVDg4^fetmd*YGj<^DB2lr7w+(#3Ue6$7>$jBo!3&Clx8>c@y2 z?D9`#M#g0j!D1A_r4T{nlmS`^#>)f>e>NUQE(TDhWMJTq6BXT}{Y))cVUg?H=B-CG zkJwIRVqjo!wu%WYPAw{qNy^O0iE+s<&&$bAOeu~@PcO*V%}p#WNiB*=D$UGEi775h zj&XMn@YhSpEQ$$A%}GrxPK5{*q$Dv&@J}|LVm#G&n(=hw8OAe>XBp2no?|@Mc%Jcm z;|0bGjb*s5YPacp*4eFhTz{FtNrM*#cZ_}*$uh8uHY{LZU}#t9Q<$tUUE!F*X@%*E za}?(*Zc$vXctCNV;z`A?ia!*8EB;e#P-<4{RO(Ths5Dt=n$irVSxV=X<|u8^nX7bP zZ=TXjo%u>rbrvek)LpFfSAU7pVZEhFSGAWbeb!m2^ul1Z(r&%AN`1QPl}_nwR9dFH zN$HyIW~F1gTa@PLZdJOgwN2@n-gc!8Iy;np>F-qfZLmw}zrk*$5BhtQ4(jezdaSok z>95v)rPVqIlzwR)RN7#0NU25lu+kg-BT6$2k1CzeJEpWu=eSa<;U%RzN;j3-bp9$e zDK{whD$h|~pgd1`vhH@}eabtOPbeQ#Zqqogd|mmD@&o0&$}f~(D}PY_s{C8IS*2B_ zL#0b)mdYHJr7Fu+HmGb;IjeG2<%Y@|m9HwZG`^|)Q)yN0QJttdPj$NLSM?dHOH^m7 zu2)^5dQM}d>JyDss)saItF~yaQQe`sR&~9`KGjaG)2e^e&Zs_6y{Ouw{#f;|YKz(f zwN|wWYTatH)uyZc)0m<5MPsJgNsW1Gm-M%(b!r|}YgNChHckDS+6wjSYU|Z+s2x70)YPRJ^QsRq?vwO~p5gUlqTBbJ!nn9&1!;R%%mf zSLy)gwSJ`BHb-f$(mbX4N(+@1D=kr4sP zly)lZQrfMwM`^FpKBfIi2b2yf9a1{1bVTW>(lMpuO6Qd>DP2{%rgTH;rqUgy2TD(r zo-4gkdZ+Y3>5I}gr5{SalzuDyRr;^gpxmU~s@$gBsobmFuRKwClJXSgY0A@;XDZK9 zo~=Abd7knDf=4Ju74u-w7p8daNAn^jv>A^Cce>J-)Ksxwq)s?JiK zqdHG@f$AdFC92C+SE#O3U8TBObqy$At8P-=p}I?Tx9VQieX9Fa52zkgJ*0X>^{DDG z)f1{GRZpp&Rz0J7R`r7FMb%5HcU2##K309A`b_nW>POX2s-IQAss2>`tNLHHL9J1( zNv&C}MXgn>O|3(%Tdh~EPi=zQB(=$EQ`DxZO;?+tHdAf3+FZ4HYV*~Ws4Y`luC_vL zrP^w>HEQeBHmYq_+p4xrZM)h|wOwj^)DEZ}R6DG8RPBV?DYesTXVuQDT~xcGc2(_~ z+I6)XYB$wxsohn3p!P`ZvDy>0w`w2NKCAsv`=|C_tx>&6y;Z$ky+gfIy+^%IyQmIGsn1ZKsXj}6w)!0Px$5)P7pgB-U#h-BeYN@;^|k8j)iZjGus-IWCsD4@fhWZ`#`|1zWAF4l6f2{sQ{h9g; z^;hbz)!(asRR5~}UHzx}FZJK*f7Sn~H)u3zG;6eIv}tr`bZSi0n65EHW0uAojd>dL zH5OYVWtkGDnu~B1_#uklj8ap(0Y3$M1r*S~zkj4>>qZ-FG zPHLRdIHz$z_@ePmvovRG&efc+xj=KF<|56-noBj8X)f37)Vis4SL=b+6Rqc3ueIK3ebD--^-b%S z)?cj#?Pl#Z?GEiu?QZQJ?FrhGwWn#%)SjcgKzph7dhJcxTeNp+@72Dl{aCwAr$eVl zr%wk|YERXfsWV4sp3Z!oMLJ7#mg%h4*`TvYXN%4uont!3bx!G=(>bqmS?9LSJ)H+S zpLIZG`G1`jT~K-6r#o49n(j>9IlA+7=j$%iU8cKIcfIaL-F>?ibxgy(YcsdMosH>+RP&tan21wB9AX%X*+%;f~&2z59BP z^`7Z{(fhC0s^6vGufI@#t^RTSQ~GE1&+A{(zpDR8|Ec~n{TKRg^grl-)BmOaSHII> znZXK!RR$XjK()mSgI5Nx4c-`h1lJkA4gMRn8g>|h>W+zqQw(Pq&Np0axYcmG;eNw| z;Ckc&xF)#=u1j8lYm;x_`s6>jM(H%_0oN*XjTV6GmDNU@jkX!>Fxq8w!052iF{3+1 z_lEjC`?wEs4zuglEPGl z$qLgHrYKBTn5r;CVXDGRg=q@26s9Z8R+ynMM`5PIT!mQ*^Au()%vYGBus~t1!a{|4 z3X2rxD=b!6ps++?p~6yyMGDIl7Aq`QSfa2(VX4AOg=Gq>6qYNjR#>61Mq#DGT7^{# z>l9WitXEj0ut8z1!bXL43Y!$xD{NNSps+<@qrz5&O$yr-HY;pb*rKpQVXMMUg>4GE z6t*kuR@kAiM`5SJUWHu>`xJI7>{r;Ma6nMxj~ZtU|NGIfau7=M_#VTu?Zza8com!X<^X z3YQhmDO^!FuW(i2g2FY0iwf5jE-BnlxU6tf;flg7g{um;6|O1VQMj&fSK)@jJ%yVJ z_Z4m_JW#l;@KE87!Xt&d3Xc`;DLhfQukcjifxvT9o8n}}cEu@*9g0&GFDpz_yrM8&u~Tt|Vwd7f#Wf1E6xS-uR_s=squ8T3 zSFuNNo?@@!e8oP+1&aNO3l%3QE>fJRxL9$L;u6Klic1xzC@xc+s<>Qnn&Jw@>53~A zXDF^xoT<24ahBp5#o3B$73V0fQ=F@~UU8n{2F3Y`8x*X;#0*_iq8~J zD?V2|qxeGcjN(hhvx=`2&ndoEJg@jh@q*%8#S4n>6fY{iSG=V7LGiNUN5w0OpA@es zepbAy_(k!W;#bA%ir*A(D1KMGsrWQ$bcZ!pg-YZU4`k**PX}ZExrRfUOls+m>SNfzl zL+P{POr_6?vy{Fl&Q|)WI7jK5;#{Tgiu06yD9%^7U|KrT>b{lp2(lD>W*uP-;?Isno2rN~uL@wNk6n8l^U+wMy+u>y$c_)+==?ZBXh` z+Njj6v`MK)X|qzV(iWvYrL9W+O52nsC~a4osI)_AlG0A4$x6GFrYP-JnyR!%X`0er zrRhrhlx8UHSDLAGKxvlJL8aMBhm__h9afsFbVO;M(ov=PO2?EIC>>W?sB}VUky&OQtyj9Ev_a{v(j0|*N^=zMD{WMIptMQpq0(lh zM@n0i9xH8CdZM&V>8a9Mg=b3J6`m_?S9+neL+Pc`PNi2$JC$B5?NWN9v|H(|(jKLE zN_&;wEA3PIptN78sKqrEf}ymA)$-QTm~DROzSEKBZqu z$CQ36ZCCoEv|Qn@(s8AKN+*>5E1gtoP(G#9sC-(fN%@RYv+_KJ7Ug*gt;%PW+LX^J zwJV=j>QKI*)Tw+?sZ05iQn&JDr5@!gO1;WgmHL#gD)lQjDojwGtT0h|mck_EYf6)q zuPaSazM(W#`KHn|qtYhjPfDAWKPzof{-U&1`K!`4|`zm1ihFP@bv$PX+@-Qxxm#toa*xU$1edD@;(?uRKxZfbt}jgUXXt4k=GjIjlTY<%se$m7~hjRgNjoP&uwVQ{{y6ER~bW zvsJb$&rvz0JXhtE@;sH(%JWsuC@)YstGrO#Q zRW2*9P`RwUQss*BDwV6st5vQkuTiQ{}AAEtL+9+bZXD?x>vCxvSEmdQato&V7|XS`Sn%>O54rr1MDSvd&|bD>_e9 zuIfBhxu)|><+{#ul^Z%QRBr0LRJo<|O69iBYn2X-H!62@-l}w~yi@5`d9Sic;e*O7 z?T;$6wLhuM(f+J*P5X<=b?vVzcXht0+|&84a$o0%$^)IBDi3vjsXWs8t@2pskIECB zzba34{;53E`LFU!r$P0(PNV7zohH?nI?bxf6kAkZ>9nf8)@f6HqtmYXR;NStold9f zdz~)T4?5kdA9Z?EKk4+Ue$wev{jAfk`bB4g>Q|kKs(Z91sqWR9th!HYit2u?sj54a zr>X8xp00X8YliAUt(mHav}UOu)|#z)L~D-fQLVYE$F%0D9@m<$dR%LP>ItodswcG; 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%0AQgV<7H9-l6kx`l`!<68L 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

$vf=_*DOM{O8P9_yA?XZDD!Kxe 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 z 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

AXg$vLfFuM7sz0c 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 literal 0 HcmV?d00001 diff --git a/vendor/ggpo/LICENSE b/vendor/ggpo/LICENSE new file mode 100644 index 000000000..49e89062c --- /dev/null +++ b/vendor/ggpo/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2009-2019 GroundStorm Studios, LLC. (http://ggpo.net) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/ggpo/ggpo.odin b/vendor/ggpo/ggpo.odin new file mode 100644 index 000000000..c727e4a67 --- /dev/null +++ b/vendor/ggpo/ggpo.odin @@ -0,0 +1,526 @@ +package ggpo + +foreign import lib "GGPO.lib" + +import c "core:c/libc" + +Session :: distinct rawptr + +MAX_PLAYERS :: 4 +MAX_PREDICTION_FRAMES :: 8 +MAX_SPECTATORS :: 32 + +SPECTATOR_INPUT_INTERVAL :: 4 + +PlayerHandle :: distinct c.int +PlayerType :: enum c.int { + LOCAL, + REMOTE, + SPECTATOR, +} + +/* + * The Player structure used to describe players in add_player + * + * size: Should be set to the size_of(Player) + * + * type: One of the PlayerType values describing how inputs should be handled + * Local players must have their inputs updated every frame via + * add_local_inputs. Remote players values will come over the + * network. + * + * player_num: The player number. Should be between 1 and the number of players + * In the game (e.g. in a 2 player game, either 1 or 2). + * + * If type == PLAYERTYPE_REMOTE: + * + * remote.ip_address: The ip address of the ggpo session which will host this + * player. + * + * remote.port: The port where udp packets should be sent to reach this player. + * All the local inputs for this session will be sent to this player at + * ip_address:port. + * + */ + + +Player :: struct { + size: c.int, + type: PlayerType, + player_num: c.int, + using u: struct #raw_union { + local: struct {}, + remove: struct { + ip_address: [32]byte, + port: u16, + }, + }, +} + +LocalEndpoint :: struct { + player_num: c.int, +} + +ErrorCode :: enum c.int { + OK = 0, + SUCCESS = 0, + GENERAL_FAILURE = -1, + INVALID_SESSION = 1, + INVALID_PLAYER_HANDLE = 2, + PLAYER_OUT_OF_RANGE = 3, + PREDICTION_THRESHOLD = 4, + UNSUPPORTED = 5, + NOT_SYNCHRONIZED = 6, + IN_ROLLBACK = 7, + INPUT_DROPPED = 8, + PLAYER_DISCONNECTED = 9, + TOO_MANY_SPECTATORS = 10, + INVALID_REQUEST = 11, +} + +INVALID_HANDLE :: PlayerHandle(-1) + +/* + * The EventCode enumeration describes what type of event just happened. + * + * CONNECTED_TO_PEER - Handshake with the game running on the + * other side of the network has been completed. + * + * SYNCHRONIZING_WITH_PEER - Beginning the synchronization + * process with the client on the other end of the networking. The count + * and total fields in the u.synchronizing struct of the Event + * object indicate progress. + * + * SYNCHRONIZED_WITH_PEER - The synchronziation with this + * peer has finished. + * + * RUNNING - All the clients have synchronized. You may begin + * sending inputs with synchronize_inputs. + * + * DISCONNECTED_FROM_PEER - The network connection on + * the other end of the network has closed. + * + * TIMESYNC - The time synchronziation code has determined + * that this client is too far ahead of the other one and should slow + * down to ensure fairness. The u.timesync.frames_ahead parameter in + * the Event object indicates how many frames the client is. + * + */ +EventCode :: enum c.int { + CONNECTED_TO_PEER = 1000, + SYNCHRONIZING_WITH_PEER = 1001, + SYNCHRONIZED_WITH_PEER = 1002, + RUNNING = 1003, + DISCONNECTED_FROM_PEER = 1004, + TIMESYNC = 1005, + CONNECTION_INTERRUPTED = 1006, + CONNECTION_RESUMED = 1007, +} + +/* + * The Event structure contains an asynchronous event notification sent + * by the on_event callback. See EventCode, above, for a detailed + * explanation of each event. + */ + + Event :: struct { + code: EventCode, + using u: struct #raw_union { + connected: struct { + player: PlayerHandle, + }, + synchronizing: struct { + player: PlayerHandle, + count: c.int, + total: c.int, + }, + synchronized: struct { + player: PlayerHandle, + }, + disconnected: struct { + player: PlayerHandle, + }, + timesync: struct { + frames_ahead: c.int, + }, + connection_interrupted: struct { + player: PlayerHandle, + disconnect_timeout: c.int, + }, + connection_resumed: struct { + player: PlayerHandle, + }, + }, +} + +/* + * The SessionCallbacks structure contains the callback functions that + * your application must implement. GGPO.net will periodically call these + * functions during the game. All callback functions must be implemented. + */ +SessionCallbacks :: struct { + /* + * begin_game callback - This callback has been deprecated. You must + * implement it, but should ignore the 'game' parameter. + */ + begin_game: proc "c" (game: cstring) -> bool, + + /* + * save_game_state - The client should allocate a buffer, copy the + * entire contents of the current game state into it, and copy the + * length into the len parameter. Optionally, the client can compute + * a checksum of the data and store it in the checksum argument. + */ + save_game_state: proc "c" (buffer: ^[^]byte, len: ^c.int, checksum: ^c.int, frame: c.int) -> bool, + + /* + * load_game_state - GGPO.net will call this function at the beginning + * of a rollback. The buffer and len parameters contain a previously + * saved state returned from the save_game_state function. The client + * should make the current game state match the state contained in the + * buffer. + */ + load_game_state: proc "c" (buffer: [^]byte, len: c.int) -> bool, + + /* + * log_game_state - Used in diagnostic testing. The client should use + * the log function to write the contents of the specified save + * state in a human readible form. + */ + log_game_state: proc "c" (filename: cstring, buffer: [^]byte, len: c.int) -> bool, + + /* + * free_buffer - Frees a game state allocated in save_game_state. You + * should deallocate the memory contained in the buffer. + */ + free_buffer: proc "c" (buffer: rawptr), + + /* + * advance_frame - Called during a rollback. You should advance your game + * state by exactly one frame. Before each frame, call synchronize_input + * to retrieve the inputs you should use for that frame. After each frame, + * you should call advance_frame to notify GGPO.net that you're + * finished. + * + * The flags parameter is reserved. It can safely be ignored at this time. + */ + advance_frame: proc "c" (flags: c.int) -> bool, + + /* + * on_event - Notification that something has happened. See the EventCode + * structure above for more information. + */ + on_event: proc "c" (info: ^Event) -> bool, +} + +/* + * The NetworkStats function contains some statistics about the current + * session. + * + * network.send_queue_len - The length of the queue containing UDP packets + * which have not yet been acknowledged by the end client. The length of + * the send queue is a rough indication of the quality of the connection. + * The longer the send queue, the higher the round-trip time between the + * clients. The send queue will also be longer than usual during high + * packet loss situations. + * + * network.recv_queue_len - The number of inputs currently buffered by the + * GGPO.net network layer which have yet to be validated. The length of + * the prediction queue is roughly equal to the current frame number + * minus the frame number of the last packet in the remote queue. + * + * network.ping - The roundtrip packet transmission time as calcuated + * by GGPO.net. This will be roughly equal to the actual round trip + * packet transmission time + 2 the interval at which you call idle + * or advance_frame. + * + * network.kbps_sent - The estimated bandwidth used between the two + * clients, in kilobits per second. + * + * timesync.local_frames_behind - The number of frames GGPO.net calculates + * that the local client is behind the remote client at this instant in + * time. For example, if at this instant the current game client is running + * frame 1002 and the remote game client is running frame 1009, this value + * will mostly likely roughly equal 7. + * + * timesync.remote_frames_behind - The same as local_frames_behind, but + * calculated from the perspective of the remote player. + * + */ +NetworkStats :: struct { + network: struct { + send_queue_len: c.int, + recv_queue_len: c.int, + ping: c.int, + kbps_sent: c.int, + }, + timesync: struct { + local_frames_behind: c.int, + remote_frames_behind: c.int, + }, +} + +@(default_calling_convention="c") +@(link_prefix="ggpo_") +foreign lib { + /* + * start_session -- + * + * Used to being a new GGPO.net session. The ggpo object returned by start_session + * uniquely identifies the state for this session and should be passed to all other + * functions. + * + * session - An out parameter to the new ggpo session object. + * + * cb - A SessionCallbacks structure which contains the callbacks you implement + * to help GGPO.net synchronize the two games. You must implement all functions in + * cb, even if they do nothing but 'return true'; + * + * game - The name of the game. This is used internally for GGPO for logging purposes only. + * + * num_players - The number of players which will be in this game. The number of players + * per session is fixed. If you need to change the number of players or any player + * disconnects, you must start a new session. + * + * input_size - The size of the game inputs which will be passsed to add_local_input. + * + * local_port - The port GGPO should bind to for UDP traffic. + */ + start_session :: proc(session: ^^Session, + cb: ^SessionCallbacks, + game: cstring, + num_players: c.int, + input_size: c.int, + localport: u16) -> ErrorCode --- + + + /* + * add_player -- + * + * Must be called for each player in the session (e.g. in a 3 player session, must + * be called 3 times). + * + * player - A Player struct used to describe the player. + * + * handle - An out parameter to a handle used to identify this player in the future. + * (e.g. in the on_event callbacks). + */ + add_player :: proc(session: ^Session, + player: ^Player, + handle: ^PlayerHandle) -> ErrorCode --- + + + /* + * start_synctest -- + * + * Used to being a new GGPO.net sync test session. During a sync test, every + * frame of execution is run twice: once in prediction mode and once again to + * verify the result of the prediction. If the checksums of your save states + * do not match, the test is aborted. + * + * cb - A SessionCallbacks structure which contains the callbacks you implement + * to help GGPO.net synchronize the two games. You must implement all functions in + * cb, even if they do nothing but 'return true'; + * + * game - The name of the game. This is used internally for GGPO for logging purposes only. + * + * num_players - The number of players which will be in this game. The number of players + * per session is fixed. If you need to change the number of players or any player + * disconnects, you must start a new session. + * + * input_size - The size of the game inputs which will be passsed to add_local_input. + * + * frames - The number of frames to run before verifying the prediction. The + * recommended value is 1. + * + */ + start_synctest :: proc(session: ^^Session, + cb: ^SessionCallbacks, + game: cstring, + num_players: c.int, + input_size: c.int, + frames: c.int) -> ErrorCode --- + + + /* + * start_spectating -- + * + * Start a spectator session. + * + * cb - A SessionCallbacks structure which contains the callbacks you implement + * to help GGPO.net synchronize the two games. You must implement all functions in + * cb, even if they do nothing but 'return true'; + * + * game - The name of the game. This is used internally for GGPO for logging purposes only. + * + * num_players - The number of players which will be in this game. The number of players + * per session is fixed. If you need to change the number of players or any player + * disconnects, you must start a new session. + * + * input_size - The size of the game inputs which will be passsed to add_local_input. + * + * local_port - The port GGPO should bind to for UDP traffic. + * + * host_ip - The IP address of the host who will serve you the inputs for the game. Any + * player partcipating in the session can serve as a host. + * + * host_port - The port of the session on the host + */ + start_spectating :: proc(session: ^^Session, + cb: ^SessionCallbacks, + game: cstring, + num_players: c.int, + input_size: c.int, + local_port: u16, + host_ip: cstring, + host_port: u16) -> ErrorCode --- + + /* + * close_session -- + * Used to close a session. You must call close_session to + * free the resources allocated in start_session. + */ + close_session :: proc(session: ^Session) -> ErrorCode --- + + + /* + * set_frame_delay -- + * + * Change the amount of frames ggpo will delay local input. Must be called + * before the first call to synchronize_input. + */ + set_frame_delay :: proc(session: ^Session, + player: PlayerHandle, + frame_delay: c.int) -> ErrorCode --- + + /* + * idle -- + * Should be called periodically by your application to give GGPO.net + * a chance to do some work. Most packet transmissions and rollbacks occur + * in idle. + * + * timeout - The amount of time GGPO.net is allowed to spend in this function, + * in milliseconds. + */ + idle :: proc(session: ^Session, + timeout: c.int) -> ErrorCode --- + + /* + * add_local_input -- + * + * Used to notify GGPO.net of inputs that should be trasmitted to remote + * players. add_local_input must be called once every frame for + * all player of type PLAYERTYPE_LOCAL. + * + * player - The player handle returned for this player when you called + * add_local_player. + * + * values - The controller inputs for this player. + * + * size - The size of the controller inputs. This must be exactly equal to the + * size passed into start_session. + */ + add_local_input :: proc(session: ^Session, + player: PlayerHandle, + values: rawptr, + size: c.int) -> ErrorCode --- + + /* + * synchronize_input -- + * + * You should call synchronize_input before every frame of execution, + * including those frames which happen during rollback. + * + * values - When the function returns, the values parameter will contain + * inputs for this frame for all players. The values array must be at + * least (size * players) large. + * + * size - The size of the values array. + * + * disconnect_flags - Indicated whether the input in slot (1 << flag) is + * valid. If a player has disconnected, the input in the values array for + * that player will be zeroed and the i-th flag will be set. For example, + * if only player 3 has disconnected, disconnect flags will be 8 (i.e. 1 << 3). + */ + synchronize_input :: proc(session: ^Session, + values: rawptr, + size: c.int, + disconnect_flags: ^c.int) -> ErrorCode --- + + /* + * disconnect_player -- + * + * Disconnects a remote player from a game. Will return ERRORCODE_PLAYER_DISCONNECTED + * if you try to disconnect a player who has already been disconnected. + */ + disconnect_player :: proc(session: ^Session, + player: PlayerHandle) -> ErrorCode --- + + /* + * advance_frame -- + * + * You should call advance_frame to notify GGPO.net that you have + * advanced your gamestate by a single frame. You should call this everytime + * you advance the gamestate by a frame, even during rollbacks. GGPO.net + * may call your save_state callback before this function returns. + */ + advance_frame :: proc(session: ^Session) -> ErrorCode --- + + /* + * get_network_stats -- + * + * Used to fetch some statistics about the quality of the network connection. + * + * player - The player handle returned from the add_player function you used + * to add the remote player. + * + * stats - Out parameter to the network statistics. + */ + get_network_stats :: proc(session: ^Session, + player: PlayerHandle, + stats: ^NetworkStats) -> ErrorCode --- + + /* + * set_disconnect_timeout -- + * + * Sets the disconnect timeout. The session will automatically disconnect + * from a remote peer if it has not received a packet in the timeout window. + * You will be notified of the disconnect via a EVENTCODE_DISCONNECTED_FROM_PEER + * event. + * + * Setting a timeout value of 0 will disable automatic disconnects. + * + * timeout - The time in milliseconds to wait before disconnecting a peer. + */ + set_disconnect_timeout :: proc(session: ^Session, + timeout: c.int) -> ErrorCode --- + + /* + * set_disconnect_notify_start -- + * + * The time to wait before the first EVENTCODE_NETWORK_INTERRUPTED timeout + * will be sent. + * + * timeout - The amount of time which needs to elapse without receiving a packet + * before the EVENTCODE_NETWORK_INTERRUPTED event is sent. + */ + set_disconnect_notify_start :: proc(session: ^Session, + timeout: c.int) -> ErrorCode --- + + /* + * log -- + * + * Used to write to the ggpo.net log. In the current versions of the + * SDK, a log file is only generated if the "quark.log" environment + * variable is set to 1. This will change in future versions of the + * SDK. + */ + log :: proc(session: ^Session, fmt: cstring, #c_vararg args: ..any) --- + /* + * logv -- + * + * A varargs compatible version of log. See log for + * more details. + */ + logv :: proc(session: ^Session, fmt: cstring, args: c.va_list) --- +} \ No newline at end of file From 37c6279031897d84e729c3a1902e6ac9cb6da5e7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 9 May 2022 23:33:00 +0100 Subject: [PATCH 183/245] Add ggpo to examples/all/all_vendor.odin --- examples/all/all_vendor.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/all/all_vendor.odin b/examples/all/all_vendor.odin index e4603a84f..7da2e501b 100644 --- a/examples/all/all_vendor.odin +++ b/examples/all/all_vendor.odin @@ -2,6 +2,7 @@ package all import botan "vendor:botan" import ENet "vendor:ENet" +import ggpo "vendor:ggpo" import gl "vendor:OpenGL" import glfw "vendor:glfw" import microui "vendor:microui" @@ -24,6 +25,7 @@ import CA "vendor:darwin/QuartzCore" _ :: botan _ :: ENet +_ :: ggpo _ :: gl _ :: glfw _ :: microui From 8559790bd8e9e69187566ab3fa7855bbba2e7ec3 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 10 May 2022 20:02:39 +0200 Subject: [PATCH 184/245] Fix ; typo. --- core/intrinsics/intrinsics.odin | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 7e75aecc4..85859e8c3 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -87,20 +87,20 @@ atomic_load :: proc(dst: ^$T) -> T --- atomic_load_explicit :: proc(dst: ^$T, order: Atomic_Memory_Order) -> T --- // fetch then operator -atomic_add :: proc(dst; ^$T, val: T) -> T --- -atomic_add_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_sub :: proc(dst; ^$T, val: T) -> T --- -atomic_sub_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_and :: proc(dst; ^$T, val: T) -> T --- -atomic_and_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_nand :: proc(dst; ^$T, val: T) -> T --- -atomic_nand_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_or :: proc(dst; ^$T, val: T) -> T --- -atomic_or_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_xor :: proc(dst; ^$T, val: T) -> T --- -atomic_xor_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_exchange :: proc(dst; ^$T, val: T) -> T --- -atomic_exchange_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_add :: proc(dst: ^$T, val: T) -> T --- +atomic_add_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_sub :: proc(dst: ^$T, val: T) -> T --- +atomic_sub_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_and :: proc(dst: ^$T, val: T) -> T --- +atomic_and_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_nand :: proc(dst: ^$T, val: T) -> T --- +atomic_nand_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_or :: proc(dst: ^$T, val: T) -> T --- +atomic_or_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_xor :: proc(dst: ^$T, val: T) -> T --- +atomic_xor_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_exchange :: proc(dst: ^$T, val: T) -> T --- +atomic_exchange_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) -> T --- atomic_compare_exchange_strong :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- atomic_compare_exchange_strong_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok --- From d48d3bfa87f8f944c7bb96a1efe298beaaa9c1cf Mon Sep 17 00:00:00 2001 From: Thimilius Date: Wed, 11 May 2022 13:12:07 +0200 Subject: [PATCH 185/245] Fix join_multiple typo --- core/thread/thread.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/thread/thread.odin b/core/thread/thread.odin index d1b95a2fd..90230ae75 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -53,7 +53,7 @@ join :: proc(thread: ^Thread) { } -join_mulitple :: proc(threads: ..^Thread) { +join_multiple :: proc(threads: ..^Thread) { _join_multiple(..threads) } From dca2fbccffd22b47cdb89e56170f3dae9a6257ad Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 11 May 2022 12:15:10 +0100 Subject: [PATCH 186/245] Improve ternary if type inference --- src/check_expr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 336a711d4..f578f8c73 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7241,7 +7241,11 @@ ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *t node->viral_state_flags |= te->x->viral_state_flags; if (te->y != nullptr) { - check_expr_or_type(c, &y, te->y, type_hint); + Type *th = type_hint; + if (type_hint == nullptr && is_type_typed(x.type)) { + th = x.type; + } + check_expr_or_type(c, &y, te->y, th); node->viral_state_flags |= te->y->viral_state_flags; } else { error(node, "A ternary expression must have an else clause"); From b4df272eb5ca8b43a47ad0f70dff19dc98563642 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 11 May 2022 12:15:37 +0100 Subject: [PATCH 187/245] Improve -vet shadowing to allow `x := x if cond else y` etc --- src/checker.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index fdd75126f..d186163e4 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -544,6 +544,28 @@ GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) { return token_pos_cmp(x->token.pos, y->token.pos); } +bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) { + Ast *init = unparen_expr(expr); + if (init == nullptr) { + return false; + } + if (init->kind == Ast_Ident) { + // TODO(bill): Which logic is better? Same name or same entity + // bool ignore = init->Ident.token.string == name; + bool ignore = init->Ident.entity == shadowed; + if (ignore) { + return true; + } + } else if (init->kind == Ast_TernaryIfExpr) { + bool x = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.x); + bool y = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.y); + if (x || y) { + return true; + } + } + + return false; +} bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { @@ -594,17 +616,14 @@ bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) { } // NOTE(bill): Ignore intentional redeclaration - // x := x; + // x := x // Suggested in issue #637 (2020-05-11) + // Also allow the following + // x := x if cond else y + // x := z if cond else x if ((e->flags & EntityFlag_Using) == 0 && e->kind == Entity_Variable) { - Ast *init = unparen_expr(e->Variable.init_expr); - if (init != nullptr && init->kind == Ast_Ident) { - // TODO(bill): Which logic is better? Same name or same entity - // bool ignore = init->Ident.token.string == name; - bool ignore = init->Ident.entity == shadowed; - if (ignore) { - return false; - } + if (check_vet_shadowing_assignment(c, shadowed, e->Variable.init_expr)) { + return false; } } From 56e3b7cb7d96a467ace98ebdca11d2baeef0a8c0 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 11 May 2022 13:43:29 +0200 Subject: [PATCH 188/245] Fix join on *nix. --- core/thread/thread_unix.odin | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 8452df112..3897f6100 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -7,6 +7,8 @@ import "core:intrinsics" import "core:sync" import "core:sys/unix" +CAS :: intrinsics.atomic_compare_exchange_strong + Thread_State :: enum u8 { Started, Joined, @@ -98,7 +100,7 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ } _start :: proc(t: ^Thread) { - sync.guard(&t.mutex) + // sync.guard(&t.mutex) t.flags += { .Started } sync.signal(&t.cond) } @@ -108,15 +110,22 @@ _is_done :: proc(t: ^Thread) -> bool { } _join :: proc(t: ^Thread) { - sync.guard(&t.mutex) + // sync.guard(&t.mutex) - if .Joined in t.flags || unix.pthread_equal(unix.pthread_self(), t.unix_thread) { + if unix.pthread_equal(unix.pthread_self(), t.unix_thread) { return } - unix.pthread_join(t.unix_thread, nil) + // Preserve other flags besides `.Joined`, like `.Started`. + unjoined := intrinsics.atomic_load(&t.flags) - {.Joined} + joined := unjoined + {.Joined} - t.flags += { .Joined } + // Try to set `t.flags` from unjoined to joined. If it returns joined, + // it means the previous value had that flag set and we can return. + if res, ok := CAS(&t.flags, unjoined, joined); res == joined && !ok { + return + } + unix.pthread_join(t.unix_thread, nil) } _join_multiple :: proc(threads: ..^Thread) { From 8fb718245a76cc9daa45122e6e6990f558b14de7 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 11 May 2022 15:52:04 +0200 Subject: [PATCH 189/245] Implement pthread_cancel. --- core/sys/unix/pthread_darwin.odin | 13 +++++++++++++ core/sys/unix/pthread_freebsd.odin | 10 +++++++++- core/sys/unix/pthread_linux.odin | 9 +++++++++ core/sys/unix/pthread_openbsd.odin | 11 ++++++++++- core/thread/thread_unix.odin | 11 ++++++++++- examples/demo/demo.odin | 29 ++++++++++++++++++++++++++++- 6 files changed, 79 insertions(+), 4 deletions(-) diff --git a/core/sys/unix/pthread_darwin.odin b/core/sys/unix/pthread_darwin.odin index 542a550cb..e138b8610 100644 --- a/core/sys/unix/pthread_darwin.odin +++ b/core/sys/unix/pthread_darwin.odin @@ -81,3 +81,16 @@ PTHREAD_MUTEX_NORMAL :: 0 PTHREAD_MUTEX_RECURSIVE :: 1 PTHREAD_MUTEX_ERRORCHECK :: 2 +PTHREAD_CANCEL_ENABLE :: 0 +PTHREAD_CANCEL_DISABLE :: 1 +PTHREAD_CANCEL_DEFERRED :: 0 +PTHREAD_CANCEL_ASYNCHRONOUS :: 1 + +foreign import pthread "System.framework" + +@(default_calling_convention="c") +foreign pthread { + pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int --- + pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int --- + pthread_cancel :: proc (thread: pthread_t) -> c.int --- +} \ No newline at end of file diff --git a/core/sys/unix/pthread_freebsd.odin b/core/sys/unix/pthread_freebsd.odin index dd5306417..e02345cad 100644 --- a/core/sys/unix/pthread_freebsd.odin +++ b/core/sys/unix/pthread_freebsd.odin @@ -92,6 +92,11 @@ sem_t :: struct { _padding: u32, } +PTHREAD_CANCEL_ENABLE :: 0 +PTHREAD_CANCEL_DISABLE :: 1 +PTHREAD_CANCEL_DEFERRED :: 0 +PTHREAD_CANCEL_ASYNCHRONOUS :: 1 + foreign import "system:pthread" @(default_calling_convention="c") @@ -110,5 +115,8 @@ foreign pthread { // NOTE: unclear whether pthread_yield is well-supported on Linux systems, // see https://linux.die.net/man/3/pthread_yield pthread_yield :: proc() --- -} + pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int --- + pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int --- + pthread_cancel :: proc (thread: pthread_t) -> c.int --- +} \ No newline at end of file diff --git a/core/sys/unix/pthread_linux.odin b/core/sys/unix/pthread_linux.odin index 099e7c7e9..9c297ef22 100644 --- a/core/sys/unix/pthread_linux.odin +++ b/core/sys/unix/pthread_linux.odin @@ -94,6 +94,11 @@ when size_of(int) == 8 { SEM_T_SIZE :: 16 } +PTHREAD_CANCEL_ENABLE :: 0 +PTHREAD_CANCEL_DISABLE :: 1 +PTHREAD_CANCEL_DEFERRED :: 0 +PTHREAD_CANCEL_ASYNCHRONOUS :: 1 + foreign import "system:pthread" @(default_calling_convention="c") @@ -112,4 +117,8 @@ foreign pthread { // NOTE: unclear whether pthread_yield is well-supported on Linux systems, // see https://linux.die.net/man/3/pthread_yield pthread_yield :: proc() -> c.int --- + + pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int --- + pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int --- + pthread_cancel :: proc (thread: pthread_t) -> c.int --- } diff --git a/core/sys/unix/pthread_openbsd.odin b/core/sys/unix/pthread_openbsd.odin index c855f95c0..7ae82e662 100644 --- a/core/sys/unix/pthread_openbsd.odin +++ b/core/sys/unix/pthread_openbsd.odin @@ -46,6 +46,11 @@ sched_param :: struct { sem_t :: distinct rawptr +PTHREAD_CANCEL_ENABLE :: 0 +PTHREAD_CANCEL_DISABLE :: 1 +PTHREAD_CANCEL_DEFERRED :: 0 +PTHREAD_CANCEL_ASYNCHRONOUS :: 1 + foreign import libc "system:c" @(default_calling_convention="c") @@ -62,4 +67,8 @@ foreign libc { // NOTE: unclear whether pthread_yield is well-supported on Linux systems, // see https://linux.die.net/man/3/pthread_yield pthread_yield :: proc() --- -} + + pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int --- + pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int --- + pthread_cancel :: proc (thread: pthread_t) -> c.int --- +} \ No newline at end of file diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 3897f6100..1a2b30197 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -31,6 +31,9 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ __linux_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { t := (^Thread)(t) + // We need to give the thread a moment to start up before we enable cancellation. + can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) == 0 + context = runtime.default_context() sync.lock(&t.mutex) @@ -44,6 +47,12 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ init_context := t.init_context context = init_context.? or_else runtime.default_context() + // Enable thread's cancelability. + if can_set_thread_cancel_state { + unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) + unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) + } + t.procedure(t) intrinsics.atomic_store(&t.flags, t.flags + { .Done }) @@ -141,7 +150,7 @@ _destroy :: proc(t: ^Thread) { } _terminate :: proc(t: ^Thread, exit_code: int) { - // TODO(bill) + unix.pthread_cancel(t.unix_thread) } _yield :: proc() { diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index a36acdf18..c50a5bdf8 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1110,9 +1110,16 @@ prefix_table := [?]string{ "Black", } +print_mutex := b64(false) + threading_example :: proc() { fmt.println("\n# threading_example") + did_acquire :: proc(m: ^b64) -> (acquired: bool) { + res, ok := intrinsics.atomic_compare_exchange_strong(m, false, true) + return ok && res == false + } + { // Basic Threads fmt.println("\n## Basic Threads") worker_proc :: proc(t: ^thread.Thread) { @@ -1154,14 +1161,21 @@ threading_example :: proc() { task_proc :: proc(t: thread.Task) { index := t.user_index % len(prefix_table) for iteration in 1..=5 { + for !did_acquire(&print_mutex) { thread.yield() } // Allow one thread to print at a time. + fmt.printf("Worker Task %d is on iteration %d\n", t.user_index, iteration) fmt.printf("`%s`: iteration %d\n", prefix_table[index], iteration) + + print_mutex = false + time.sleep(1 * time.Millisecond) } } + N :: 3 + pool: thread.Pool - thread.pool_init(pool=&pool, thread_count=3, allocator=context.allocator) + thread.pool_init(pool=&pool, thread_count=N, allocator=context.allocator) defer thread.pool_destroy(&pool) @@ -1171,6 +1185,19 @@ threading_example :: proc() { } thread.pool_start(&pool) + + { + // Wait a moment before we cancel a thread + time.sleep(5 * time.Millisecond) + + // Allow one thread to print at a time. + for !did_acquire(&print_mutex) { thread.yield() } + + thread.terminate(pool.threads[N - 1], 0) + fmt.println("Canceled last thread") + print_mutex = false + } + thread.pool_finish(&pool) } } From f4ad4c7aa6f9137dd10c9d201e80f072181d2f93 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Wed, 11 May 2022 16:17:35 +0200 Subject: [PATCH 190/245] Disable thread.terminate on Darwin for now. --- core/thread/thread_unix.odin | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 1a2b30197..8c7058f17 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -31,8 +31,10 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ __linux_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { t := (^Thread)(t) - // We need to give the thread a moment to start up before we enable cancellation. - can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) == 0 + when ODIN_OS != .Darwin { + // We need to give the thread a moment to start up before we enable cancellation. + can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) == 0 + } context = runtime.default_context() @@ -47,10 +49,12 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ init_context := t.init_context context = init_context.? or_else runtime.default_context() - // Enable thread's cancelability. - if can_set_thread_cancel_state { - unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) - unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) + when ODIN_OS != .Darwin { + // Enable thread's cancelability. + if can_set_thread_cancel_state { + unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) + unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) + } } t.procedure(t) @@ -150,7 +154,10 @@ _destroy :: proc(t: ^Thread) { } _terminate :: proc(t: ^Thread, exit_code: int) { - unix.pthread_cancel(t.unix_thread) + // `pthread_cancel` is unreliable on Darwin for unknown reasons. + when ODIN_OS != .Darwin { + unix.pthread_cancel(t.unix_thread) + } } _yield :: proc() { From 8b4b81fdeb5e5367602855d5bedd83083118dfc1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 11:33:01 +0100 Subject: [PATCH 191/245] Fill in most of os2/file_windows.odin --- core/os/os2/errors.odin | 3 + core/os/os2/file.odin | 34 ++- core/os/os2/file_windows.odin | 473 +++++++++++++++++++++++++++++++-- core/sys/windows/kernel32.odin | 5 + core/sys/windows/types.odin | 1 + 5 files changed, 479 insertions(+), 37 deletions(-) diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 6ddae74b1..b54b10cb2 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -13,6 +13,9 @@ General_Error :: enum u32 { Timeout, Invalid_File, + Invalid_Path, + + Unsupported, } Platform_Error :: struct { diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 0ed08c850..268631dd6 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -2,6 +2,7 @@ package os2 import "core:io" import "core:time" +import "core:runtime" File :: struct { impl: _File, @@ -31,6 +32,7 @@ File_Flag :: enum { Sync, Trunc, Sparse, + Close_On_Exec, } O_RDONLY :: File_Flags{.Read} @@ -137,23 +139,36 @@ symlink :: proc(old_name, new_name: string) -> Error { return _symlink(old_name, new_name) } -read_link :: proc(name: string) -> (string, Error) { - return _read_link(name) +read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error) { + return _read_link(name,allocator) } -chdir :: proc(f: ^File) -> Error { - return _chdir(f) +chdir :: proc(name: string) -> Error { + return _chdir(name) } -chmod :: proc(f: ^File, mode: File_Mode) -> Error { - return _chmod(f, mode) +chmod :: proc(name: string, mode: File_Mode) -> Error { + return _chmod(name, mode) } -chown :: proc(f: ^File, uid, gid: int) -> Error { - return _chown(f, uid, gid) +chown :: proc(name: string, uid, gid: int) -> Error { + return _chown(name, uid, gid) } +fchdir :: proc(f: ^File) -> Error { + return _fchdir(f) +} + +fchmod :: proc(f: ^File, mode: File_Mode) -> Error { + return _fchmod(f, mode) +} + +fchown :: proc(f: ^File, uid, gid: int) -> Error { + return _fchown(f, uid, gid) +} + + lchown :: proc(name: string, uid, gid: int) -> Error { return _lchown(name, uid, gid) @@ -163,6 +178,9 @@ lchown :: proc(name: string, uid, gid: int) -> Error { chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { return _chtimes(name, atime, mtime) } +fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { + return _fchtimes(f, atime, mtime) +} exists :: proc(path: string) -> bool { return _exists(path) diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index 880305830..07117a15a 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -2,13 +2,19 @@ package os2 import "core:io" -import "core:time" +import "core:mem" import "core:runtime" import "core:strings" +import "core:time" +import "core:unicode/utf16" import win32 "core:sys/windows" INVALID_HANDLE :: ~uintptr(0) +S_IWRITE :: 0o200 +_ERROR_BAD_NETPATH :: 53 +MAX_RW :: 1<<30 + _file_allocator :: proc() -> runtime.Allocator { return heap_allocator() } @@ -26,6 +32,10 @@ _File :: struct { kind: _File_Kind, } +_handle :: proc(f: ^File) -> win32.HANDLE { + return win32.HANDLE(_fd(f)) +} + _get_platform_error :: proc() -> Error { err := i32(win32.GetLastError()) if err != 0 { @@ -34,8 +44,79 @@ _get_platform_error :: proc() -> Error { return nil } -_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (^File, Error) { - return nil, nil +_open_internal :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (handle: uintptr, err: Error) { + if len(name) == 0 { + err = .Not_Exist + return + } + + path := _fix_long_path(name) + access: u32 + switch flags & {.Read, .Write} { + case {.Read}: access = win32.FILE_GENERIC_READ + case {.Write}: access = win32.FILE_GENERIC_WRITE + case {.Read, .Write}: access = win32.FILE_GENERIC_READ | win32.FILE_GENERIC_WRITE + } + + if .Create in flags { + access |= win32.FILE_GENERIC_WRITE + } + if .Append in flags { + access &~= win32.FILE_GENERIC_WRITE + access |= win32.FILE_APPEND_DATA + } + share_mode := u32(win32.FILE_SHARE_READ | win32.FILE_SHARE_WRITE) + sa: ^win32.SECURITY_ATTRIBUTES + if .Close_On_Exec not_in flags { + sa = &win32.SECURITY_ATTRIBUTES{} + sa.nLength = size_of(win32.SECURITY_ATTRIBUTES) + sa.bInheritHandle = true + } + + create_mode: u32 = win32.OPEN_EXISTING + switch { + case flags & {.Create, .Excl} == {.Create, .Excl}: + create_mode = win32.CREATE_NEW + case flags & {.Create, .Trunc} == {.Create, .Trunc}: + create_mode = win32.CREATE_ALWAYS + case flags & {.Create} == {.Create}: + create_mode = win32.OPEN_ALWAYS + case flags & {.Trunc} == {.Trunc}: + create_mode = win32.TRUNCATE_EXISTING + } + + attrs: u32 = win32.FILE_ATTRIBUTE_NORMAL + if perm & S_IWRITE == 0 { + attrs = win32.FILE_ATTRIBUTE_READONLY + if create_mode == win32.CREATE_ALWAYS { + // NOTE(bill): Open has just asked to create a file in read-only mode. + // If the file already exists, to make it akin to a *nix open call, + // the call preserves the existing permissions. + h := win32.CreateFileW(path, access, share_mode, sa, win32.TRUNCATE_EXISTING, win32.FILE_ATTRIBUTE_NORMAL, nil) + if h == win32.INVALID_HANDLE { + switch e := win32.GetLastError(); e { + case win32.ERROR_FILE_NOT_FOUND, _ERROR_BAD_NETPATH, win32.ERROR_PATH_NOT_FOUND: + // file does not exist, create the file + case 0: + return uintptr(h), nil + case: + return 0, Platform_Error{i32(e)} + } + } + } + } + h := win32.CreateFileW(path, access, share_mode, sa, create_mode, attrs, nil) + if h == win32.INVALID_HANDLE { + return 0, _get_platform_error() + } + return uintptr(h), nil +} + + +_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) { + flags := flags if flags != nil else {.Read} + handle := _open_internal(name, flags + {.Close_On_Exec}, perm) or_return + return _new_file(handle, name), nil } _new_file :: proc(handle: uintptr, name: string) -> ^File { @@ -48,11 +129,12 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File { f.impl.name = strings.clone(name, context.allocator) f.impl.wname = win32.utf8_to_wstring(name, context.allocator) + handle := _handle(f) kind := _File_Kind.File - if m: u32; win32.GetConsoleMode(win32.HANDLE(fd), &m) { + if m: u32; win32.GetConsoleMode(handle, &m) { kind = .Console } - if win32.GetFileType(win32.HANDLE(fd)) == win32.FILE_TYPE_PIPE { + if win32.GetFileType(handle) == win32.FILE_TYPE_PIPE { kind = .Pipe } f.impl.kind = kind @@ -95,9 +177,14 @@ _name :: proc(f: ^File) -> string { } _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error) { - if f == nil { - return + handle := _handle(f) + if handle == win32.INVALID_HANDLE { + return 0, .Invalid_File } + if f.impl.kind == .Pipe { + return 0, .Invalid_File + } + w: u32 switch whence { case .Start: w = win32.FILE_BEGIN @@ -106,12 +193,8 @@ _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error } hi := i32(offset>>32) lo := i32(offset) - ft := win32.GetFileType(win32.HANDLE(fd)) - if ft == win32.FILE_TYPE_PIPE { - return 0, .Invalid_File - } - dw_ptr := win32.SetFilePointer(win32.HANDLE(fd), lo, &hi, w) + dw_ptr := win32.SetFilePointer(handle, lo, &hi, w) if dw_ptr == win32.INVALID_SET_FILE_POINTER { return 0, _get_platform_error() } @@ -119,35 +202,192 @@ _seek :: proc(f: ^File, offset: i64, whence: Seek_From) -> (ret: i64, err: Error } _read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return + read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Error) { + if len(b) == 0 { + return 0, nil + } + + BUF_SIZE :: 386 + buf16: [BUF_SIZE]u16 + buf8: [4*BUF_SIZE]u8 + + for n < len(b) && err == nil { + min_read := max(len(b)/4, 1 if len(b) > 0 else 0) + max_read := u32(min(BUF_SIZE, min_read)) + if max_read == 0 { + break + } + + single_read_length: u32 + ok := win32.ReadConsoleW(handle, &buf16[0], max_read, &single_read_length, nil) + if !ok { + err = _get_platform_error() + } + + buf8_len := utf16.decode_to_utf8(buf8[:], buf16[:single_read_length]) + src := buf8[:buf8_len] + + ctrl_z := false + for i := 0; i < len(src) && n+i < len(b); i += 1 { + x := src[i] + if x == 0x1a { // ctrl-z + ctrl_z = true + break + } + b[n] = x + n += 1 + } + if ctrl_z || single_read_length < max_read { + break + } + + // NOTE(bill): if the last two values were a newline, then it is expected that + // this is the end of the input + if n >= 2 && single_read_length == max_read && string(b[n-2:n]) == "\r\n" { + break + } + } + + return + } + + handle := _handle(f) + + single_read_length: win32.DWORD + total_read: int + length := len(p) + + to_read := min(win32.DWORD(length), MAX_RW) + + e: win32.BOOL + if f.impl.kind == .Console { + n, err := read_console(handle, p[total_read:][:to_read]) + total_read += n + if err != nil { + return int(total_read), err + } + } else { + e = win32.ReadFile(handle, &p[total_read], to_read, &single_read_length, nil) + } + if single_read_length <= 0 || !e { + return int(total_read), _get_platform_error() + } + total_read += int(single_read_length) + + return int(total_read), nil } _read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { + pread :: proc(f: ^File, data: []byte, offset: i64) -> (n: int, err: Error) { + buf := data + if len(buf) > MAX_RW { + buf = buf[:MAX_RW] + + } + curr_offset := seek(f, offset, .Current) or_return + defer seek(f, curr_offset, .Start) + + o := win32.OVERLAPPED{ + OffsetHigh = u32(offset>>32), + Offset = u32(offset), + } + + // TODO(bill): Determine the correct behaviour for consoles + + h := _handle(f) + done: win32.DWORD + if !win32.ReadFile(h, raw_data(buf), u32(len(buf)), &done, &o) { + err = _get_platform_error() + done = 0 + } + n = int(done) + return + } + p, offset := p, offset + for len(p) > 0 { + m := pread(f, p, offset) or_return + n += m + p = p[m:] + offset += i64(m) + } return } _read_from :: proc(f: ^File, r: io.Reader) -> (n: i64, err: Error) { + // TODO(bill) return } _write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { - return + if len(p) == 0 { + return + } + + single_write_length: win32.DWORD + total_write: i64 + length := i64(len(p)) + + handle := _handle(f) + + for total_write < length { + remaining := length - total_write + to_write := win32.DWORD(min(i32(remaining), MAX_RW)) + + e := win32.WriteFile(handle, &p[total_write], to_write, &single_write_length, nil) + if single_write_length <= 0 || !e { + n = int(total_write) + err = _get_platform_error() + return + } + total_write += i64(single_write_length) + } + return int(total_write), nil } _write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { + pwrite :: proc(f: ^File, data: []byte, offset: i64) -> (n: int, err: Error) { + buf := data + if len(buf) > MAX_RW { + buf = buf[:MAX_RW] + + } + curr_offset := seek(f, offset, .Current) or_return + defer seek(f, curr_offset, .Start) + + o := win32.OVERLAPPED{ + OffsetHigh = u32(offset>>32), + Offset = u32(offset), + } + + h := _handle(f) + done: win32.DWORD + if !win32.WriteFile(h, raw_data(buf), u32(len(buf)), &done, &o) { + err = _get_platform_error() + done = 0 + } + n = int(done) + return + } + + p, offset := p, offset + for len(p) > 0 { + m := pwrite(f, p, offset) or_return + n += m + p = p[m:] + offset += i64(m) + } return } _write_to :: proc(f: ^File, w: io.Writer) -> (n: i64, err: Error) { + // TODO(bill) return } _file_size :: proc(f: ^File) -> (n: i64, err: Error) { - if f == nil { - return - } length: win32.LARGE_INTEGER - if !win32.GetFileSizeEx(win32.HANDLE(fd), &length) { + handle := _handle(f) + if !win32.GetFileSizeEx(handle, &length) { err = _get_platform_error() } n = i64(length) @@ -156,10 +396,14 @@ _file_size :: proc(f: ^File) -> (n: i64, err: Error) { _sync :: proc(f: ^File) -> Error { - return nil + return _flush(f) } _flush :: proc(f: ^File) -> Error { + handle := _handle(f) + if !win32.FlushFileBuffers(handle) { + return _get_platform_error() + } return nil } @@ -170,7 +414,8 @@ _truncate :: proc(f: ^File, size: i64) -> Error { curr_off := seek(f, 0, .Current) or_return defer seek(f, curr_off, .Start) seek(f, size, .Start) or_return - if !win32.SetEndOfFile(win32.HANDLE(fd)) { + handle := _handle(f) + if !win32.SetEndOfFile(handle) { return _get_platform_error() } return nil @@ -234,43 +479,213 @@ _link :: proc(old_name, new_name: string) -> Error { } _symlink :: proc(old_name, new_name: string) -> Error { - return nil + return .Unsupported } -_read_link :: proc(name: string) -> (string, Error) { +_open_sym_link :: proc(p: [^]u16) -> (handle: win32.HANDLE, err: Error) { + attrs := u32(win32.FILE_FLAG_BACKUP_SEMANTICS) + attrs |= win32.FILE_FLAG_OPEN_REPARSE_POINT + handle = win32.CreateFileW(p, 0, 0, nil, win32.OPEN_EXISTING, attrs, nil) + if handle == win32.INVALID_HANDLE { + return nil, _get_platform_error() + } + return + +} + +_normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: string, err: Error) { + has_prefix :: proc(p: []u16, str: string) -> bool { + if len(p) < len(str) { + return false + } + // assume ascii + for i in 0.. bool { + return has_prefix(p, `\??\`) + } + + if !has_unc_prefix(p) { + return win32.utf16_to_utf8(p, allocator), nil + } + + ws := p[4:] + switch { + case len(ws) >= 2 && ws[1] == ':': + return win32.utf16_to_utf8(ws, allocator), nil + case has_prefix(ws, `UNC\`): + ws[3] = '\\' // override data in buffer + return win32.utf16_to_utf8(ws[3:], allocator), nil + } + + + handle := _open_sym_link(raw_data(p)) or_return + defer win32.CloseHandle(handle) + + n := win32.GetFinalPathNameByHandleW(handle, nil, 0, win32.VOLUME_NAME_DOS) + if n == 0 { + return "", _get_platform_error() + } + buf := make([]u16, n+1, context.temp_allocator) + n = win32.GetFinalPathNameByHandleW(handle, raw_data(buf), u32(len(buf)), win32.VOLUME_NAME_DOS) + if n == 0 { + return "", _get_platform_error() + } + + ws = buf[:n] + if has_unc_prefix(ws) { + ws = ws[4:] + if len(ws) > 3 && has_prefix(ws, `UNC`) { + ws[2] = '\\' + return win32.utf16_to_utf8(ws[2:], allocator), nil + } + return win32.utf16_to_utf8(ws, allocator), nil + } + return "", .Invalid_Path +} + +_read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, err: Error) { + MAXIMUM_REPARSE_DATA_BUFFER_SIZE :: 16 * 1024 + + @thread_local + rdb_buf: [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte + + p := _fix_long_path(name) + handle := _open_sym_link(p) or_return + defer win32.CloseHandle(handle) + + bytes_returned: u32 + if !win32.DeviceIoControl(handle, win32.FSCTL_GET_REPARSE_POINT, nil, 0, &rdb_buf[0], len(rdb_buf)-1, &bytes_returned, nil) { + err = _get_platform_error() + return + } + mem.zero_slice(rdb_buf[:min(bytes_returned+1, len(rdb_buf))]) + + + rdb := (^win32.REPARSE_DATA_BUFFER)(&rdb_buf[0]) + switch rdb.ReparseTag { + case win32.IO_REPARSE_TAG_SYMLINK: + rb := (^win32.SYMBOLIC_LINK_REPARSE_BUFFER)(&rdb.rest) + pb := win32.wstring(&rb.PathBuffer) + pb[rb.SubstituteNameOffset+rb.SubstituteNameLength] = 0 + p := pb[rb.SubstituteNameOffset:][:rb.SubstituteNameLength] + if rb.Flags & win32.SYMLINK_FLAG_RELATIVE != 0 { + return win32.utf16_to_utf8(p, allocator), nil + } + return _normalize_link_path(p, allocator) + + case win32.IO_REPARSE_TAG_MOUNT_POINT: + rb := (^win32.MOUNT_POINT_REPARSE_BUFFER)(&rdb.rest) + pb := win32.wstring(&rb.PathBuffer) + pb[rb.SubstituteNameOffset+rb.SubstituteNameLength] = 0 + p := pb[rb.SubstituteNameOffset:][:rb.SubstituteNameLength] + return _normalize_link_path(p, allocator) + } + // Path wasn't a symlink/junction but another reparse point kind return "", nil } -_chdir :: proc(f: ^File) -> Error { +_fchdir :: proc(f: ^File) -> Error { if f == nil { return nil } - if win32.SetCurrentDirectoryW(f.impl.wname) { + if !win32.SetCurrentDirectoryW(f.impl.wname) { + return _get_platform_error() + } + return nil +} + +_fchmod :: proc(f: ^File, mode: File_Mode) -> Error { + if f == nil { return nil } - return _get_platform_error() -} + d: win32.BY_HANDLE_FILE_INFORMATION + if !win32.GetFileInformationByHandle(_handle(f), &d) { + return _get_platform_error() + } + attrs := d.dwFileAttributes + if mode & S_IWRITE != 0 { + attrs &~= win32.FILE_ATTRIBUTE_READONLY + } else { + attrs |= win32.FILE_ATTRIBUTE_READONLY + } -_chmod :: proc(f: ^File, mode: File_Mode) -> Error { + info: win32.FILE_BASIC_INFO + info.FileAttributes = attrs + if !win32.SetFileInformationByHandle(_handle(f), .FileBasicInfo, &info, size_of(d)) { + return _get_platform_error() + } return nil } -_chown :: proc(f: ^File, uid, gid: int) -> Error { +_fchown :: proc(f: ^File, uid, gid: int) -> Error { + return .Unsupported +} + +_chdir :: proc(name: string) -> Error { + p := _fix_long_path(name) + if !win32.SetCurrentDirectoryW(p) { + return _get_platform_error() + } return nil } +_chmod :: proc(name: string, mode: File_Mode) -> Error { + f := open(name, {.Write}) or_return + defer close(f) + return _fchmod(f, mode) +} + +_chown :: proc(name: string, uid, gid: int) -> Error { + return .Unsupported +} _lchown :: proc(name: string, uid, gid: int) -> Error { - return nil + return .Unsupported } _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { + f := open(name, {.Write}) or_return + defer close(f) + return _fchtimes(f, atime, mtime) +} +_fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { + if f == nil { + return nil + } + d: win32.BY_HANDLE_FILE_INFORMATION + if !win32.GetFileInformationByHandle(_handle(f), &d) { + return _get_platform_error() + } + + to_windows_time :: #force_inline proc(t: time.Time) -> win32.LARGE_INTEGER { + // a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC) + return win32.LARGE_INTEGER(time.time_to_unix_nano(t) * 100 + 116444736000000000) + } + + atime, mtime := atime, mtime + if time.time_to_unix_nano(atime) < time.time_to_unix_nano(mtime) { + atime = mtime + } + + info: win32.FILE_BASIC_INFO + info.LastAccessTime = to_windows_time(atime) + info.LastWriteTime = to_windows_time(mtime) + if !win32.SetFileInformationByHandle(_handle(f), .FileBasicInfo, &info, size_of(d)) { + return _get_platform_error() + } return nil } + _exists :: proc(path: string) -> bool { wpath := _fix_long_path(path) attribs := win32.GetFileAttributesW(wpath) diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index d95ff91c9..1f8927a16 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -29,6 +29,11 @@ foreign kernel32 { SetHandleInformation :: proc(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL --- + SetFileInformationByHandle :: proc(hFile: HANDLE, + FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, + lpFileInformation: LPVOID, + dwBufferSize: DWORD) -> BOOL --- + AddVectoredExceptionHandler :: proc(FirstHandler: ULONG, VectoredHandler: PVECTORED_EXCEPTION_HANDLER) -> LPVOID --- AddVectoredContinueHandler :: proc(FirstHandler: ULONG, VectoredHandler: PVECTORED_EXCEPTION_HANDLER) -> LPVOID --- diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index d06cd287c..6770e7a95 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -191,6 +191,7 @@ FILE_WRITE_DATA: DWORD : 0x00000002 FILE_APPEND_DATA: DWORD : 0x00000004 FILE_WRITE_EA: DWORD : 0x00000010 FILE_WRITE_ATTRIBUTES: DWORD : 0x00000100 +FILE_READ_ATTRIBUTES: DWORD : 0x000000080 READ_CONTROL: DWORD : 0x00020000 SYNCHRONIZE: DWORD : 0x00100000 GENERIC_READ: DWORD : 0x80000000 From ccb38c3dc684ece829c7ca1066867cc5212533c3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 12:54:14 +0100 Subject: [PATCH 192/245] Add _safe versions --- core/bytes/bytes.odin | 43 +++++++++++++++++++++++++++++++++++++++ core/strings/strings.odin | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index 09a3ed259..66fd20829 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -10,6 +10,12 @@ clone :: proc(s: []byte, allocator := context.allocator, loc := #caller_location return c[:len(s)] } +clone_safe :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> (data: []byte, err: mem.Allocator_Error) { + c := make([]byte, len(s), allocator, loc) or_return + copy(c, s) + return c[:len(s)], nil +} + ptr_from_slice :: proc(str: []byte) -> ^byte { d := transmute(mem.Raw_String)str return d.data @@ -134,6 +140,25 @@ join :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> []byte return b } +join_safe :: proc(a: [][]byte, sep: []byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) { + if len(a) == 0 { + return nil, nil + } + + n := len(sep) * (len(a) - 1) + for s in a { + n += len(s) + } + + b := make([]byte, n, allocator) or_return + i := copy(b, a[0]) + for s in a[1:] { + i += copy(b[i:], sep) + i += copy(b[i:], s) + } + return b, nil +} + concatenate :: proc(a: [][]byte, allocator := context.allocator) -> []byte { if len(a) == 0 { return nil @@ -151,6 +176,24 @@ concatenate :: proc(a: [][]byte, allocator := context.allocator) -> []byte { return b } +concatenate_safe :: proc(a: [][]byte, allocator := context.allocator) -> (data: []byte, err: mem.Allocator_Error) { + if len(a) == 0 { + return nil, nil + } + + n := 0 + for s in a { + n += len(s) + } + b := make([]byte, n, allocator) or_return + i := 0 + for s in a { + i += copy(b[i:], s) + } + return b, nil +} + + @private _split :: proc(s, sep: []byte, sep_save, n: int, allocator := context.allocator) -> [][]byte { s, n := s, n diff --git a/core/strings/strings.odin b/core/strings/strings.odin index a3d9fa93e..2429b451d 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -14,6 +14,13 @@ clone :: proc(s: string, allocator := context.allocator, loc := #caller_location return string(c[:len(s)]) } +// returns a clone of the string `s` allocated using the `allocator` +clone_safe :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (str: string, err: mem.Allocator_Error) { + c := make([]byte, len(s), allocator, loc) or_return + copy(c, s) + return string(c[:len(s)]), nil +} + // returns a clone of the string `s` allocated using the `allocator` as a cstring // a nul byte is appended to the clone, to make the cstring safe clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> cstring { @@ -260,6 +267,25 @@ join :: proc(a: []string, sep: string, allocator := context.allocator) -> string return string(b) } +join_safe :: proc(a: []string, sep: string, allocator := context.allocator) -> (str: string, err: mem.Allocator_Error) { + if len(a) == 0 { + return "", nil + } + + n := len(sep) * (len(a) - 1) + for s in a { + n += len(s) + } + + b := make([]byte, n, allocator) or_return + i := copy(b, a[0]) + for s in a[1:] { + i += copy(b[i:], sep) + i += copy(b[i:], s) + } + return string(b), nil +} + /* returns a combined string from the slice of strings `a` without a seperator allocates the string using the `allocator` @@ -285,6 +311,23 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string { return string(b) } +concatenate_safe :: proc(a: []string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) { + if len(a) == 0 { + return "", nil + } + + n := 0 + for s in a { + n += len(s) + } + b := make([]byte, n, allocator) or_return + i := 0 + for s in a { + i += copy(b[i:], s) + } + return string(b), nil +} + /* `rune_offset` and `rune_length` are in runes, not bytes. If `rune_length` <= 0, then it'll return the remainder of the string starting at `rune_offset`. From bb4f1084879975e2f6c76cda325d4d60154fae46 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 12:54:27 +0100 Subject: [PATCH 193/245] Update error handling for os2 on windows --- core/os/os2/env_windows.odin | 10 ++- core/os/os2/errors.odin | 79 ++++++++++------- core/os/os2/errors_windows.odin | 46 ++++++++++ core/os/os2/file_util.odin | 10 ++- core/os/os2/file_windows.odin | 80 ++++++++++------- core/os/os2/path.odin | 4 +- core/os/os2/path_windows.odin | 57 ++++++++++++- core/os/os2/pipe_windows.odin | 2 +- core/os/os2/stat.odin | 11 +-- core/os/os2/stat_windows.odin | 132 ++++++++++++----------------- core/os/os2/temp_file.odin | 7 +- core/os/os2/temp_file_windows.odin | 30 +++---- core/os/os2/user.odin | 31 ++++--- core/os/stat_unix.odin | 1 - core/sys/windows/types.odin | 1 + 15 files changed, 310 insertions(+), 191 deletions(-) diff --git a/core/os/os2/env_windows.odin b/core/os/os2/env_windows.odin index 2ce755203..52c6c0f55 100644 --- a/core/os/os2/env_windows.odin +++ b/core/os/os2/env_windows.odin @@ -2,8 +2,9 @@ package os2 import win32 "core:sys/windows" +import "core:runtime" -_lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { +_lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) { if key == "" { return } @@ -17,7 +18,7 @@ _lookup_env :: proc(key: string, allocator := context.allocator) -> (value: stri } return "", true } - b := make([]u16, n+1, context.temp_allocator) + b := make([]u16, n+1, _temp_allocator()) n = win32.GetEnvironmentVariableW(wkey, raw_data(b), u32(len(b))) if n == 0 { @@ -25,6 +26,7 @@ _lookup_env :: proc(key: string, allocator := context.allocator) -> (value: stri if err == win32.ERROR_ENVVAR_NOT_FOUND { return "", false } + return "", false } value = win32.utf16_to_utf8(b[:n], allocator) @@ -45,7 +47,7 @@ _unset_env :: proc(key: string) -> bool { } _clear_env :: proc() { - envs := environ(context.temp_allocator) + envs := environ(_temp_allocator()) for env in envs { for j in 1.. bool { } _mkdir :: proc(name: string, perm: File_Mode) -> Error { + if !win32.CreateDirectoryW(_fix_long_path(name), nil) { + return _get_platform_error() + } return nil } _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { - // TODO(bill): _mkdir_all for windows + fix_root_directory :: proc(p: string) -> (s: string, allocated: bool, err: runtime.Allocator_Error) { + if len(p) == len(`\\?\c:`) { + if is_path_separator(p[0]) && is_path_separator(p[1]) && p[2] == '?' && is_path_separator(p[3]) && p[5] == ':' { + s = strings.concatenate_safe({p, `\`}, _file_allocator()) or_return + allocated = true + return + } + } + return p, false, nil + } + + dir, err := stat(path, _temp_allocator()) + if err == nil { + if dir.is_dir { + return nil + } + return .Exist + } + + i := len(path) + for i > 0 && is_path_separator(path[i-1]) { + i -= 1 + } + + j := i + for j > 0 && !is_path_separator(path[j-1]) { + j -= 1 + } + + if j > 1 { + new_path, allocated := fix_root_directory(path[:j-1]) or_return + defer if allocated { + delete(new_path, _file_allocator()) + } + mkdir_all(new_path, perm) or_return + } + + err = mkdir(path, perm) + if err != nil { + dir1, err1 := lstat(path, _temp_allocator()) + if err1 == nil && dir1.is_dir { + return nil + } + return err + } return nil } @@ -24,11 +73,13 @@ _remove_all :: proc(path: string) -> Error { return nil } -_getwd :: proc(allocator := context.allocator) -> (dir: string, err: Error) { +_getwd :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { + // TODO(bill) return "", nil } _setwd :: proc(dir: string) -> (err: Error) { + // TODO(bill) return nil } @@ -75,7 +126,7 @@ _fix_long_path_internal :: proc(path: string) -> string { } PREFIX :: `\\?` - path_buf := make([]byte, len(PREFIX)+len(path)+1, context.temp_allocator) + path_buf := make([]byte, len(PREFIX)+len(path)+1, _temp_allocator()) copy(path_buf, PREFIX) n := len(path) r, w := 0, len(PREFIX) diff --git a/core/os/os2/pipe_windows.odin b/core/os/os2/pipe_windows.odin index ddb54f80c..bab8b44f5 100644 --- a/core/os/os2/pipe_windows.odin +++ b/core/os/os2/pipe_windows.odin @@ -6,7 +6,7 @@ import win32 "core:sys/windows" _pipe :: proc() -> (r, w: ^File, err: Error) { p: [2]win32.HANDLE if !win32.CreatePipe(&p[0], &p[1], nil, 0) { - return nil, nil, Platform_Error{i32(win32.GetLastError())} + return nil, nil, _get_platform_error() } return new_file(uintptr(p[0]), ""), new_file(uintptr(p[1]), ""), nil } diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index 63f5a17e8..24a01fb0a 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -1,6 +1,7 @@ package os2 import "core:time" +import "core:runtime" File_Info :: struct { fullpath: string, @@ -13,26 +14,26 @@ File_Info :: struct { access_time: time.Time, } -file_info_slice_delete :: proc(infos: []File_Info, allocator := context.allocator) { +file_info_slice_delete :: proc(infos: []File_Info, allocator: runtime.Allocator) { for i := len(infos)-1; i >= 0; i -= 1 { file_info_delete(infos[i], allocator) } delete(infos, allocator) } -file_info_delete :: proc(fi: File_Info, allocator := context.allocator) { +file_info_delete :: proc(fi: File_Info, allocator: runtime.Allocator) { delete(fi.fullpath, allocator) } -fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Error) { +fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { return _fstat(f, allocator) } -stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { +stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return _stat(name, allocator) } -lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { +lstat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return _lstat(name, allocator) } diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index a79e5aae2..603343a18 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -1,22 +1,22 @@ //+private package os2 +import "core:runtime" import "core:time" import "core:strings" import win32 "core:sys/windows" -_fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Error) { +_fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { if f == nil || f.impl.fd == nil { - return {}, .Invalid_Argument + return {}, nil } - context.allocator = allocator - path, err := _cleanpath_from_handle(f) + path, err := _cleanpath_from_handle(f, allocator) if err != nil { return {}, err } - h := win32.HANDLE(f.impl.fd) + h := _handle(f) switch win32.GetFileType(h) { case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR: fi: File_Info @@ -26,13 +26,13 @@ _fstat :: proc(f: ^File, allocator := context.allocator) -> (File_Info, Error) { return fi, nil } - return _file_info_from_get_file_information_by_handle(path, h) + return _file_info_from_get_file_information_by_handle(path, h, allocator) } -_stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { - return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS) +_stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { + return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS, allocator) } -_lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Error) { - return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS|win32.FILE_FLAG_OPEN_REPARSE_POINT) +_lstat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { + return internal_stat(name, win32.FILE_FLAG_BACKUP_SEMANTICS|win32.FILE_FLAG_OPEN_REPARSE_POINT, allocator) } _same_file :: proc(fi1, fi2: File_Info) -> bool { return fi1.fullpath == fi2.fullpath @@ -40,50 +40,38 @@ _same_file :: proc(fi1, fi2: File_Info) -> bool { -_stat_errno :: proc(errno: win32.DWORD) -> Error { - return Platform_Error{i32(errno)} -} - -full_path_from_name :: proc(name: string, allocator := context.allocator) -> (path: string, err: Error) { - context.allocator = allocator - +full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path: string, err: Error) { name := name if name == "" { name = "." } - p := win32.utf8_to_utf16(name, context.temp_allocator) - buf := make([dynamic]u16, 100) - for { - n := win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil) - if n == 0 { - delete(buf) - return "", _stat_errno(win32.GetLastError()) - } - if n <= u32(len(buf)) { - return win32.utf16_to_utf8(buf[:n]), nil - } - resize(&buf, len(buf)*2) - } + p := win32.utf8_to_utf16(name, _temp_allocator()) - return + n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil) + if n == 0 { + return "", _get_platform_error() + } + buf := make([]u16, n+1, _temp_allocator()) + n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil) + if n == 0 { + return "", _get_platform_error() + } + return win32.utf16_to_utf8(buf[:n], allocator), nil } -internal_stat :: proc(name: string, create_file_attributes: u32, allocator := context.allocator) -> (fi: File_Info, e: Error) { +internal_stat :: proc(name: string, create_file_attributes: u32, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { if len(name) == 0 { return {}, .Not_Exist } - context.allocator = allocator - - wname := _fix_long_path(name) fa: win32.WIN32_FILE_ATTRIBUTE_DATA ok := win32.GetFileAttributesExW(wname, win32.GetFileExInfoStandard, &fa) if ok && fa.dwFileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 { // Not a symlink - return _file_info_from_win32_file_attribute_data(&fa, name) + return _file_info_from_win32_file_attribute_data(&fa, name, allocator) } err := 0 if ok else win32.GetLastError() @@ -97,7 +85,7 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator := co } win32.FindClose(sh) - return _file_info_from_win32_find_data(&fd, name) + return _file_info_from_win32_find_data(&fd, name, allocator) } h := win32.CreateFileW(wname, 0, 0, nil, win32.OPEN_EXISTING, create_file_attributes, nil) @@ -106,7 +94,7 @@ internal_stat :: proc(name: string, create_file_attributes: u32, allocator := co return } defer win32.CloseHandle(h) - return _file_info_from_get_file_information_by_handle(name, h) + return _file_info_from_get_file_information_by_handle(name, h, allocator) } @@ -131,56 +119,40 @@ _cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { } -_cleanpath_from_handle :: proc(f: ^File) -> (string, Error) { +_cleanpath_from_handle :: proc(f: ^File, allocator: runtime.Allocator) -> (string, Error) { if f == nil || f.impl.fd == nil { - return "", .Invalid_Argument + return "", nil } - h := win32.HANDLE(f.impl.fd) + h := _handle(f) - MAX_PATH := win32.DWORD(260) + 1 - buf: []u16 - for { - buf = make([]u16, MAX_PATH, context.temp_allocator) - err := win32.GetFinalPathNameByHandleW(h, raw_data(buf), MAX_PATH, 0) - switch err { - case win32.ERROR_PATH_NOT_FOUND, win32.ERROR_INVALID_PARAMETER: - return "", _stat_errno(err) - case win32.ERROR_NOT_ENOUGH_MEMORY: - MAX_PATH = MAX_PATH*2 + 1 - continue - } - break + n := win32.GetFinalPathNameByHandleW(h, nil, 0, 0) + if n == 0 { + return "", _get_platform_error() } - return _cleanpath_from_buf(buf), nil + buf := make([]u16, max(n, 260)+1, _temp_allocator()) + n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0) + return _cleanpath_from_buf(buf[:n], allocator), nil } _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) { if f == nil || f.impl.fd == nil { - return nil, .Invalid_Argument + return nil, nil } - h := win32.HANDLE(f.impl.fd) + h := _handle(f) - MAX_PATH := win32.DWORD(260) + 1 - buf: []u16 - for { - buf = make([]u16, MAX_PATH, context.temp_allocator) - err := win32.GetFinalPathNameByHandleW(h, raw_data(buf), MAX_PATH, 0) - switch err { - case win32.ERROR_PATH_NOT_FOUND, win32.ERROR_INVALID_PARAMETER: - return nil, _stat_errno(err) - case win32.ERROR_NOT_ENOUGH_MEMORY: - MAX_PATH = MAX_PATH*2 + 1 - continue - } - break + n := win32.GetFinalPathNameByHandleW(h, nil, 0, 0) + if n == 0 { + return nil, _get_platform_error() } - return _cleanpath_strip_prefix(buf), nil + buf := make([]u16, max(n, 260)+1, _temp_allocator()) + n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0) + return _cleanpath_strip_prefix(buf[:n]), nil } -_cleanpath_from_buf :: proc(buf: []u16) -> string { +_cleanpath_from_buf :: proc(buf: []u16, allocator: runtime.Allocator) -> string { buf := buf buf = _cleanpath_strip_prefix(buf) - return win32.utf16_to_utf8(buf, context.allocator) + return win32.utf16_to_utf8(buf, allocator) } @@ -252,7 +224,7 @@ _file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HA } -_file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Error) { +_file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) @@ -262,14 +234,14 @@ _file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) - fi.fullpath, e = full_path_from_name(name) + fi.fullpath, e = full_path_from_name(name, allocator) fi.name = basename(fi.fullpath) return } -_file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string) -> (fi: File_Info, e: Error) { +_file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string, allocator: runtime.Allocator) -> (fi: File_Info, e: Error) { fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.mode |= _file_mode_from_file_attributes(d.dwFileAttributes, nil, 0) @@ -279,17 +251,17 @@ _file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) - fi.fullpath, e = full_path_from_name(name) + fi.fullpath, e = full_path_from_name(name, allocator) fi.name = basename(fi.fullpath) return } -_file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Error) { +_file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE, allocator: runtime.Allocator) -> (File_Info, Error) { d: win32.BY_HANDLE_FILE_INFORMATION if !win32.GetFileInformationByHandle(h, &d) { - return {}, _stat_errno(win32.GetLastError()) + return {}, _get_platform_error() } @@ -297,7 +269,7 @@ _file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HA if !win32.GetFileInformationByHandleEx(h, .FileAttributeTagInfo, &ti, size_of(ti)) { err := win32.GetLastError() if err != win32.ERROR_INVALID_PARAMETER { - return {}, _stat_errno(err) + return {}, Platform_Error(err) } // Indicate this is a symlink on FAT file systems ti.ReparseTag = 0 diff --git a/core/os/os2/temp_file.odin b/core/os/os2/temp_file.odin index 90131699d..faf176de1 100644 --- a/core/os/os2/temp_file.odin +++ b/core/os/os2/temp_file.odin @@ -1,14 +1,15 @@ package os2 +import "core:runtime" create_temp :: proc(dir, pattern: string) -> (^File, Error) { return _create_temp(dir, pattern) } -mkdir_temp :: proc(dir, pattern: string, allocator := context.allocator) -> (string, Error) { - return _mkdir_temp(dir, pattern) +mkdir_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (string, Error) { + return _mkdir_temp(dir, pattern, allocator) } -temp_dir :: proc(allocator := context.allocator) -> string { +temp_dir :: proc(allocator: runtime.Allocator) -> string { return _temp_dir(allocator) } diff --git a/core/os/os2/temp_file_windows.odin b/core/os/os2/temp_file_windows.odin index 17967393a..a7587988b 100644 --- a/core/os/os2/temp_file_windows.odin +++ b/core/os/os2/temp_file_windows.odin @@ -1,29 +1,29 @@ //+private package os2 +import "core:runtime" import win32 "core:sys/windows" _create_temp :: proc(dir, pattern: string) -> (^File, Error) { return nil, nil } -_mkdir_temp :: proc(dir, pattern: string, allocator := context.allocator) -> (string, Error) { +_mkdir_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (string, Error) { return "", nil } -_temp_dir :: proc(allocator := context.allocator) -> string { - b := make([dynamic]u16, u32(win32.MAX_PATH), context.temp_allocator) - for { - n := win32.GetTempPathW(u32(len(b)), raw_data(b)) - if n > u32(len(b)) { - resize(&b, int(n)) - continue - } - if n == 3 && b[1] == ':' && b[2] == '\\' { - - } else if n > 0 && b[n-1] == '\\' { - n -= 1 - } - return win32.utf16_to_utf8(b[:n], allocator) +_temp_dir :: proc(allocator: runtime.Allocator) -> string { + n := win32.GetTempPathW(0, nil) + if n == 0 { + return "" } + b := make([]u16, max(win32.MAX_PATH, n), _temp_allocator()) + n = win32.GetTempPathW(u32(len(b)), raw_data(b)) + + if n == 3 && b[1] == ':' && b[2] == '\\' { + + } else if n > 0 && b[n-1] == '\\' { + n -= 1 + } + return win32.utf16_to_utf8(b[:n], allocator) } diff --git a/core/os/os2/user.odin b/core/os/os2/user.odin index 976e61bb1..1fb653b85 100644 --- a/core/os/os2/user.odin +++ b/core/os/os2/user.odin @@ -1,18 +1,19 @@ package os2 import "core:strings" +import "core:runtime" -user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { +user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { #partial switch ODIN_OS { case .Windows: dir = get_env("LocalAppData") if dir != "" { - dir = strings.clone(dir, allocator) + dir = strings.clone_safe(dir, allocator) or_return } case .Darwin: dir = get_env("HOME") if dir != "" { - dir = strings.concatenate({dir, "/Library/Caches"}, allocator) + dir = strings.concatenate_safe({dir, "/Library/Caches"}, allocator) or_return } case: // All other UNIX systems dir = get_env("XDG_CACHE_HOME") @@ -21,24 +22,26 @@ user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defin if dir == "" { return } - dir = strings.concatenate({dir, "/.cache"}, allocator) + dir = strings.concatenate_safe({dir, "/.cache"}, allocator) or_return } } - is_defined = dir != "" + if dir == "" { + err = .Invalid_Path + } return } -user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { +user_config_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { #partial switch ODIN_OS { case .Windows: dir = get_env("AppData") if dir != "" { - dir = strings.clone(dir, allocator) + dir = strings.clone_safe(dir, allocator) or_return } case .Darwin: dir = get_env("HOME") if dir != "" { - dir = strings.concatenate({dir, "/Library/Application Support"}, allocator) + dir = strings.concatenate_safe({dir, "/Library/Application Support"}, allocator) or_return } case: // All other UNIX systems dir = get_env("XDG_CACHE_HOME") @@ -47,22 +50,24 @@ user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defi if dir == "" { return } - dir = strings.concatenate({dir, "/.config"}, allocator) + dir = strings.concatenate_safe({dir, "/.config"}, allocator) or_return } } - is_defined = dir != "" + if dir == "" { + err = .Invalid_Path + } return } -user_home_dir :: proc() -> (dir: string, is_defined: bool) { +user_home_dir :: proc() -> (dir: string, err: Error) { env := "HOME" #partial switch ODIN_OS { case .Windows: env = "USERPROFILE" } if v := get_env(env); v != "" { - return v, true + return v, nil } - return "", false + return "", .Invalid_Path } diff --git a/core/os/stat_unix.odin b/core/os/stat_unix.odin index 395d2e73e..dae7ab2fb 100644 --- a/core/os/stat_unix.odin +++ b/core/os/stat_unix.odin @@ -119,7 +119,6 @@ lstat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, e } stat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, err: Errno) { - context.allocator = allocator s: OS_Stat diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 6770e7a95..4f594e22d 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -1140,6 +1140,7 @@ ERROR_BROKEN_PIPE: DWORD : 109 ERROR_CALL_NOT_IMPLEMENTED: DWORD : 120 ERROR_INSUFFICIENT_BUFFER: DWORD : 122 ERROR_INVALID_NAME: DWORD : 123 +ERROR_BAD_ARGUMENTS: DWORD: 160 ERROR_LOCK_FAILED: DWORD : 167 ERROR_ALREADY_EXISTS: DWORD : 183 ERROR_NO_DATA: DWORD : 232 From eef44b11f3b26cde6086251ce1b9f661557e4d5c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 13:17:58 +0100 Subject: [PATCH 194/245] Make the utf16 conversion procedures in `core:sys/windows` safer by checking for memory leaks --- core/os/dir_windows.odin | 2 +- core/os/env_windows.odin | 4 +-- core/os/file_windows.odin | 2 +- core/os/os2/env_windows.odin | 4 +-- core/os/os2/file.odin | 18 ++++++++++++ core/os/os2/file_stream.odin | 10 ++++++- core/os/os2/file_windows.odin | 12 ++++---- core/os/os2/stat_windows.odin | 14 ++++----- core/os/os2/temp_file.odin | 2 +- core/os/os2/temp_file_windows.odin | 4 +-- core/os/stat_windows.odin | 6 ++-- core/sys/win32/comdlg32.odin | 2 +- core/sys/win32/crt.odin | 2 +- core/sys/win32/general.odin | 18 ++++++------ core/sys/win32/tests/general.odin | 46 +++++++++++++++--------------- core/sys/windows/kernel32.odin | 5 ++++ core/sys/windows/util.odin | 26 ++++++++--------- 17 files changed, 105 insertions(+), 72 deletions(-) diff --git a/core/os/dir_windows.odin b/core/os/dir_windows.odin index 3261b8cb3..89a09d403 100644 --- a/core/os/dir_windows.odin +++ b/core/os/dir_windows.odin @@ -13,7 +13,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F if d.cFileName[0] == '.' && d.cFileName[1] == '.' && d.cFileName[2] == 0 { return } - path := strings.concatenate({base_path, `\`, win32.utf16_to_utf8(d.cFileName[:])}) + path := strings.concatenate({base_path, `\`, win32.utf16_to_utf8(d.cFileName[:]) or_else ""}) fi.fullpath = path fi.name = basename(path) fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) diff --git a/core/os/env_windows.odin b/core/os/env_windows.odin index 74981bc6e..9a33a0611 100644 --- a/core/os/env_windows.odin +++ b/core/os/env_windows.odin @@ -22,7 +22,7 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } if n <= u32(len(b)) { - value = win32.utf16_to_utf8(b[:n], allocator) + value, _ = win32.utf16_to_utf8(b[:n], allocator) found = true return } @@ -76,7 +76,7 @@ environ :: proc(allocator := context.allocator) -> []string { if i <= from { break } - append(&r, win32.utf16_to_utf8(envs[from:i], allocator)) + append(&r, win32.utf16_to_utf8(envs[from:i], allocator) or_else "") from = i + 1 } } diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin index a9f78070f..daabe60f0 100644 --- a/core/os/file_windows.odin +++ b/core/os/file_windows.odin @@ -365,7 +365,7 @@ get_current_directory :: proc(allocator := context.allocator) -> string { win32.ReleaseSRWLockExclusive(&cwd_lock) - return win32.utf16_to_utf8(dir_buf_wstr, allocator) + return win32.utf16_to_utf8(dir_buf_wstr, allocator) or_else "" } set_current_directory :: proc(path: string) -> (err: Errno) { diff --git a/core/os/os2/env_windows.odin b/core/os/os2/env_windows.odin index 52c6c0f55..f58922fac 100644 --- a/core/os/os2/env_windows.odin +++ b/core/os/os2/env_windows.odin @@ -29,7 +29,7 @@ _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string return "", false } - value = win32.utf16_to_utf8(b[:n], allocator) + value = win32.utf16_to_utf8(b[:n], allocator) or_else "" found = true return } @@ -73,7 +73,7 @@ _environ :: proc(allocator: runtime.Allocator) -> []string { break } w := ([^]u16)(p)[from:i] - append(&r, win32.utf16_to_utf8(w, allocator)) + append(&r, win32.utf16_to_utf8(w, allocator) or_else "") from = i + 1 } } diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 268631dd6..4b271b9ea 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -21,6 +21,7 @@ File_Mode_Device :: File_Mode(1<<18) File_Mode_Char_Device :: File_Mode(1<<19) File_Mode_Sym_Link :: File_Mode(1<<20) +File_Mode_Perm :: File_Mode(0o777) // Unix permision bits File_Flags :: distinct bit_set[File_Flag; uint] File_Flag :: enum { @@ -194,3 +195,20 @@ is_dir :: proc(path: string) -> bool { return _is_dir(path) } + +copy_file :: proc(dst_path, src_path: string) -> Error { + src := open(src_path) or_return + defer close(src) + + info := fstat(src, _file_allocator()) or_return + defer file_info_delete(info, _file_allocator()) + if info.is_dir { + return .Invalid_File + } + + dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & File_Mode_Perm) or_return + defer close(dst) + + _, err := io.copy(to_writer(dst), to_reader(src)) + return err +} \ No newline at end of file diff --git a/core/os/os2/file_stream.odin b/core/os/os2/file_stream.odin index 7b68d0e21..5e3db9370 100644 --- a/core/os/os2/file_stream.odin +++ b/core/os/os2/file_stream.odin @@ -2,12 +2,20 @@ package os2 import "core:io" -file_to_stream :: proc(f: ^File) -> (s: io.Stream) { +to_stream :: proc(f: ^File) -> (s: io.Stream) { s.stream_data = f s.stream_vtable = _file_stream_vtable return } +to_writer :: proc(f: ^File) -> (s: io.Writer) { + return {to_stream(f)} +} +to_reader :: proc(f: ^File) -> (s: io.Reader) { + return {to_stream(f)} +} + + @(private) error_to_io_error :: proc(ferr: Error) -> io.Error { if ferr == nil { diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index b9ebfe10e..7589ed799 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -529,16 +529,16 @@ _normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: st } if !has_unc_prefix(p) { - return win32.utf16_to_utf8(p, allocator), nil + return win32.utf16_to_utf8(p, allocator) } ws := p[4:] switch { case len(ws) >= 2 && ws[1] == ':': - return win32.utf16_to_utf8(ws, allocator), nil + return win32.utf16_to_utf8(ws, allocator) case has_prefix(ws, `UNC\`): ws[3] = '\\' // override data in buffer - return win32.utf16_to_utf8(ws[3:], allocator), nil + return win32.utf16_to_utf8(ws[3:], allocator) } @@ -560,9 +560,9 @@ _normalize_link_path :: proc(p: []u16, allocator: runtime.Allocator) -> (str: st ws = ws[4:] if len(ws) > 3 && has_prefix(ws, `UNC`) { ws[2] = '\\' - return win32.utf16_to_utf8(ws[2:], allocator), nil + return win32.utf16_to_utf8(ws[2:], allocator) } - return win32.utf16_to_utf8(ws, allocator), nil + return win32.utf16_to_utf8(ws, allocator) } return "", .Invalid_Path } @@ -593,7 +593,7 @@ _read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, er pb[rb.SubstituteNameOffset+rb.SubstituteNameLength] = 0 p := pb[rb.SubstituteNameOffset:][:rb.SubstituteNameLength] if rb.Flags & win32.SYMLINK_FLAG_RELATIVE != 0 { - return win32.utf16_to_utf8(p, allocator), nil + return win32.utf16_to_utf8(p, allocator) } return _normalize_link_path(p, allocator) diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 603343a18..5de5269d7 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -57,7 +57,7 @@ full_path_from_name :: proc(name: string, allocator: runtime.Allocator) -> (path if n == 0 { return "", _get_platform_error() } - return win32.utf16_to_utf8(buf[:n], allocator), nil + return win32.utf16_to_utf8(buf[:n], allocator) } @@ -131,7 +131,7 @@ _cleanpath_from_handle :: proc(f: ^File, allocator: runtime.Allocator) -> (strin } buf := make([]u16, max(n, 260)+1, _temp_allocator()) n = win32.GetFinalPathNameByHandleW(h, raw_data(buf), u32(len(buf)), 0) - return _cleanpath_from_buf(buf[:n], allocator), nil + return _cleanpath_from_buf(buf[:n], allocator) } _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) { @@ -149,7 +149,7 @@ _cleanpath_from_handle_u16 :: proc(f: ^File) -> ([]u16, Error) { return _cleanpath_strip_prefix(buf[:n]), nil } -_cleanpath_from_buf :: proc(buf: []u16, allocator: runtime.Allocator) -> string { +_cleanpath_from_buf :: proc(buf: []u16, allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { buf := buf buf = _cleanpath_strip_prefix(buf) return win32.utf16_to_utf8(buf, allocator) @@ -194,15 +194,15 @@ file_type_mode :: proc(h: win32.HANDLE) -> File_Mode { -_file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (mode: File_Mode) { - if FileAttributes & win32.FILE_ATTRIBUTE_READONLY != 0 { +_file_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (mode: File_Mode) { + if file_attributes & win32.FILE_ATTRIBUTE_READONLY != 0 { mode |= 0o444 } else { mode |= 0o666 } is_sym := false - if FileAttributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 { + if file_attributes & win32.FILE_ATTRIBUTE_REPARSE_POINT == 0 { is_sym = false } else { is_sym = ReparseTag == win32.IO_REPARSE_TAG_SYMLINK || ReparseTag == win32.IO_REPARSE_TAG_MOUNT_POINT @@ -211,7 +211,7 @@ _file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HA if is_sym { mode |= File_Mode_Sym_Link } else { - if FileAttributes & win32.FILE_ATTRIBUTE_DIRECTORY != 0 { + if file_attributes & win32.FILE_ATTRIBUTE_DIRECTORY != 0 { mode |= 0o111 | File_Mode_Dir } diff --git a/core/os/os2/temp_file.odin b/core/os/os2/temp_file.odin index faf176de1..b05c186a0 100644 --- a/core/os/os2/temp_file.odin +++ b/core/os/os2/temp_file.odin @@ -10,6 +10,6 @@ mkdir_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (strin return _mkdir_temp(dir, pattern, allocator) } -temp_dir :: proc(allocator: runtime.Allocator) -> string { +temp_dir :: proc(allocator: runtime.Allocator) -> (string, Error) { return _temp_dir(allocator) } diff --git a/core/os/os2/temp_file_windows.odin b/core/os/os2/temp_file_windows.odin index a7587988b..08837f7f0 100644 --- a/core/os/os2/temp_file_windows.odin +++ b/core/os/os2/temp_file_windows.odin @@ -12,10 +12,10 @@ _mkdir_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) -> (stri return "", nil } -_temp_dir :: proc(allocator: runtime.Allocator) -> string { +_temp_dir :: proc(allocator: runtime.Allocator) -> (string, runtime.Allocator_Error) { n := win32.GetTempPathW(0, nil) if n == 0 { - return "" + return "", nil } b := make([]u16, max(win32.MAX_PATH, n), _temp_allocator()) n = win32.GetTempPathW(u32(len(b)), raw_data(b)) diff --git a/core/os/stat_windows.odin b/core/os/stat_windows.odin index 5da925560..79bb8c42e 100644 --- a/core/os/stat_windows.odin +++ b/core/os/stat_windows.odin @@ -20,7 +20,7 @@ full_path_from_name :: proc(name: string, allocator := context.allocator) -> (pa return "", Errno(win32.GetLastError()) } if n <= u32(len(buf)) { - return win32.utf16_to_utf8(buf[:n], allocator), ERROR_NONE + return win32.utf16_to_utf8(buf[:n], allocator) or_else "", ERROR_NONE } resize(&buf, len(buf)*2) } @@ -136,7 +136,7 @@ cleanpath_from_handle :: proc(fd: Handle) -> (string, Errno) { if err != 0 { return "", err } - return win32.utf16_to_utf8(buf, context.allocator), err + return win32.utf16_to_utf8(buf, context.allocator) or_else "", err } @(private) cleanpath_from_handle_u16 :: proc(fd: Handle) -> ([]u16, Errno) { @@ -157,7 +157,7 @@ cleanpath_from_handle_u16 :: proc(fd: Handle) -> ([]u16, Errno) { cleanpath_from_buf :: proc(buf: []u16) -> string { buf := buf buf = cleanpath_strip_prefix(buf) - return win32.utf16_to_utf8(buf, context.allocator) + return win32.utf16_to_utf8(buf, context.allocator) or_else "" } @(private) diff --git a/core/sys/win32/comdlg32.odin b/core/sys/win32/comdlg32.odin index 1e0d5c3ca..815def7b6 100644 --- a/core/sys/win32/comdlg32.odin +++ b/core/sys/win32/comdlg32.odin @@ -126,7 +126,7 @@ _open_file_dialog :: proc(title: string, dir: string, } - file_name := utf16_to_utf8(file_buf[:], allocator) + file_name, _ := utf16_to_utf8(file_buf[:], allocator) path = strings.trim_right_null(file_name) return } diff --git a/core/sys/win32/crt.odin b/core/sys/win32/crt.odin index b39d35375..8584a27be 100644 --- a/core/sys/win32/crt.odin +++ b/core/sys/win32/crt.odin @@ -10,6 +10,6 @@ foreign { get_cwd :: proc(allocator := context.temp_allocator) -> string { buffer := make([]u16, MAX_PATH_WIDE, allocator) _get_cwd_wide(Wstring(&buffer[0]), MAX_PATH_WIDE) - file := utf16_to_utf8(buffer[:], allocator) + file, _ := utf16_to_utf8(buffer[:], allocator) return strings.trim_right_null(file) } diff --git a/core/sys/win32/general.odin b/core/sys/win32/general.odin index 1baad8b11..64ee952ce 100644 --- a/core/sys/win32/general.odin +++ b/core/sys/win32/general.odin @@ -1,6 +1,8 @@ // +build windows package win32 +import "core:runtime" + Uint_Ptr :: distinct uintptr Int_Ptr :: distinct int Long_Ptr :: distinct int @@ -858,14 +860,14 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> Wstri return nil } -wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator) -> string { +wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator) -> (str: string, err: runtime.Allocator_Error) { if N == 0 { - return "" + return } n := wide_char_to_multi_byte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil) if n == 0 { - return "" + return } // If N == -1 the call to wide_char_to_multi_byte assume the wide string is null terminated @@ -873,11 +875,11 @@ wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator) // also null terminated. // If N != -1 it assumes the wide string is not null terminated and the resulting string // will not be null terminated, we therefore have to force it to be null terminated manually. - text := make([]byte, n+1 if N != -1 else n, allocator) + text := make([]byte, n+1 if N != -1 else n, allocator) or_return if n1 := wide_char_to_multi_byte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), cstring(&text[0]), n, nil, nil); n1 == 0 { delete(text, allocator) - return "" + return "", nil } for i in 0.. string { +utf16_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> (string, runtime.Allocator_Error) { if len(s) == 0 { - return "" + return "", nil } return wstring_to_utf8(cast(Wstring)&s[0], len(s), allocator) } diff --git a/core/sys/win32/tests/general.odin b/core/sys/win32/tests/general.odin index 1a5fc911a..9a78dec11 100644 --- a/core/sys/win32/tests/general.odin +++ b/core/sys/win32/tests/general.odin @@ -1,41 +1,41 @@ package win32_tests -import "core:sys/win32" +import win32 "core:sys/windows" import "core:testing" utf16_to_utf8 :: proc(t: ^testing.T, str: []u16, comparison: string, expected_result: bool, loc := #caller_location) { - result := win32.utf16_to_utf8(str[:]); - testing.expect(t, (result == comparison) == expected_result, "Incorrect utf16_to_utf8 conversion", loc); + result, _ := win32.utf16_to_utf8(str[:]) + testing.expect(t, (result == comparison) == expected_result, "Incorrect utf16_to_utf8 conversion", loc) } wstring_to_utf8 :: proc(t: ^testing.T, str: []u16, comparison: string, expected_result: bool, loc := #caller_location) { - result := win32.wstring_to_utf8(nil if len(str) == 0 else cast(win32.Wstring)&str[0], -1); - testing.expect(t, (result == comparison) == expected_result, "Incorrect wstring_to_utf8 conversion", loc); + result, _ := win32.wstring_to_utf8(nil if len(str) == 0 else cast(win32.Wstring)&str[0], -1) + testing.expect(t, (result == comparison) == expected_result, "Incorrect wstring_to_utf8 conversion", loc) } @test test_utf :: proc(t: ^testing.T) { - utf16_to_utf8(t, []u16{}, "", true); - utf16_to_utf8(t, []u16{0}, "", true); - utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true); - utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true); - utf16_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", true); - utf16_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true); - utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true); - utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true); + utf16_to_utf8(t, []u16{}, "", true) + utf16_to_utf8(t, []u16{0}, "", true) + utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true) + utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true) + utf16_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", true) + utf16_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true) + utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true) + utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true) - wstring_to_utf8(t, []u16{}, "", true); - wstring_to_utf8(t, []u16{0}, "", true); - wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true); - wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true); - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true); - wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true); - wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true); + wstring_to_utf8(t, []u16{}, "", true) + wstring_to_utf8(t, []u16{0}, "", true) + wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true) + wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true) + wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true) + wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true) + wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true) // WARNING: Passing a non-zero-terminated string to wstring_to_utf8 is dangerous, // as it will go out of bounds looking for a zero. // It will "fail" or "succeed" by having a zero just after the end of the input string or not. - wstring_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", false); - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}[:4], "test", true); - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 'q'}[:4], "test", false); + wstring_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", false) + wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}[:4], "test", true) + wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 'q'}[:4], "test", false) } \ No newline at end of file diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 1f8927a16..ac959db2d 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -272,6 +272,11 @@ foreign kernel32 { HeapReAlloc :: proc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID --- HeapFree :: proc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL --- + LocalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID --- + LocalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID --- + LocalFree :: proc(mem: LPVOID) -> LPVOID --- + + ReadDirectoryChangesW :: proc( hDirectory: HANDLE, lpBuffer: LPVOID, diff --git a/core/sys/windows/util.odin b/core/sys/windows/util.odin index f448f6bc5..5c8f35bef 100644 --- a/core/sys/windows/util.odin +++ b/core/sys/windows/util.odin @@ -2,7 +2,7 @@ package sys_windows import "core:strings" -import "core:sys/win32" +import "core:runtime" import "core:intrinsics" L :: intrinsics.constant_utf16_cstring @@ -56,16 +56,16 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri return nil } -wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string) { +wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) { context.allocator = allocator if N <= 0 { - return "" + return } n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil) if n == 0 { - return "" + return } // If N == -1 the call to WideCharToMultiByte assume the wide string is null terminated @@ -73,12 +73,12 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) // also null terminated. // If N != -1 it assumes the wide string is not null terminated and the resulting string // will not be null terminated, we therefore have to force it to be null terminated manually. - text := make([]byte, n+1 if N != -1 else n) + text := make([]byte, n+1 if N != -1 else n) or_return n1 := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), raw_data(text), n, nil, nil) if n1 == 0 { delete(text, allocator) - return "" + return } for i in 0.. string { +utf16_to_utf8 :: proc(s: []u16, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) { if len(s) == 0 { - return "" + return "", nil } return wstring_to_utf8(raw_data(s), len(s), allocator) } @@ -216,7 +216,7 @@ get_computer_name_and_account_sid :: proc(username: string) -> (computer_name: s if !res { return "", {}, false } - computer_name = utf16_to_utf8(cname_w, context.temp_allocator) + computer_name = utf16_to_utf8(cname_w, context.temp_allocator) or_else "" ok = true return @@ -306,7 +306,7 @@ add_user_profile :: proc(username: string) -> (ok: bool, profile_path: string) { if res == false { return false, "" } - defer win32.local_free(sb) + defer LocalFree(sb) pszProfilePath := make([]u16, 257, context.temp_allocator) res2 := CreateProfile( @@ -318,7 +318,7 @@ add_user_profile :: proc(username: string) -> (ok: bool, profile_path: string) { if res2 != 0 { return false, "" } - profile_path = wstring_to_utf8(&pszProfilePath[0], 257) + profile_path = wstring_to_utf8(&pszProfilePath[0], 257) or_else "" return true, profile_path } @@ -336,7 +336,7 @@ delete_user_profile :: proc(username: string) -> (ok: bool) { if res == false { return false } - defer win32.local_free(sb) + defer LocalFree(sb) res2 := DeleteProfileW( sb, From dc832ad49fa01b083b08a2e09102a66f31b025c1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 13:20:55 +0100 Subject: [PATCH 195/245] Minor fix --- core/path/filepath/path_windows.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/path/filepath/path_windows.odin b/core/path/filepath/path_windows.odin index 25b2ae500..28238dd6e 100644 --- a/core/path/filepath/path_windows.odin +++ b/core/path/filepath/path_windows.odin @@ -68,7 +68,7 @@ temp_full_path :: proc(name: string) -> (path: string, err: os.Errno) { return "", os.Errno(win32.GetLastError()) } if n <= u32(len(buf)) { - return win32.utf16_to_utf8(buf[:n], ta), os.ERROR_NONE + return win32.utf16_to_utf8(buf[:n], ta) or_else "", os.ERROR_NONE } resize(&buf, len(buf)*2) } From 2fb351bf04ee2af9c43858f7178d1bee1e1c7a06 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 13:45:17 +0100 Subject: [PATCH 196/245] Update sys/windows to be closer to the soon to be deleted sys/win32 --- core/sys/windows/bluetooth.odin | 2 +- core/sys/windows/comdlg32.odin | 168 ++++++++++++++++++++++++++++++++ core/sys/windows/kernel32.odin | 4 +- core/sys/windows/ntdll.odin | 4 +- core/sys/windows/shell32.odin | 2 +- core/sys/windows/wgl.odin | 87 +++++++++++++++++ 6 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 core/sys/windows/comdlg32.odin create mode 100644 core/sys/windows/wgl.odin diff --git a/core/sys/windows/bluetooth.odin b/core/sys/windows/bluetooth.odin index c9f6bcc93..dad44892a 100644 --- a/core/sys/windows/bluetooth.odin +++ b/core/sys/windows/bluetooth.odin @@ -51,7 +51,7 @@ BLUETOOTH_DEVICE_INFO :: struct { name: [BLUETOOTH_MAX_NAME_SIZE]u16, // Name of the device } -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign bthprops { /* Version diff --git a/core/sys/windows/comdlg32.odin b/core/sys/windows/comdlg32.odin new file mode 100644 index 000000000..a3709cba7 --- /dev/null +++ b/core/sys/windows/comdlg32.odin @@ -0,0 +1,168 @@ +// +build windows +package sys_windows + +foreign import "system:Comdlg32.lib" +import "core:strings" + +LPOFNHOOKPROC :: #type proc "stdcall" (hdlg: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR + +OPENFILENAMEW :: struct { + lStructSize: DWORD, + hwndOwner: HWND, + hInstance: HINSTANCE, + lpstrFilter: wstring, + lpstrCustomFilter: wstring, + nMaxCustFilter: DWORD, + nFilterIndex: DWORD, + lpstrFile: wstring, + nMaxFile: DWORD, + lpstrFileTitle: wstring, + nMaxFileTitle: DWORD, + lpstrInitialDir: wstring, + lpstrTitle: wstring, + Flags: DWORD, + nFileOffset: WORD, + nFileExtension: WORD, + lpstrDefExt: wstring, + lCustData: LPARAM, + lpfnHook: LPOFNHOOKPROC, + lpTemplateName: wstring, + lpEditInfo: rawptr, // LPEDITMENU, + lpstrPrompt: wstring, + pvReserved: rawptr, + dwReserved: DWORD, + FlagsEx: DWORD, +} + +@(default_calling_convention="stdcall") +foreign Comdlg32 { + GetOpenFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL --- + GetSaveFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL --- + CommDlgExtendedError :: proc() -> u32 --- +} + +OPEN_TITLE :: "Select file to open" +OPEN_FLAGS :: u32(OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST) +OPEN_FLAGS_MULTI :: OPEN_FLAGS | OFN_ALLOWMULTISELECT | OFN_EXPLORER + +SAVE_TITLE :: "Select file to save" +SAVE_FLAGS :: u32(OFN_OVERWRITEPROMPT | OFN_EXPLORER) +SAVE_EXT :: "txt" + +Open_Save_Mode :: enum { + Open = 0, + Save = 1, +} + +_open_file_dialog :: proc(title: string, dir: string, + filters: []string, default_filter: u32, + flags: u32, default_ext: string, + mode: Open_Save_Mode, allocator := context.temp_allocator) -> (path: string, ok: bool = true) { + context.allocator = allocator + file_buf := make([]u16, MAX_PATH_WIDE) + defer if !ok { + delete(file_buf) + } + + // Filters need to be passed as a pair of strings (title, filter) + filter_len := u32(len(filters)) + if filter_len % 2 != 0 { + return "", false + } + + filter: string + filter = strings.join(filters, "\u0000", context.temp_allocator) + filter = strings.concatenate({filter, "\u0000"}, context.temp_allocator) + + ofn := OPENFILENAMEW{ + lStructSize = size_of(OPENFILENAMEW), + lpstrFile = wstring(&file_buf[0]), + nMaxFile = MAX_PATH_WIDE, + lpstrTitle = utf8_to_wstring(title, context.temp_allocator), + lpstrFilter = utf8_to_wstring(filter, context.temp_allocator), + lpstrInitialDir = utf8_to_wstring(dir, context.temp_allocator), + nFilterIndex = u32(clamp(default_filter, 1, filter_len / 2)), + lpstrDefExt = utf8_to_wstring(default_ext, context.temp_allocator), + Flags = u32(flags), + } + + switch mode { + case .Open: + ok = bool(GetOpenFileNameW(&ofn)) + case .Save: + ok = bool(GetSaveFileNameW(&ofn)) + case: + ok = false + } + + if !ok { + return + } + + + file_name, _ := utf16_to_utf8(file_buf[:], allocator) + path = strings.trim_right_null(file_name) + return +} + +select_file_to_open :: proc(title := OPEN_TITLE, dir := ".", + filters := []string{"All Files", "*.*"}, default_filter := u32(1), + flags := OPEN_FLAGS, allocator := context.temp_allocator) -> (path: string, ok: bool) { + + path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, "", Open_Save_Mode.Open, allocator) + return +} + +select_file_to_save :: proc(title := SAVE_TITLE, dir := ".", + filters := []string{"All Files", "*.*"}, default_filter := u32(1), + flags := SAVE_FLAGS, default_ext := SAVE_EXT, + allocator := context.temp_allocator) -> (path: string, ok: bool) { + + path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, default_ext, Open_Save_Mode.Save, allocator) + return +} + +// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes +// it output of the form "path\u0000\file1u\0000file2" and turns it into []string with the path + file pre-concatenated for you. + +OFN_ALLOWMULTISELECT :: 0x00000200 // NOTE(Jeroen): Without OFN_EXPLORER it uses the Win3 dialog. +OFN_CREATEPROMPT :: 0x00002000 +OFN_DONTADDTORECENT :: 0x02000000 +OFN_ENABLEHOOK :: 0x00000020 +OFN_ENABLEINCLUDENOTIFY :: 0x00400000 +OFN_ENABLESIZING :: 0x00800000 +OFN_ENABLETEMPLATE :: 0x00000040 +OFN_ENABLETEMPLATEHANDLE :: 0x00000080 +OFN_EXPLORER :: 0x00080000 +OFN_EXTENSIONDIFFERENT :: 0x00000400 +OFN_FILEMUSTEXIST :: 0x00001000 +OFN_FORCESHOWHIDDEN :: 0x10000000 +OFN_HIDEREADONLY :: 0x00000004 +OFN_LONGNAMES :: 0x00200000 +OFN_NOCHANGEDIR :: 0x00000008 +OFN_NODEREFERENCELINKS :: 0x00100000 +OFN_NOLONGNAMES :: 0x00040000 +OFN_NONETWORKBUTTON :: 0x00020000 +OFN_NOREADONLYRETURN :: 0x00008000 +OFN_NOTESTFILECREATE :: 0x00010000 +OFN_NOVALIDATE :: 0x00000100 +OFN_OVERWRITEPROMPT :: 0x00000002 +OFN_PATHMUSTEXIST :: 0x00000800 +OFN_READONLY :: 0x00000001 +OFN_SHAREAWARE :: 0x00004000 +OFN_SHOWHELP :: 0x00000010 + +CDERR_DIALOGFAILURE :: 0x0000FFFF +CDERR_GENERALCODES :: 0x00000000 +CDERR_STRUCTSIZE :: 0x00000001 +CDERR_INITIALIZATION :: 0x00000002 +CDERR_NOTEMPLATE :: 0x00000003 +CDERR_NOHINSTANCE :: 0x00000004 +CDERR_LOADSTRFAILURE :: 0x00000005 +CDERR_FINDRESFAILURE :: 0x00000006 +CDERR_LOADRESFAILURE :: 0x00000007 +CDERR_LOCKRESFAILURE :: 0x00000008 +CDERR_MEMALLOCFAILURE :: 0x00000009 +CDERR_MEMLOCKFAILURE :: 0x0000000A +CDERR_NOHOOK :: 0x0000000B +CDERR_REGISTERMSGFAIL :: 0x0000000C diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index ac959db2d..e235b45ed 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -3,8 +3,6 @@ package sys_windows foreign import kernel32 "system:Kernel32.lib" - - @(default_calling_convention="stdcall") foreign kernel32 { OutputDebugStringA :: proc(lpOutputString: LPCSTR) --- @@ -781,7 +779,7 @@ foreign kernel32 { ) -> BOOL --- } -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign kernel32 { @(link_name="SetConsoleCtrlHandler") set_console_ctrl_handler :: proc(handler: Handler_Routine, add: BOOL) -> BOOL --- } diff --git a/core/sys/windows/ntdll.odin b/core/sys/windows/ntdll.odin index 5deffd9f9..dda5b9711 100644 --- a/core/sys/windows/ntdll.odin +++ b/core/sys/windows/ntdll.odin @@ -3,7 +3,7 @@ package sys_windows foreign import ntdll_lib "system:ntdll.lib" -@(default_calling_convention="std") +@(default_calling_convention="stdcall") foreign ntdll_lib { - RtlGetVersion :: proc(lpVersionInformation: ^OSVERSIONINFOEXW) -> NTSTATUS --- + RtlGetVersion :: proc(lpVersionInformation: ^OSVERSIONINFOEXW) -> NTSTATUS --- } \ No newline at end of file diff --git a/core/sys/windows/shell32.odin b/core/sys/windows/shell32.odin index 70d8943bd..a6ecefc32 100644 --- a/core/sys/windows/shell32.odin +++ b/core/sys/windows/shell32.odin @@ -3,7 +3,7 @@ package sys_windows foreign import shell32 "system:Shell32.lib" -@(default_calling_convention = "std") +@(default_calling_convention="stdcall") foreign shell32 { CommandLineToArgvW :: proc(cmd_list: wstring, num_args: ^c_int) -> ^wstring --- } diff --git a/core/sys/windows/wgl.odin b/core/sys/windows/wgl.odin new file mode 100644 index 000000000..689a41dea --- /dev/null +++ b/core/sys/windows/wgl.odin @@ -0,0 +1,87 @@ +// +build windows +package sys_windows + +import "core:c" + +foreign import "system:Opengl32.lib" + +CONTEXT_MAJOR_VERSION_ARB :: 0x2091 +CONTEXT_MINOR_VERSION_ARB :: 0x2092 +CONTEXT_FLAGS_ARB :: 0x2094 +CONTEXT_PROFILE_MASK_ARB :: 0x9126 +CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002 +CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001 +CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002 + +HGLRC :: distinct HANDLE + +LPLAYERPLANEDESCRIPTOR :: ^LAYERPLANEDESCRIPTOR +LAYERPLANEDESCRIPTOR :: struct { + nSize: WORD, + nVersion: WORD, + dwFlags: DWORD, + iPixelType: BYTE, + cColorBits: BYTE, + cRedBits: BYTE, + cRedShift: BYTE, + cGreenBits: BYTE, + cGreenShift: BYTE, + cBlueBits: BYTE, + cBlueShift: BYTE, + cAlphaBits: BYTE, + cAlphaShift: BYTE, + cAccumBits: BYTE, + cAccumRedBits: BYTE, + cAccumGreenBits: BYTE, + cAccumBlueBits: BYTE, + cAccumAlphaBits: BYTE, + cDepthBits: BYTE, + cStencilBits: BYTE, + cAuxBuffers: BYTE, + iLayerPlane: BYTE, + bReserved: BYTE, + crTransparent: COLORREF, +} + +POINTFLOAT :: struct {x, y: f32} + +LPGLYPHMETRICSFLOAT :: ^GLYPHMETRICSFLOAT +GLYPHMETRICSFLOAT :: struct { + gmfBlackBoxX: f32, + gmfBlackBoxY: f32, + gmfptGlyphOrigin: POINTFLOAT, + gmfCellIncX: f32, + gmfCellIncY: f32, +} + +CreateContextAttribsARBType :: #type proc "c" (hdc: HDC, hShareContext: rawptr, attribList: [^]c.int) -> HGLRC +ChoosePixelFormatARBType :: #type proc "c" (hdc: HDC, attribIList: [^]c.int, attribFList: [^]f32, maxFormats: DWORD, formats: [^]c.int, numFormats: [^]DWORD) -> BOOL +SwapIntervalEXTType :: #type proc "c" (interval: c.int) -> bool +GetExtensionsStringARBType :: #type proc "c" (HDC) -> cstring + +// Procedures + wglCreateContextAttribsARB: CreateContextAttribsARBType + wglChoosePixelFormatARB: ChoosePixelFormatARBType + wglSwapIntervalExt: SwapIntervalEXTType + wglGetExtensionsStringARB: GetExtensionsStringARBType + + +@(default_calling_convention="stdcall") +foreign Opengl32 { + wglCreateContext :: proc(hdc: HDC) -> HGLRC --- + wglMakeCurrent :: proc(hdc: HDC, HGLRC: HGLRC) -> BOOL --- + wglGetProcAddress :: proc(c_str: cstring) -> rawptr --- + wglDeleteContext :: proc(HGLRC: HGLRC) -> BOOL --- + wglCopyContext :: proc(src, dst: HGLRC, mask: UINT) -> BOOL --- + wglCreateLayerContext :: proc(hdc: HDC, layer_plane: c.int) -> HGLRC --- + wglDescribeLayerPlane :: proc(hdc: HDC, pixel_format, layer_plane: c.int, bytes: UINT, pd: LPLAYERPLANEDESCRIPTOR) -> BOOL --- + wglGetCurrentContext :: proc() -> HGLRC --- + wglGetCurrentDC :: proc() -> HDC --- + wglGetLayerPaletteEntries :: proc(hdc: HDC, layer_plane, start, entries: c.int, cr: ^COLORREF) -> c.int --- + wglRealizeLayerPalette :: proc(hdc: HDC, layer_plane: c.int, realize: BOOL) -> BOOL --- + wglSetLayerPaletteEntries :: proc(hdc: HDC, layer_plane, start, entries: c.int, cr: ^COLORREF) -> c.int --- + wglShareLists :: proc(HGLRC1, HGLRC2: HGLRC) -> BOOL --- + wglSwapLayerBuffers :: proc(hdc: HDC, planes: DWORD) -> BOOL --- + wglUseFontBitmaps :: proc(hdc: HDC, first, count, list_base: DWORD) -> BOOL --- + wglUseFontOutlines :: proc(hdc: HDC, first, count, list_base: DWORD, deviation, extrusion: f32, format: c.int, gmf: LPGLYPHMETRICSFLOAT) -> BOOL --- +} From d1fc9d3073ac85e643199d7558c6fce548084ba3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 13:54:40 +0100 Subject: [PATCH 197/245] Add more libraries --- core/sys/windows/advapi32.odin | 6 ++ core/sys/windows/kernel32.odin | 3 +- core/sys/windows/ole32.odin | 18 +++++ core/sys/windows/shlwapi.odin | 11 +++ core/sys/windows/types.odin | 143 ++++++++++++++++++++++++++++++--- 5 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 core/sys/windows/ole32.odin create mode 100644 core/sys/windows/shlwapi.odin diff --git a/core/sys/windows/advapi32.odin b/core/sys/windows/advapi32.odin index a2a24242f..20badb5da 100644 --- a/core/sys/windows/advapi32.odin +++ b/core/sys/windows/advapi32.odin @@ -3,6 +3,8 @@ package sys_windows foreign import advapi32 "system:Advapi32.lib" +HCRYPTPROV :: distinct HANDLE + @(default_calling_convention="stdcall") foreign advapi32 { @(link_name = "SystemFunction036") @@ -10,6 +12,10 @@ foreign advapi32 { OpenProcessToken :: proc(ProcessHandle: HANDLE, DesiredAccess: DWORD, TokenHandle: ^HANDLE) -> BOOL --- + + CryptAcquireContextW :: proc(hProv: ^HCRYPTPROV, szContainer, szProvider: wstring, dwProvType, dwFlags: DWORD) -> DWORD --- + CryptGenRandom :: proc(hProv: HCRYPTPROV, dwLen: DWORD, buf: LPVOID) -> DWORD --- + CryptReleaseContext :: proc(hProv: HCRYPTPROV, dwFlags: DWORD) -> DWORD --- } // Necessary to create a token to impersonate a user with for CreateProcessAsUser diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index e235b45ed..f52fb46e6 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -21,7 +21,8 @@ foreign kernel32 { GetConsoleMode :: proc(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL --- - + SetConsoleMode :: proc(hConsoleHandle: HANDLE, + dwMode: DWORD) -> BOOL --- GetFileInformationByHandle :: proc(hFile: HANDLE, lpFileInformation: LPBY_HANDLE_FILE_INFORMATION) -> BOOL --- SetHandleInformation :: proc(hObject: HANDLE, diff --git a/core/sys/windows/ole32.odin b/core/sys/windows/ole32.odin new file mode 100644 index 000000000..23fe888d2 --- /dev/null +++ b/core/sys/windows/ole32.odin @@ -0,0 +1,18 @@ +// +build windows +package sys_windows + +foreign import "system:Ole32.lib" + +//objbase.h +COINIT :: enum DWORD { + APARTMENTTHREADED = 0x2, + MULTITHREADED, + DISABLE_OLE1DDE = 0x4, + SPEED_OVER_MEMORY = 0x8, +} + +@(default_calling_convention="stdcall") +foreign Ole32 { + CoInitializeEx :: proc(reserved: rawptr, co_init: COINIT) -> HRESULT --- + CoUninitialize :: proc() --- +} diff --git a/core/sys/windows/shlwapi.odin b/core/sys/windows/shlwapi.odin new file mode 100644 index 000000000..1852d536f --- /dev/null +++ b/core/sys/windows/shlwapi.odin @@ -0,0 +1,11 @@ +// +build windows +package sys_windows + +foreign import shlwapi "system:shlwapi.lib" + +@(default_calling_convention="stdcall") +foreign shlwapi { + PathFileExistsW :: proc(pszPath: wstring) -> BOOL --- + PathFindExtensionW :: proc(pszPath: wstring) -> wstring --- + PathFindFileNameW :: proc(pszPath: wstring) -> wstring --- +} diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 4f594e22d..b497f181e 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -3,19 +3,21 @@ package sys_windows import "core:c" -c_char :: c.char -c_uchar :: c.uchar -c_int :: c.int -c_uint :: c.uint -c_long :: c.long -c_longlong :: c.longlong -c_ulong :: c.ulong -c_short :: c.short -c_ushort :: c.ushort -size_t :: c.size_t -wchar_t :: c.wchar_t +c_char :: c.char +c_uchar :: c.uchar +c_int :: c.int +c_uint :: c.uint +c_long :: c.long +c_longlong :: c.longlong +c_ulong :: c.ulong +c_ulonglong :: c.ulonglong +c_short :: c.short +c_ushort :: c.ushort +size_t :: c.size_t +wchar_t :: c.wchar_t DWORD :: c_ulong +QWORD :: c.ulonglong HANDLE :: distinct LPVOID HINSTANCE :: HANDLE HMODULE :: distinct HINSTANCE @@ -2170,3 +2172,122 @@ SYSTEMTIME :: struct { second: WORD, milliseconds: WORD, } + + +@(private="file") +IMAGE_DOS_HEADER :: struct { + e_magic: WORD, + e_cblp: WORD, + e_cp: WORD, + e_crlc: WORD, + e_cparhdr: WORD, + e_minalloc: WORD, + e_maxalloc: WORD, + e_ss: WORD, + e_sp: WORD, + e_csum: WORD, + e_ip: WORD, + e_cs: WORD, + e_lfarlc: WORD, + e_ovno: WORD, + e_res_0: WORD, + e_res_1: WORD, + e_res_2: WORD, + e_res_3: WORD, + e_oemid: WORD, + e_oeminfo: WORD, + e_res2_0: WORD, + e_res2_1: WORD, + e_res2_2: WORD, + e_res2_3: WORD, + e_res2_4: WORD, + e_res2_5: WORD, + e_res2_6: WORD, + e_res2_7: WORD, + e_res2_8: WORD, + e_res2_9: WORD, + e_lfanew: DWORD, +} + +IMAGE_DATA_DIRECTORY :: struct { + VirtualAddress: DWORD, + Size: DWORD, +} + +IMAGE_FILE_HEADER :: struct { + Machine: WORD, + NumberOfSections: WORD, + TimeDateStamp: DWORD, + PointerToSymbolTable: DWORD, + NumberOfSymbols: DWORD, + SizeOfOptionalHeader: WORD, + Characteristics: WORD, +} + +IMAGE_OPTIONAL_HEADER64 :: struct { + Magic: WORD, + MajorLinkerVersion: BYTE, + MinorLinkerVersion: BYTE, + SizeOfCode: DWORD, + SizeOfInitializedData: DWORD, + SizeOfUninitializedData: DWORD, + AddressOfEntryPoint: DWORD, + BaseOfCode: DWORD, + ImageBase: QWORD, + SectionAlignment: DWORD, + FileAlignment: DWORD, + MajorOperatingSystemVersion: WORD, + MinorOperatingSystemVersion: WORD, + MajorImageVersion: WORD, + MinorImageVersion: WORD, + MajorSubsystemVersion: WORD, + MinorSubsystemVersion: WORD, + Win32VersionValue: DWORD, + SizeOfImage: DWORD, + SizeOfHeaders: DWORD, + CheckSum: DWORD, + Subsystem: WORD, + DllCharacteristics: WORD, + SizeOfStackReserve: QWORD, + SizeOfStackCommit: QWORD, + SizeOfHeapReserve: QWORD, + SizeOfHeapCommit: QWORD, + LoaderFlags: DWORD, + NumberOfRvaAndSizes: DWORD, + ExportTable: IMAGE_DATA_DIRECTORY, + ImportTable: IMAGE_DATA_DIRECTORY, + ResourceTable: IMAGE_DATA_DIRECTORY, + ExceptionTable: IMAGE_DATA_DIRECTORY, + CertificateTable: IMAGE_DATA_DIRECTORY, + BaseRelocationTable: IMAGE_DATA_DIRECTORY, + Debug: IMAGE_DATA_DIRECTORY, + Architecture: IMAGE_DATA_DIRECTORY, + GlobalPtr: IMAGE_DATA_DIRECTORY, + TLSTable: IMAGE_DATA_DIRECTORY, + LoadConfigTable: IMAGE_DATA_DIRECTORY, + BoundImport: IMAGE_DATA_DIRECTORY, + IAT: IMAGE_DATA_DIRECTORY, + DelayImportDescriptor: IMAGE_DATA_DIRECTORY, + CLRRuntimeHeader: IMAGE_DATA_DIRECTORY, + Reserved: IMAGE_DATA_DIRECTORY, +} + +IMAGE_NT_HEADERS64 :: struct { + Signature: DWORD, + FileHeader: IMAGE_FILE_HEADER, + OptionalHeader: IMAGE_OPTIONAL_HEADER64, +} + +IMAGE_EXPORT_DIRECTORY :: struct { + Characteristics: DWORD, + TimeDateStamp: DWORD, + MajorVersion: WORD, + MinorVersion: WORD, + Name: DWORD, + Base: DWORD, + NumberOfFunctions: DWORD, + NumberOfNames: DWORD, + AddressOfFunctions: DWORD, // RVA from base of image + AddressOfNames: DWORD, // RVA from base of image + AddressOfNameOrdinals: DWORD, // RVA from base of image +} \ No newline at end of file From 0c45a46aab99fdd924afd8e0385fd27e40c60dec Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 14:21:25 +0100 Subject: [PATCH 198/245] Remove `A` calls in favour of `W` calls --- core/sys/windows/bluetooth.odin | 47 ++++-------------- core/sys/windows/kernel32.odin | 3 +- core/sys/windows/synchronization.odin | 4 +- core/sys/windows/user32.odin | 68 +-------------------------- core/sys/windows/util.odin | 32 ++++++------- core/sys/windows/winmm.odin | 2 +- 6 files changed, 33 insertions(+), 123 deletions(-) diff --git a/core/sys/windows/bluetooth.odin b/core/sys/windows/bluetooth.odin index dad44892a..c2534896b 100644 --- a/core/sys/windows/bluetooth.odin +++ b/core/sys/windows/bluetooth.odin @@ -56,49 +56,22 @@ foreign bthprops { /* Version */ - @(link_name="BluetoothIsVersionAvailable") bluetooth_is_version_available :: proc( - major: u8, minor: u8, - ) -> BOOL --- + BluetoothIsVersionAvailable :: proc(major: u8, minor: u8) -> BOOL --- /* Radio enumeration */ - @(link_name="BluetoothFindFirstRadio") bluetooth_find_first_radio :: proc( - find_radio_params: ^BLUETOOTH_FIND_RADIO_PARAMS, radio: ^HANDLE, - ) -> HBLUETOOTH_RADIO_FIND --- - - @(link_name="BluetoothFindNextRadio") bluetooth_find_next_radio :: proc( - handle: HBLUETOOTH_RADIO_FIND, radio: ^HANDLE, - ) -> BOOL --- - - @(link_name="BluetoothFindRadioClose") bluetooth_find_radio_close :: proc( - handle: HBLUETOOTH_RADIO_FIND, - ) -> BOOL --- - - @(link_name="BluetoothGetRadioInfo") bluetooth_get_radio_info :: proc( - radio: HANDLE, radio_info: ^BLUETOOTH_RADIO_INFO, - ) -> DWORD --- + BluetoothFindFirstRadio :: proc(find_radio_params: ^BLUETOOTH_FIND_RADIO_PARAMS, radio: ^HANDLE) -> HBLUETOOTH_RADIO_FIND --- + BluetoothFindNextRadio :: proc(handle: HBLUETOOTH_RADIO_FIND, radio: ^HANDLE) -> BOOL --- + BluetoothFindRadioClose :: proc(handle: HBLUETOOTH_RADIO_FIND) -> BOOL --- + BluetoothGetRadioInfo :: proc(radio: HANDLE, radio_info: ^BLUETOOTH_RADIO_INFO) -> DWORD --- /* Device enumeration */ - @(link_name="BluetoothFindFirstDevice") bluetooth_find_first_device :: proc( - search_params: ^BLUETOOTH_DEVICE_SEARCH_PARAMS, device_info: ^BLUETOOTH_DEVICE_INFO, - ) -> HBLUETOOTH_DEVICE_FIND --- - - @(link_name="BluetoothFindNextDevice") bluetooth_find_next_device :: proc( - handle: HBLUETOOTH_DEVICE_FIND, device_info: ^BLUETOOTH_DEVICE_INFO, - ) -> BOOL --- - - @(link_name="BluetoothFindDeviceClose") bluetooth_find_device_close :: proc( - handle: HBLUETOOTH_DEVICE_FIND, - ) -> BOOL --- - - @(link_name="BluetoothGetDeviceInfo") bluetooth_get_device_info :: proc( - radio: HANDLE, device_info: ^BLUETOOTH_DEVICE_INFO, - ) -> DWORD --- - - @(link_name="BluetoothDisplayDeviceProperties") bluetooth_display_device_properties :: proc( - hwnd_parent: HWND, device_info: ^BLUETOOTH_DEVICE_INFO, - ) -> BOOL --- + BluetoothFindFirstDevice :: proc(search_params: ^BLUETOOTH_DEVICE_SEARCH_PARAMS, device_info: ^BLUETOOTH_DEVICE_INFO) -> HBLUETOOTH_DEVICE_FIND --- + BluetoothFindNextDevice :: proc(handle: HBLUETOOTH_DEVICE_FIND, device_info: ^BLUETOOTH_DEVICE_INFO) -> BOOL --- + BluetoothFindDeviceClose :: proc(handle: HBLUETOOTH_DEVICE_FIND) -> BOOL --- + BluetoothGetDeviceInfo :: proc(radio: HANDLE, device_info: ^BLUETOOTH_DEVICE_INFO) -> DWORD --- + BluetoothDisplayDeviceProperties :: proc(hwnd_parent: HWND, device_info: ^BLUETOOTH_DEVICE_INFO) -> BOOL --- } \ No newline at end of file diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index f52fb46e6..ad637db82 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -5,7 +5,8 @@ foreign import kernel32 "system:Kernel32.lib" @(default_calling_convention="stdcall") foreign kernel32 { - OutputDebugStringA :: proc(lpOutputString: LPCSTR) --- + OutputDebugStringA :: proc(lpOutputString: LPCSTR) --- // The only A thing that is allowed + OutputDebugStringW :: proc(lpOutputString: LPCSTR) --- ReadConsoleW :: proc(hConsoleInput: HANDLE, lpBuffer: LPVOID, diff --git a/core/sys/windows/synchronization.odin b/core/sys/windows/synchronization.odin index c4e1d2188..c98730aa0 100644 --- a/core/sys/windows/synchronization.odin +++ b/core/sys/windows/synchronization.odin @@ -5,7 +5,7 @@ foreign import Synchronization "system:Synchronization.lib" @(default_calling_convention="stdcall") foreign Synchronization { - WaitOnAddress :: proc(Address: PVOID, CompareAddress: PVOID, AddressSize: SIZE_T, dwMilliseconds: DWORD) -> BOOL --- + WaitOnAddress :: proc(Address: PVOID, CompareAddress: PVOID, AddressSize: SIZE_T, dwMilliseconds: DWORD) -> BOOL --- WakeByAddressSingle :: proc(Address: PVOID) --- - WakeByAddressAll :: proc(Address: PVOID) --- + WakeByAddressAll :: proc(Address: PVOID) --- } diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 2010f0810..1b6d23ba4 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -5,43 +5,20 @@ foreign import user32 "system:User32.lib" @(default_calling_convention="stdcall") foreign user32 { - GetClassInfoA :: proc(hInstance: HINSTANCE, lpClassNAme: LPCSTR, lpWndClass: ^WNDCLASSA) -> BOOL --- GetClassInfoW :: proc(hInstance: HINSTANCE, lpClassNAme: LPCWSTR, lpWndClass: ^WNDCLASSW) -> BOOL --- - GetClassInfoExA :: proc(hInsatnce: HINSTANCE, lpszClass: LPCSTR, lpwcx: ^WNDCLASSEXA) -> BOOL --- GetClassInfoExW :: proc(hInsatnce: HINSTANCE, lpszClass: LPCWSTR, lpwcx: ^WNDCLASSEXW) -> BOOL --- - GetClassLongA :: proc(hWnd: HWND, nIndex: c_int) -> DWORD --- GetClassLongW :: proc(hWnd: HWND, nIndex: c_int) -> DWORD --- - SetClassLongA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> DWORD --- SetClassLongW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> DWORD --- - GetWindowLongA :: proc(hWnd: HWND, nIndex: c_int) -> LONG --- GetWindowLongW :: proc(hWnd: HWND, nIndex: c_int) -> LONG --- - SetWindowLongA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> LONG --- SetWindowLongW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> LONG --- - GetClassNameA :: proc(hWnd: HWND, lpClassName: LPSTR, nMaxCount: c_int) -> c_int --- GetClassNameW :: proc(hWnd: HWND, lpClassName: LPWSTR, nMaxCount: c_int) -> c_int --- - RegisterClassA :: proc(lpWndClass: ^WNDCLASSA) -> ATOM --- RegisterClassW :: proc(lpWndClass: ^WNDCLASSW) -> ATOM --- - RegisterClassExA :: proc(^WNDCLASSEXA) -> ATOM --- RegisterClassExW :: proc(^WNDCLASSEXW) -> ATOM --- - CreateWindowExA :: proc( - dwExStyle: DWORD, - lpClassName: LPCSTR, - lpWindowName: LPCSTR, - dwStyle: DWORD, - X: c_int, - Y: c_int, - nWidth: c_int, - nHeight: c_int, - hWndParent: HWND, - hMenu: HMENU, - hInstance: HINSTANCE, - lpParam: LPVOID, - ) -> HWND --- CreateWindowExW :: proc( dwExStyle: DWORD, lpClassName: LPCWSTR, @@ -67,11 +44,9 @@ foreign user32 { SetActiveWindow :: proc(hWnd: HWND) -> HWND --- GetActiveWindow :: proc() -> HWND --- - GetMessageA :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- TranslateMessage :: proc(lpMsg: ^MSG) -> BOOL --- - DispatchMessageA :: proc(lpMsg: ^MSG) -> LRESULT --- DispatchMessageW :: proc(lpMsg: ^MSG) -> LRESULT --- PeekMessageA :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) -> BOOL --- @@ -141,10 +116,8 @@ foreign user32 { GetKeyState :: proc(nVirtKey: c_int) -> SHORT --- GetAsyncKeyState :: proc(vKey: c_int) -> SHORT --- - MapVirtualKeyA :: proc(uCode: UINT, uMapType: UINT) -> UINT --- MapVirtualKeyW :: proc(uCode: UINT, uMapType: UINT) -> UINT --- - SetWindowsHookExA :: proc(idHook: c_int, lpfn: HOOKPROC, hmod: HINSTANCE, dwThreadId: DWORD) -> HHOOK --- SetWindowsHookExW :: proc(idHook: c_int, lpfn: HOOKPROC, hmod: HINSTANCE, dwThreadId: DWORD) -> HHOOK --- UnhookWindowsHookEx :: proc(hhk: HHOOK) -> BOOL --- CallNextHookEx :: proc(hhk: HHOOK, nCode: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- @@ -152,9 +125,9 @@ foreign user32 { SetTimer :: proc(hWnd: HWND, nIDEvent: UINT_PTR, uElapse: UINT, lpTimerFunc: TIMERPROC) -> UINT_PTR --- KillTimer :: proc(hWnd: HWND, uIDEvent: UINT_PTR) -> BOOL --- - MessageBoxA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT) -> c_int --- + // MessageBoxA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT) -> c_int --- MessageBoxW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT) -> c_int --- - MessageBoxExA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT, wLanguageId: WORD) -> c_int --- + // MessageBoxExA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT, wLanguageId: WORD) -> c_int --- MessageBoxExW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT, wLanguageId: WORD) -> c_int --- ClipCursor :: proc(lpRect: LPRECT) -> BOOL --- @@ -163,35 +136,6 @@ foreign user32 { SetCursor :: proc(hCursor: HCURSOR) -> HCURSOR --- } -CreateWindowA :: #force_inline proc "stdcall" ( - lpClassName: LPCSTR, - lpWindowName: LPCSTR, - dwStyle: DWORD, - X: c_int, - Y: c_int, - nWidth: c_int, - nHeight: c_int, - hWndParent: HWND, - hMenu: HMENU, - hInstance: HINSTANCE, - lpParam: LPVOID, -) -> HWND { - return CreateWindowExA( - 0, - lpClassName, - lpWindowName, - dwStyle, - X, - Y, - nWidth, - nHeight, - hWndParent, - hMenu, - hInstance, - lpParam, - ) -} - CreateWindowW :: #force_inline proc "stdcall" ( lpClassName: LPCTSTR, lpWindowName: LPCTSTR, @@ -224,25 +168,17 @@ CreateWindowW :: #force_inline proc "stdcall" ( when ODIN_ARCH == .amd64 { @(default_calling_convention="stdcall") foreign user32 { - GetClassLongPtrA :: proc(hWnd: HWND, nIndex: c_int) -> ULONG_PTR --- GetClassLongPtrW :: proc(hWnd: HWND, nIndex: c_int) -> ULONG_PTR --- - SetClassLongPtrA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> ULONG_PTR --- SetClassLongPtrW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> ULONG_PTR --- - GetWindowLongPtrA :: proc(hWnd: HWND, nIndex: c_int) -> LONG_PTR --- GetWindowLongPtrW :: proc(hWnd: HWND, nIndex: c_int) -> LONG_PTR --- - SetWindowLongPtrA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> LONG_PTR --- SetWindowLongPtrW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> LONG_PTR --- } } else when ODIN_ARCH == .i386 { - GetClassLongPtrA :: GetClassLongA GetClassLongPtrW :: GetClassLongW - SetClassLongPtrA :: SetClassLongA SetClassLongPtrW :: SetClassLongW - GetWindowLongPtrA :: GetWindowLongA GetWindowLongPtrW :: GetWindowLongW - SetWindowLongPtrA :: GetWindowLongA SetWindowLongPtrW :: GetWindowLongW } diff --git a/core/sys/windows/util.odin b/core/sys/windows/util.odin index 5c8f35bef..1c8b9175b 100644 --- a/core/sys/windows/util.odin +++ b/core/sys/windows/util.odin @@ -451,20 +451,20 @@ run_as_user :: proc(username, password, application, commandline: string, pi: ^P nil, // lpProcessAttributes, nil, // lpThreadAttributes, false, // bInheritHandles, - 0, // creation flags - nil, // environment, - nil, // current directory: inherit from parent if nil - &si, - pi, - )) - if ok { - if wait { - WaitForSingleObject(pi.hProcess, INFINITE) - CloseHandle(pi.hProcess) - CloseHandle(pi.hThread) - } - return true - } else { - return false - } + 0, // creation flags + nil, // environment, + nil, // current directory: inherit from parent if nil + &si, + pi, + )) + if ok { + if wait { + WaitForSingleObject(pi.hProcess, INFINITE) + CloseHandle(pi.hProcess) + CloseHandle(pi.hThread) + } + return true + } else { + return false + } } diff --git a/core/sys/windows/winmm.odin b/core/sys/windows/winmm.odin index 9edd56acc..17f4d8e86 100644 --- a/core/sys/windows/winmm.odin +++ b/core/sys/windows/winmm.odin @@ -6,5 +6,5 @@ foreign import winmm "system:Winmm.lib" @(default_calling_convention="stdcall") foreign winmm { timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT --- - timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT --- + timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT --- } From 6c14586fff6361096edfb54582a6a96f8c50a23b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 14:27:46 +0100 Subject: [PATCH 199/245] Add `GetAddrInfoExW` --- core/sys/windows/types.odin | 27 +++++++++++++++++++++++++++ core/sys/windows/ws2_32.odin | 13 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index b497f181e..c64207e92 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -1566,6 +1566,33 @@ ADDRINFOA :: struct { ai_next: ^ADDRINFOA, } +PADDRINFOEXW :: ^ADDRINFOEXW +LPADDRINFOEXW :: ^ADDRINFOEXW +ADDRINFOEXW :: struct { + ai_flags: c_int, + ai_family: c_int, + ai_socktype: c_int, + ai_protocol: c_int, + ai_addrlen: size_t, + ai_canonname: wstring, + ai_addr: ^sockaddr, + ai_blob: rawptr, + ai_bloblen: size_t, + ai_provider: LPGUID, + ai_next: ^ADDRINFOEXW, +} + +LPLOOKUPSERVICE_COMPLETION_ROUTINE :: #type proc "stdcall" ( + dwErrorCode: DWORD, + dwNumberOfBytesTransfered: DWORD, + lpOverlapped: LPOVERLAPPED, +) + +sockaddr :: struct { + sa_family: USHORT, + sa_data: [14]byte, +} + sockaddr_in :: struct { sin_family: ADDRESS_FAMILY, sin_port: USHORT, diff --git a/core/sys/windows/ws2_32.odin b/core/sys/windows/ws2_32.odin index 0cff5c2da..09af86bce 100644 --- a/core/sys/windows/ws2_32.odin +++ b/core/sys/windows/ws2_32.odin @@ -87,6 +87,19 @@ foreign ws2_32 { res: ^^ADDRINFOA, ) -> c_int --- freeaddrinfo :: proc(res: ^ADDRINFOA) --- + FreeAddrInfoExW :: proc(pAddrInfoEx: PADDRINFOEXW) --- + GetAddrInfoExW :: proc( + pName: PCWSTR, + pServiceName: PCWSTR, + dwNameSpace: DWORD, + lpNspId: LPGUID, + hints: ^ADDRINFOEXW, + ppResult: ^PADDRINFOEXW, + timeout: ^timeval, + lpOverlapped: LPOVERLAPPED, + lpCompletionRoutine: LPLOOKUPSERVICE_COMPLETION_ROUTINE, + lpHandle: LPHANDLE) -> INT --- + select :: proc( nfds: c_int, readfds: ^fd_set, From 97739da85a9812e37d1c349eb36f899b157dc8f5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 14:33:03 +0100 Subject: [PATCH 200/245] Remove `core:sys/win32` --- core/sys/win32/comdlg32.odin | 194 ----- core/sys/win32/crt.odin | 15 - core/sys/win32/gdi32.odin | 26 - core/sys/win32/general.odin | 1178 ----------------------------- core/sys/win32/helpers.odin | 29 - core/sys/win32/kernel32.odin | 237 ------ core/sys/win32/ole32.odin | 18 - core/sys/win32/removal.odin | 3 + core/sys/win32/shell32.odin | 9 - core/sys/win32/tests/general.odin | 41 - core/sys/win32/user32.odin | 289 ------- core/sys/win32/wgl.odin | 114 --- core/sys/win32/winmm.odin | 12 - 13 files changed, 3 insertions(+), 2162 deletions(-) delete mode 100644 core/sys/win32/comdlg32.odin delete mode 100644 core/sys/win32/crt.odin delete mode 100644 core/sys/win32/gdi32.odin delete mode 100644 core/sys/win32/general.odin delete mode 100644 core/sys/win32/helpers.odin delete mode 100644 core/sys/win32/kernel32.odin delete mode 100644 core/sys/win32/ole32.odin create mode 100644 core/sys/win32/removal.odin delete mode 100644 core/sys/win32/shell32.odin delete mode 100644 core/sys/win32/tests/general.odin delete mode 100644 core/sys/win32/user32.odin delete mode 100644 core/sys/win32/wgl.odin delete mode 100644 core/sys/win32/winmm.odin diff --git a/core/sys/win32/comdlg32.odin b/core/sys/win32/comdlg32.odin deleted file mode 100644 index 815def7b6..000000000 --- a/core/sys/win32/comdlg32.odin +++ /dev/null @@ -1,194 +0,0 @@ -// +build windows -package win32 - -foreign import "system:comdlg32.lib" -import "core:strings" - -OFN_Hook_Proc :: #type proc "stdcall" (hdlg: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Uint_Ptr - -Open_File_Name_A :: struct { - struct_size: u32, - hwnd_owner: Hwnd, - instance: Hinstance, - filter: cstring, - custom_filter: cstring, - max_cust_filter: u32, - filter_index: u32, - file: cstring, - max_file: u32, - file_title: cstring, - max_file_title: u32, - initial_dir: cstring, - title: cstring, - flags: u32, - file_offset: u16, - file_extension: u16, - def_ext: cstring, - cust_data: Lparam, - hook: OFN_Hook_Proc, - template_name: cstring, - pv_reserved: rawptr, - dw_reserved: u32, - flags_ex: u32, -} - -Open_File_Name_W :: struct { - struct_size: u32, - hwnd_owner: Hwnd, - instance: Hinstance, - filter: Wstring, - custom_filter: Wstring, - max_cust_filter: u32, - filter_index: u32, - file: Wstring, - max_file: u32, - file_title: Wstring, - max_file_title: u32, - initial_dir: Wstring, - title: Wstring, - flags: u32, - file_offset: u16, - file_extension: u16, - def_ext: Wstring, - cust_data: Lparam, - hook: OFN_Hook_Proc, - template_name: Wstring, - pv_reserved: rawptr, - dw_reserved: u32, - flags_ex: u32, -} - -@(default_calling_convention = "c") -foreign comdlg32 { - @(link_name="GetOpenFileNameA") get_open_file_name_a :: proc(arg1: ^Open_File_Name_A) -> Bool --- - @(link_name="GetOpenFileNameW") get_open_file_name_w :: proc(arg1: ^Open_File_Name_W) -> Bool --- - @(link_name="GetSaveFileNameA") get_save_file_name_a :: proc(arg1: ^Open_File_Name_A) -> Bool --- - @(link_name="GetSaveFileNameW") get_save_file_name_w :: proc(arg1: ^Open_File_Name_W) -> Bool --- - @(link_name="CommDlgExtendedError") comm_dlg_extended_error :: proc() -> u32 --- -} - -OPEN_TITLE :: "Select file to open" -OPEN_FLAGS :: u32(OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST) -OPEN_FLAGS_MULTI :: OPEN_FLAGS | OFN_ALLOWMULTISELECT | OFN_EXPLORER - -SAVE_TITLE :: "Select file to save" -SAVE_FLAGS :: u32(OFN_OVERWRITEPROMPT | OFN_EXPLORER) -SAVE_EXT :: "txt" - -Open_Save_Mode :: enum { - Open = 0, - Save = 1, -} - -_open_file_dialog :: proc(title: string, dir: string, - filters: []string, default_filter: u32, - flags: u32, default_ext: string, - mode: Open_Save_Mode, allocator := context.temp_allocator) -> (path: string, ok: bool = true) { - context.allocator = allocator - file_buf := make([]u16, MAX_PATH_WIDE) - defer if !ok { - delete(file_buf) - } - - // Filters need to be passed as a pair of strings (title, filter) - filter_len := u32(len(filters)) - if filter_len % 2 != 0 { - return "", false - } - - filter: string - filter = strings.join(filters, "\u0000", context.temp_allocator) - filter = strings.concatenate({filter, "\u0000"}, context.temp_allocator) - - ofn := Open_File_Name_W{ - struct_size = size_of(Open_File_Name_W), - file = Wstring(&file_buf[0]), - max_file = MAX_PATH_WIDE, - title = utf8_to_wstring(title, context.temp_allocator), - filter = utf8_to_wstring(filter, context.temp_allocator), - initial_dir = utf8_to_wstring(dir, context.temp_allocator), - filter_index = u32(clamp(default_filter, 1, filter_len / 2)), - def_ext = utf8_to_wstring(default_ext, context.temp_allocator), - flags = u32(flags), - } - - switch mode { - case .Open: - ok = bool(get_open_file_name_w(&ofn)) - case .Save: - ok = bool(get_save_file_name_w(&ofn)) - case: - ok = false - } - - if !ok { - return - } - - - file_name, _ := utf16_to_utf8(file_buf[:], allocator) - path = strings.trim_right_null(file_name) - return -} - -select_file_to_open :: proc(title := OPEN_TITLE, dir := ".", - filters := []string{"All Files", "*.*"}, default_filter := u32(1), - flags := OPEN_FLAGS, allocator := context.temp_allocator) -> (path: string, ok: bool) { - - path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, "", Open_Save_Mode.Open, allocator) - return -} - -select_file_to_save :: proc(title := SAVE_TITLE, dir := ".", - filters := []string{"All Files", "*.*"}, default_filter := u32(1), - flags := SAVE_FLAGS, default_ext := SAVE_EXT, - allocator := context.temp_allocator) -> (path: string, ok: bool) { - - path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, default_ext, Open_Save_Mode.Save, allocator) - return -} - -// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes -// it output of the form "path\u0000\file1u\0000file2" and turns it into []string with the path + file pre-concatenated for you. - -OFN_ALLOWMULTISELECT :: 0x00000200 // NOTE(Jeroen): Without OFN_EXPLORER it uses the Win3 dialog. -OFN_CREATEPROMPT :: 0x00002000 -OFN_DONTADDTORECENT :: 0x02000000 -OFN_ENABLEHOOK :: 0x00000020 -OFN_ENABLEINCLUDENOTIFY :: 0x00400000 -OFN_ENABLESIZING :: 0x00800000 -OFN_ENABLETEMPLATE :: 0x00000040 -OFN_ENABLETEMPLATEHANDLE :: 0x00000080 -OFN_EXPLORER :: 0x00080000 -OFN_EXTENSIONDIFFERENT :: 0x00000400 -OFN_FILEMUSTEXIST :: 0x00001000 -OFN_FORCESHOWHIDDEN :: 0x10000000 -OFN_HIDEREADONLY :: 0x00000004 -OFN_LONGNAMES :: 0x00200000 -OFN_NOCHANGEDIR :: 0x00000008 -OFN_NODEREFERENCELINKS :: 0x00100000 -OFN_NOLONGNAMES :: 0x00040000 -OFN_NONETWORKBUTTON :: 0x00020000 -OFN_NOREADONLYRETURN :: 0x00008000 -OFN_NOTESTFILECREATE :: 0x00010000 -OFN_NOVALIDATE :: 0x00000100 -OFN_OVERWRITEPROMPT :: 0x00000002 -OFN_PATHMUSTEXIST :: 0x00000800 -OFN_READONLY :: 0x00000001 -OFN_SHAREAWARE :: 0x00004000 -OFN_SHOWHELP :: 0x00000010 - -CDERR_DIALOGFAILURE :: 0x0000FFFF -CDERR_GENERALCODES :: 0x00000000 -CDERR_STRUCTSIZE :: 0x00000001 -CDERR_INITIALIZATION :: 0x00000002 -CDERR_NOTEMPLATE :: 0x00000003 -CDERR_NOHINSTANCE :: 0x00000004 -CDERR_LOADSTRFAILURE :: 0x00000005 -CDERR_FINDRESFAILURE :: 0x00000006 -CDERR_LOADRESFAILURE :: 0x00000007 -CDERR_LOCKRESFAILURE :: 0x00000008 -CDERR_MEMALLOCFAILURE :: 0x00000009 -CDERR_MEMLOCKFAILURE :: 0x0000000A -CDERR_NOHOOK :: 0x0000000B -CDERR_REGISTERMSGFAIL :: 0x0000000C diff --git a/core/sys/win32/crt.odin b/core/sys/win32/crt.odin deleted file mode 100644 index 8584a27be..000000000 --- a/core/sys/win32/crt.odin +++ /dev/null @@ -1,15 +0,0 @@ -// +build windows -package win32 - -import "core:strings" - -foreign { - @(link_name="_wgetcwd") _get_cwd_wide :: proc(buffer: Wstring, buf_len: int) -> ^Wstring --- -} - -get_cwd :: proc(allocator := context.temp_allocator) -> string { - buffer := make([]u16, MAX_PATH_WIDE, allocator) - _get_cwd_wide(Wstring(&buffer[0]), MAX_PATH_WIDE) - file, _ := utf16_to_utf8(buffer[:], allocator) - return strings.trim_right_null(file) -} diff --git a/core/sys/win32/gdi32.odin b/core/sys/win32/gdi32.odin deleted file mode 100644 index 13bc4796f..000000000 --- a/core/sys/win32/gdi32.odin +++ /dev/null @@ -1,26 +0,0 @@ -// +build windows -package win32 - -foreign import "system:gdi32.lib" - -WHITENESS :: 0x00FF0062 -BLACKNESS :: 0x00000042 - -@(default_calling_convention = "std") -foreign gdi32 { - @(link_name="GetStockObject") get_stock_object :: proc(fn_object: i32) -> Hgdiobj --- - - @(link_name="StretchDIBits") - stretch_dibits :: proc(hdc: Hdc, - x_dst, y_dst, width_dst, height_dst: i32, - x_src, y_src, width_src, header_src: i32, - bits: rawptr, bits_info: ^Bitmap_Info, - usage: u32, - rop: u32) -> i32 --- - - @(link_name="SetPixelFormat") set_pixel_format :: proc(hdc: Hdc, pixel_format: i32, pfd: ^Pixel_Format_Descriptor) -> Bool --- - @(link_name="ChoosePixelFormat") choose_pixel_format :: proc(hdc: Hdc, pfd: ^Pixel_Format_Descriptor) -> i32 --- - @(link_name="SwapBuffers") swap_buffers :: proc(hdc: Hdc) -> Bool --- - - @(link_name="PatBlt") pat_blt :: proc(hdc: Hdc, x, y, w, h: i32, rop: u32) -> Bool --- -} diff --git a/core/sys/win32/general.odin b/core/sys/win32/general.odin deleted file mode 100644 index 64ee952ce..000000000 --- a/core/sys/win32/general.odin +++ /dev/null @@ -1,1178 +0,0 @@ -// +build windows -package win32 - -import "core:runtime" - -Uint_Ptr :: distinct uintptr -Int_Ptr :: distinct int -Long_Ptr :: distinct int - -Handle :: distinct rawptr -Hwnd :: distinct Handle -Hdc :: distinct Handle -Hinstance :: distinct Handle -Hicon :: distinct Handle -Hcursor :: distinct Handle -Hmenu :: distinct Handle -Hbitmap :: distinct Handle -Hbrush :: distinct Handle -Hgdiobj :: distinct Handle -Hmodule :: distinct Handle -Hmonitor :: distinct Handle -Hrawinput :: distinct Handle -Hresult :: distinct i32 -HKL :: distinct Handle -Wparam :: distinct Uint_Ptr -Lparam :: distinct Long_Ptr -Lresult :: distinct Long_Ptr -Wnd_Proc :: distinct #type proc "std" (Hwnd, u32, Wparam, Lparam) -> Lresult -Monitor_Enum_Proc :: distinct #type proc "std" (Hmonitor, Hdc, ^Rect, Lparam) -> bool - - - -Bool :: distinct b32 - -Wstring :: distinct [^]u16 - -Point :: struct { - x, y: i32, -} - -Wnd_Class_A :: struct { - style: u32, - wnd_proc: Wnd_Proc, - cls_extra, wnd_extra: i32, - instance: Hinstance, - icon: Hicon, - cursor: Hcursor, - background: Hbrush, - menu_name, class_name: cstring, -} - -Wnd_Class_W :: struct { - style: u32, - wnd_proc: Wnd_Proc, - cls_extra, wnd_extra: i32, - instance: Hinstance, - icon: Hicon, - cursor: Hcursor, - background: Hbrush, - menu_name, class_name: Wstring, -} - -Wnd_Class_Ex_A :: struct { - size, style: u32, - wnd_proc: Wnd_Proc, - cls_extra, wnd_extra: i32, - instance: Hinstance, - icon: Hicon, - cursor: Hcursor, - background: Hbrush, - menu_name, class_name: cstring, - sm: Hicon, -} - -Wnd_Class_Ex_W :: struct { - size, style: u32, - wnd_proc: Wnd_Proc, - cls_extra, wnd_extra: i32, - instance: Hinstance, - icon: Hicon, - cursor: Hcursor, - background: Hbrush, - menu_name, class_name: Wstring, - sm: Hicon, -} - - -Msg :: struct { - hwnd: Hwnd, - message: u32, - wparam: Wparam, - lparam: Lparam, - time: u32, - pt: Point, -} - -Rect :: struct { - left: i32, - top: i32, - right: i32, - bottom: i32, -} - -Dev_Mode_A :: struct { - device_name: [32]u8, - spec_version: u16, - driver_version: u16, - size: u16, - driver_extra: u16, - fields: u32, - using _: struct #raw_union { - // Printer only fields. - using _: struct { - orientation: i16, - paper_size: i16, - paper_length: i16, - paper_width: i16, - scale: i16, - copies: i16, - default_source: i16, - print_quality: i16, - }, - // Display only fields. - using _: struct { - position: Point, - display_orientation: u32, - display_fixed_output: u32, - }, - }, - color: i16, - duplex: i16, - y_resolution: i16, - tt_option: i16, - collate: i16, - form_name: [32]u8, - log_pixels: u16, - bits_per_pel: u32, - pels_width: u32, - pels_height: u32, - using _: struct #raw_union { - display_flags: u32, - nup: u32, - }, - display_frequency: u32, - icm_method: u32, - icm_intent: u32, - media_type: u32, - dither_type: u32, - reserved_1: u32, - reserved_2: u32, - panning_width: u32, - panning_height: u32, -} - -Filetime :: struct { - lo, hi: u32, -} - -Systemtime :: struct { - year, month: u16, - day_of_week, day: u16, - hour, minute, second, millisecond: u16, -} - -By_Handle_File_Information :: struct { - file_attributes: u32, - creation_time, - last_access_time, - last_write_time: Filetime, - volume_serial_number, - file_size_high, - file_size_low, - number_of_links, - file_index_high, - file_index_low: u32, -} - -File_Attribute_Data :: struct { - file_attributes: u32, - creation_time, - last_access_time, - last_write_time: Filetime, - file_size_high, - file_size_low: u32, -} - -// NOTE(Jeroen): The widechar version might want at least the 32k MAX_PATH_WIDE -// https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findfirstfilew#parameters -Find_Data_W :: struct{ - file_attributes: u32, - creation_time: Filetime, - last_access_time: Filetime, - last_write_time: Filetime, - file_size_high: u32, - file_size_low: u32, - reserved0: u32, - reserved1: u32, - file_name: [MAX_PATH]u16, - alternate_file_name: [14]u16, -} - -Find_Data_A :: struct{ - file_attributes: u32, - creation_time: Filetime, - last_access_time: Filetime, - last_write_time: Filetime, - file_size_high: u32, - file_size_low: u32, - reserved0: u32, - reserved1: u32, - file_name: [MAX_PATH]byte, - alternate_file_name: [14]byte, -} - -Security_Attributes :: struct { - length: u32, - security_descriptor: rawptr, - inherit_handle: Bool, -} - -Process_Information :: struct { - process: Handle, - thread: Handle, - process_id: u32, - thread_id: u32, -} - -Startup_Info :: struct { - cb: u32, - reserved: Wstring, - desktop: Wstring, - title: Wstring, - x: u32, - y: u32, - x_size: u32, - y_size: u32, - x_count_chars: u32, - y_count_chars: u32, - fill_attribute: u32, - flags: u32, - show_window: u16, - _: u16, - _: cstring, - stdin: Handle, - stdout: Handle, - stderr: Handle, -} - -Pixel_Format_Descriptor :: struct { - size, - version, - flags: u32, - - pixel_type, - color_bits, - red_bits, - red_shift, - green_bits, - green_shift, - blue_bits, - blue_shift, - alpha_bits, - alpha_shift, - accum_bits, - accum_red_bits, - accum_green_bits, - accum_blue_bits, - accum_alpha_bits, - depth_bits, - stencil_bits, - aux_buffers, - layer_type, - reserved: byte, - - layer_mask, - visible_mask, - damage_mask: u32, -} - -Critical_Section :: struct { - debug_info: ^Critical_Section_Debug, - - lock_count: i32, - recursion_count: i32, - owning_thread: Handle, - lock_semaphore: Handle, - spin_count: ^u32, -} - -Critical_Section_Debug :: struct { - typ: u16, - creator_back_trace_index: u16, - critical_section: ^Critical_Section, - process_locks_list: ^List_Entry, - entry_count: u32, - contention_count: u32, - flags: u32, - creator_back_trace_index_high: u16, - spare_word: u16, -} - -List_Entry :: struct {flink, blink: ^List_Entry} - - -Raw_Input_Device :: struct { - usage_page: u16, - usage: u16, - flags: u32, - wnd_target: Hwnd, -} - -Raw_Input_Header :: struct { - kind: u32, - size: u32, - device: Handle, - wparam: Wparam, -} - -Raw_HID :: struct { - size_hid: u32, - count: u32, - raw_data: [1]byte, -} - -Raw_Keyboard :: struct { - make_code: u16, - flags: u16, - reserved: u16, - vkey: u16, - message: u32, - extra_information: u32, -} - -Raw_Mouse :: struct { - flags: u16, - using data: struct #raw_union { - buttons: u32, - using _: struct { - button_flags: u16, - button_data: u16, - }, - }, - raw_buttons: u32, - last_x: i32, - last_y: i32, - extra_information: u32, -} - -Raw_Input :: struct { - using header: Raw_Input_Header, - data: struct #raw_union { - mouse: Raw_Mouse, - keyboard: Raw_Keyboard, - hid: Raw_HID, - }, -} - - -Overlapped :: struct { - internal: ^u64, - internal_high: ^u64, - using _: struct #raw_union { - using _: struct { - offset: u32, - offset_high: u32, - }, - pointer: rawptr, - }, - event: Handle, -} - -File_Notify_Information :: struct { - next_entry_offset: u32, - action: u32, - file_name_length: u32, - file_name: [1]u16, -} - -// https://docs.microsoft.com/en-gb/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info -System_Info :: struct { - using _: struct #raw_union { - oem_id: u32, - using _: struct #raw_union { - processor_architecture: u16, - _: u16, // reserved - }, - }, - page_size: u32, - minimum_application_address: rawptr, - maximum_application_address: rawptr, - active_processor_mask: u32, - number_of_processors: u32, - processor_type: u32, - allocation_granularity: u32, - processor_level: u16, - processor_revision: u16, -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_osversioninfoexa -OS_Version_Info_Ex_A :: struct { - os_version_info_size: u32, - major_version: u32, - minor_version: u32, - build_number: u32, - platform_id : u32, - service_pack_string: [128]u8, - service_pack_major: u16, - service_pack_minor: u16, - suite_mask: u16, - product_type: u8, - reserved: u8, -} - -MAPVK_VK_TO_VSC :: 0 -MAPVK_VSC_TO_VK :: 1 -MAPVK_VK_TO_CHAR :: 2 -MAPVK_VSC_TO_VK_EX :: 3 - -//WinUser.h -ENUM_CURRENT_SETTINGS :: u32(4294967295) // (DWORD)-1 -ENUM_REGISTRY_SETTINGS :: u32(4294967294) // (DWORD)-2 - -VK_LBUTTON :: 0x01 -VK_RBUTTON :: 0x02 -VK_CANCEL :: 0x03 -VK_MBUTTON :: 0x04 /* NOT contiguous with L & RBUTTON */ -VK_XBUTTON1 :: 0x05 /* NOT contiguous with L & RBUTTON */ -VK_XBUTTON2 :: 0x06 /* NOT contiguous with L & RBUTTON */ - -/* - * :: 0x07 : reserved - */ - -VK_BACK :: 0x08 -VK_TAB :: 0x09 - -/* - * :: 0x0A - :: 0x0B : reserved - */ - -VK_CLEAR :: 0x0C -VK_RETURN :: 0x0D - -/* - * :: 0x0E - :: 0x0F : unassigned - */ - -VK_SHIFT :: 0x10 -VK_CONTROL :: 0x11 -VK_MENU :: 0x12 -VK_PAUSE :: 0x13 -VK_CAPITAL :: 0x14 - -VK_KANA :: 0x15 -VK_HANGEUL :: 0x15 /* old name - should be here for compatibility */ -VK_HANGUL :: 0x15 - -/* - * :: 0x16 : unassigned - */ - -VK_JUNJA :: 0x17 -VK_FINAL :: 0x18 -VK_HANJA :: 0x19 -VK_KANJI :: 0x19 - -/* - * :: 0x1A : unassigned - */ - -VK_ESCAPE :: 0x1B - -VK_CONVERT :: 0x1C -VK_NONCONVERT :: 0x1D -VK_ACCEPT :: 0x1E -VK_MODECHANGE :: 0x1F - -VK_SPACE :: 0x20 -VK_PRIOR :: 0x21 -VK_NEXT :: 0x22 -VK_END :: 0x23 -VK_HOME :: 0x24 -VK_LEFT :: 0x25 -VK_UP :: 0x26 -VK_RIGHT :: 0x27 -VK_DOWN :: 0x28 -VK_SELECT :: 0x29 -VK_PRINT :: 0x2A -VK_EXECUTE :: 0x2B -VK_SNAPSHOT :: 0x2C -VK_INSERT :: 0x2D -VK_DELETE :: 0x2E -VK_HELP :: 0x2F - -/* - * VK_0 - VK_9 are the same as ASCII '0' - '9' (:: 0x30 - :: 0x39) - * :: 0x3A - :: 0x40 : unassigned - * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (:: 0x41 - :: 0x5A) - */ - -VK_LWIN :: 0x5B -VK_RWIN :: 0x5C -VK_APPS :: 0x5D - -/* - * :: 0x5E : reserved - */ - -VK_SLEEP :: 0x5F - -VK_NUMPAD0 :: 0x60 -VK_NUMPAD1 :: 0x61 -VK_NUMPAD2 :: 0x62 -VK_NUMPAD3 :: 0x63 -VK_NUMPAD4 :: 0x64 -VK_NUMPAD5 :: 0x65 -VK_NUMPAD6 :: 0x66 -VK_NUMPAD7 :: 0x67 -VK_NUMPAD8 :: 0x68 -VK_NUMPAD9 :: 0x69 -VK_MULTIPLY :: 0x6A -VK_ADD :: 0x6B -VK_SEPARATOR :: 0x6C -VK_SUBTRACT :: 0x6D -VK_DECIMAL :: 0x6E -VK_DIVIDE :: 0x6F -VK_F1 :: 0x70 -VK_F2 :: 0x71 -VK_F3 :: 0x72 -VK_F4 :: 0x73 -VK_F5 :: 0x74 -VK_F6 :: 0x75 -VK_F7 :: 0x76 -VK_F8 :: 0x77 -VK_F9 :: 0x78 -VK_F10 :: 0x79 -VK_F11 :: 0x7A -VK_F12 :: 0x7B -VK_F13 :: 0x7C -VK_F14 :: 0x7D -VK_F15 :: 0x7E -VK_F16 :: 0x7F -VK_F17 :: 0x80 -VK_F18 :: 0x81 -VK_F19 :: 0x82 -VK_F20 :: 0x83 -VK_F21 :: 0x84 -VK_F22 :: 0x85 -VK_F23 :: 0x86 -VK_F24 :: 0x87 - -INVALID_HANDLE :: Handle(~uintptr(0)) - -CREATE_SUSPENDED :: 0x00000004 -STACK_SIZE_PARAM_IS_A_RESERVATION :: 0x00010000 -WAIT_ABANDONED :: 0x00000080 -WAIT_OBJECT_0 :: 0 -WAIT_TIMEOUT :: 0x00000102 -WAIT_FAILED :: 0xffffffff - -CS_VREDRAW :: 0x0001 -CS_HREDRAW :: 0x0002 -CS_OWNDC :: 0x0020 -CW_USEDEFAULT :: -0x80000000 - -WS_OVERLAPPED :: 0 -WS_MAXIMIZEBOX :: 0x00010000 -WS_MINIMIZEBOX :: 0x00020000 -WS_THICKFRAME :: 0x00040000 -WS_SYSMENU :: 0x00080000 -WS_BORDER :: 0x00800000 -WS_CAPTION :: 0x00C00000 -WS_VISIBLE :: 0x10000000 -WS_POPUP :: 0x80000000 -WS_MAXIMIZE :: 0x01000000 -WS_MINIMIZE :: 0x20000000 -WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX -WS_POPUPWINDOW :: WS_POPUP | WS_BORDER | WS_SYSMENU - -WS_EX_DLGMODALFRAME :: 0x00000001 -WS_EX_NOPARENTNOTIFY :: 0x00000004 -WS_EX_TOPMOST :: 0x00000008 -WS_EX_ACCEPTFILES :: 0x00000010 -WS_EX_TRANSPARENT :: 0x00000020 -WS_EX_MDICHILD :: 0x00000040 -WS_EX_TOOLWINDOW :: 0x00000080 -WS_EX_WINDOWEDGE :: 0x00000100 -WS_EX_CLIENTEDGE :: 0x00000200 -WS_EX_CONTEXTHELP :: 0x00000400 -WS_EX_RIGHT :: 0x00001000 -WS_EX_LEFT :: 0x00000000 -WS_EX_RTLREADING :: 0x00002000 -WS_EX_LTRREADING :: 0x00000000 -WS_EX_LEFTSCROLLBAR :: 0x00004000 -WS_EX_RIGHTSCROLLBAR :: 0x00000000 -WS_EX_CONTROLPARENT :: 0x00010000 -WS_EX_STATICEDGE :: 0x00020000 -WS_EX_APPWINDOW :: 0x00040000 -WS_EX_OVERLAPPEDWINDOW :: WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE -WS_EX_PALETTEWINDOW :: WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST -WS_EX_LAYERED :: 0x00080000 -WS_EX_NOINHERITLAYOUT :: 0x00100000 // Disable inheritence of mirroring by children -WS_EX_NOREDIRECTIONBITMAP :: 0x00200000 -WS_EX_LAYOUTRTL :: 0x00400000 // Right to left mirroring -WS_EX_COMPOSITED :: 0x02000000 -WS_EX_NOACTIVATE :: 0x08000000 - -WM_ACTIVATE :: 0x0006 -WM_ACTIVATEAPP :: 0x001C -WM_CHAR :: 0x0102 -WM_CLOSE :: 0x0010 -WM_CREATE :: 0x0001 -WM_DESTROY :: 0x0002 -WM_INPUT :: 0x00FF -WM_KEYDOWN :: 0x0100 -WM_KEYUP :: 0x0101 -WM_KILLFOCUS :: 0x0008 -WM_QUIT :: 0x0012 -WM_SETCURSOR :: 0x0020 -WM_SETFOCUS :: 0x0007 -WM_SIZE :: 0x0005 -WM_SIZING :: 0x0214 -WM_SYSKEYDOWN :: 0x0104 -WM_SYSKEYUP :: 0x0105 -WM_USER :: 0x0400 -WM_WINDOWPOSCHANGED :: 0x0047 -WM_COMMAND :: 0x0111 -WM_PAINT :: 0x000F - -WM_MOUSEWHEEL :: 0x020A -WM_MOUSEMOVE :: 0x0200 -WM_LBUTTONDOWN :: 0x0201 -WM_LBUTTONUP :: 0x0202 -WM_LBUTTONDBLCLK :: 0x0203 -WM_RBUTTONDOWN :: 0x0204 -WM_RBUTTONUP :: 0x0205 -WM_RBUTTONDBLCLK :: 0x0206 -WM_MBUTTONDOWN :: 0x0207 -WM_MBUTTONUP :: 0x0208 -WM_MBUTTONDBLCLK :: 0x0209 - -PM_NOREMOVE :: 0x0000 -PM_REMOVE :: 0x0001 -PM_NOYIELD :: 0x0002 - -BLACK_BRUSH :: 4 - -SM_CXSCREEN :: 0 -SM_CYSCREEN :: 1 - -SW_SHOW :: 5 - -COLOR_BACKGROUND :: Hbrush(uintptr(1)) - -INVALID_SET_FILE_POINTER :: ~u32(0) -HEAP_ZERO_MEMORY :: 0x00000008 -INFINITE :: 0xffffffff -GWL_EXSTYLE :: -20 -GWLP_HINSTANCE :: -6 -GWLP_ID :: -12 -GWL_STYLE :: -16 -GWLP_USERDATA :: -21 -GWLP_WNDPROC :: -4 -Hwnd_TOP :: Hwnd(uintptr(0)) - -BI_RGB :: 0 -DIB_RGB_COLORS :: 0x00 -SRCCOPY: u32 : 0x00cc0020 - - -MONITOR_DEFAULTTONULL :: 0x00000000 -MONITOR_DEFAULTTOPRIMARY :: 0x00000001 -MONITOR_DEFAULTTONEAREST :: 0x00000002 - -SWP_FRAMECHANGED :: 0x0020 -SWP_NOOWNERZORDER :: 0x0200 -SWP_NOZORDER :: 0x0004 -SWP_NOSIZE :: 0x0001 -SWP_NOMOVE :: 0x0002 - - -// Raw Input - - -RID_HEADER :: 0x10000005 -RID_INPUT :: 0x10000003 - - -RIDEV_APPKEYS :: 0x00000400 -RIDEV_CAPTUREMOUSE :: 0x00000200 -RIDEV_DEVNOTIFY :: 0x00002000 -RIDEV_EXCLUDE :: 0x00000010 -RIDEV_EXINPUTSINK :: 0x00001000 -RIDEV_INPUTSINK :: 0x00000100 -RIDEV_NOHOTKEYS :: 0x00000200 -RIDEV_NOLEGACY :: 0x00000030 -RIDEV_PAGEONLY :: 0x00000020 -RIDEV_REMOVE :: 0x00000001 - - -RIM_TYPEMOUSE :: 0 -RIM_TYPEKEYBOARD :: 1 -RIM_TYPEHID :: 2 - - -MOUSE_ATTRIBUTES_CHANGED :: 0x04 -MOUSE_MOVE_RELATIVE :: 0 -MOUSE_MOVE_ABSOLUTE :: 1 -MOUSE_VIRTUAL_DESKTOP :: 0x02 - - - -RI_MOUSE_BUTTON_1_DOWN :: 0x0001 -RI_MOUSE_BUTTON_1_UP :: 0x0002 -RI_MOUSE_BUTTON_2_DOWN :: 0x0004 -RI_MOUSE_BUTTON_2_UP :: 0x0008 -RI_MOUSE_BUTTON_3_DOWN :: 0x0010 -RI_MOUSE_BUTTON_3_UP :: 0x0020 -RI_MOUSE_BUTTON_4_DOWN :: 0x0040 -RI_MOUSE_BUTTON_4_UP :: 0x0080 -RI_MOUSE_BUTTON_5_DOWN :: 0x0100 -RI_MOUSE_BUTTON_5_UP :: 0x0200 -RI_MOUSE_LEFT_BUTTON_DOWN :: 0x0001 -RI_MOUSE_LEFT_BUTTON_UP :: 0x0002 -RI_MOUSE_MIDDLE_BUTTON_DOWN :: 0x0010 -RI_MOUSE_MIDDLE_BUTTON_UP :: 0x0020 -RI_MOUSE_RIGHT_BUTTON_DOWN :: 0x0004 -RI_MOUSE_RIGHT_BUTTON_UP :: 0x0008 -RI_MOUSE_WHEEL :: 0x0400 - - -RI_KEY_MAKE :: 0x00 -RI_KEY_BREAK :: 0x01 -RI_KEY_E0 :: 0x02 -RI_KEY_E1 :: 0x04 -RI_KEY_TERMSRV_SET_LED :: 0x08 -RI_KEY_TERMSRV_SHADOW :: 0x10 - -// Windows OpenGL - -PFD_TYPE_RGBA :: 0 -PFD_TYPE_COLORINDEX :: 1 -PFD_MAIN_PLANE :: 0 -PFD_OVERLAY_PLANE :: 1 -PFD_UNDERLAY_PLANE :: -1 -PFD_DOUBLEBUFFER :: 1 -PFD_STEREO :: 2 -PFD_DRAW_TO_WINDOW :: 4 -PFD_DRAW_TO_BITMAP :: 8 -PFD_SUPPORT_GDI :: 16 -PFD_SUPPORT_OPENGL :: 32 -PFD_GENERIC_FORMAT :: 64 -PFD_NEED_PALETTE :: 128 -PFD_NEED_SYSTEM_PALETTE :: 0x00000100 -PFD_SWAP_EXCHANGE :: 0x00000200 -PFD_SWAP_COPY :: 0x00000400 -PFD_SWAP_LAYER_BUFFERS :: 0x00000800 -PFD_GENERIC_ACCELERATED :: 0x00001000 -PFD_DEPTH_DONTCARE :: 0x20000000 -PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000 -PFD_STEREO_DONTCARE :: 0x80000000 - -GET_FILEEX_INFO_LEVELS :: distinct i32 -GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0 -GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1 - -STARTF_USESHOWWINDOW :: 0x00000001 -STARTF_USESIZE :: 0x00000002 -STARTF_USEPOSITION :: 0x00000004 -STARTF_USECOUNTCHARS :: 0x00000008 -STARTF_USEFILLATTRIBUTE :: 0x00000010 -STARTF_RUNFULLSCREEN :: 0x00000020 // ignored for non-x86 platforms -STARTF_FORCEONFEEDBACK :: 0x00000040 -STARTF_FORCEOFFFEEDBACK :: 0x00000080 -STARTF_USESTDHANDLES :: 0x00000100 -STARTF_USEHOTKEY :: 0x00000200 -STARTF_TITLEISLINKNAME :: 0x00000800 -STARTF_TITLEISAPPID :: 0x00001000 -STARTF_PREVENTPINNING :: 0x00002000 -STARTF_UNTRUSTEDSOURCE :: 0x00008000 - - -MOVEFILE_REPLACE_EXISTING :: 0x00000001 -MOVEFILE_COPY_ALLOWED :: 0x00000002 -MOVEFILE_DELAY_UNTIL_REBOOT :: 0x00000004 -MOVEFILE_WRITE_THROUGH :: 0x00000008 -MOVEFILE_CREATE_HARDLINK :: 0x00000010 -MOVEFILE_FAIL_IF_NOT_TRACKABLE :: 0x00000020 - -FILE_NOTIFY_CHANGE_FILE_NAME :: 0x00000001 -FILE_NOTIFY_CHANGE_DIR_NAME :: 0x00000002 -FILE_NOTIFY_CHANGE_ATTRIBUTES :: 0x00000004 -FILE_NOTIFY_CHANGE_SIZE :: 0x00000008 -FILE_NOTIFY_CHANGE_LAST_WRITE :: 0x00000010 -FILE_NOTIFY_CHANGE_LAST_ACCESS :: 0x00000020 -FILE_NOTIFY_CHANGE_CREATION :: 0x00000040 -FILE_NOTIFY_CHANGE_SECURITY :: 0x00000100 - -FILE_FLAG_WRITE_THROUGH :: 0x80000000 -FILE_FLAG_OVERLAPPED :: 0x40000000 -FILE_FLAG_NO_BUFFERING :: 0x20000000 -FILE_FLAG_RANDOM_ACCESS :: 0x10000000 -FILE_FLAG_SEQUENTIAL_SCAN :: 0x08000000 -FILE_FLAG_DELETE_ON_CLOSE :: 0x04000000 -FILE_FLAG_BACKUP_SEMANTICS :: 0x02000000 -FILE_FLAG_POSIX_SEMANTICS :: 0x01000000 -FILE_FLAG_SESSION_AWARE :: 0x00800000 -FILE_FLAG_OPEN_REPARSE_POINT :: 0x00200000 -FILE_FLAG_OPEN_NO_RECALL :: 0x00100000 -FILE_FLAG_FIRST_PIPE_INSTANCE :: 0x00080000 - -FILE_ACTION_ADDED :: 0x00000001 -FILE_ACTION_REMOVED :: 0x00000002 -FILE_ACTION_MODIFIED :: 0x00000003 -FILE_ACTION_RENAMED_OLD_NAME :: 0x00000004 -FILE_ACTION_RENAMED_NEW_NAME :: 0x00000005 - -CP_ACP :: 0 // default to ANSI code page -CP_OEMCP :: 1 // default to OEM code page -CP_MACCP :: 2 // default to MAC code page -CP_THREAD_ACP :: 3 // current thread's ANSI code page -CP_SYMBOL :: 42 // SYMBOL translations -CP_UTF7 :: 65000 // UTF-7 translation -CP_UTF8 :: 65001 // UTF-8 translation - - -MB_ERR_INVALID_CHARS :: 8 -WC_ERR_INVALID_CHARS :: 128 - -utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 { - if len(s) < 1 { - return nil - } - - b := transmute([]byte)s - cstr := cstring(&b[0]) - n := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), nil, 0) - if n == 0 { - return nil - } - - text := make([]u16, n+1, allocator) - - n1 := multi_byte_to_wide_char(CP_UTF8, MB_ERR_INVALID_CHARS, cstr, i32(len(s)), Wstring(&text[0]), i32(n)) - if n1 == 0 { - delete(text, allocator) - return nil - } - - text[n] = 0 - for n >= 1 && text[n-1] == 0 { - n -= 1 - } - return text[:n] -} -utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> Wstring { - if res := utf8_to_utf16(s, allocator); res != nil { - return Wstring(&res[0]) - } - return nil -} - -wstring_to_utf8 :: proc(s: Wstring, N: int, allocator := context.temp_allocator) -> (str: string, err: runtime.Allocator_Error) { - if N == 0 { - return - } - - n := wide_char_to_multi_byte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil) - if n == 0 { - return - } - - // If N == -1 the call to wide_char_to_multi_byte assume the wide string is null terminated - // and will scan it to find the first null terminated character. The resulting string will - // also null terminated. - // If N != -1 it assumes the wide string is not null terminated and the resulting string - // will not be null terminated, we therefore have to force it to be null terminated manually. - text := make([]byte, n+1 if N != -1 else n, allocator) or_return - - if n1 := wide_char_to_multi_byte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), cstring(&text[0]), n, nil, nil); n1 == 0 { - delete(text, allocator) - return "", nil - } - - for i in 0.. (string, runtime.Allocator_Error) { - if len(s) == 0 { - return "", nil - } - return wstring_to_utf8(cast(Wstring)&s[0], len(s), allocator) -} - -get_query_performance_frequency :: proc() -> i64 { - r: i64 - query_performance_frequency(&r) - return r -} - -HIWORD_W :: proc(wParam: Wparam) -> u16 { return u16((u32(wParam) >> 16) & 0xffff) } -HIWORD_L :: proc(lParam: Lparam) -> u16 { return u16((u32(lParam) >> 16) & 0xffff) } -LOWORD_W :: proc(wParam: Wparam) -> u16 { return u16(wParam) } -LOWORD_L :: proc(lParam: Lparam) -> u16 { return u16(lParam) } - -is_key_down :: #force_inline proc(key: Key_Code) -> bool { return get_async_key_state(i32(key)) < 0 } - - - - -MAX_PATH :: 0x00000104 -MAX_PATH_WIDE :: 0x8000 - -HANDLE_FLAG_INHERIT :: 1 -HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2 - -FILE_BEGIN :: 0 -FILE_CURRENT :: 1 -FILE_END :: 2 - -FILE_SHARE_READ :: 0x00000001 -FILE_SHARE_WRITE :: 0x00000002 -FILE_SHARE_DELETE :: 0x00000004 -FILE_GENERIC_ALL :: 0x10000000 -FILE_GENERIC_EXECUTE :: 0x20000000 -FILE_GENERIC_WRITE :: 0x40000000 -FILE_GENERIC_READ :: 0x80000000 - -FILE_READ_DATA :: 0x0001 -FILE_LIST_DIRECTORY :: 0x0001 -FILE_WRITE_DATA :: 0x0002 -FILE_ADD_FILE :: 0x0002 -FILE_APPEND_DATA :: 0x0004 -FILE_ADD_SUBDIRECTORY :: 0x0004 -FILE_CREATE_PIPE_INSTANCE :: 0x0004 -FILE_READ_EA :: 0x0008 -FILE_WRITE_EA :: 0x0010 -FILE_EXECUTE :: 0x0020 -FILE_TRAVERSE :: 0x0020 -FILE_DELETE_CHILD :: 0x0040 -FILE_READ_ATTRIBUTES :: 0x0080 -FILE_WRITE_ATTRIBUTES :: 0x0100 - -STD_INPUT_HANDLE :: -10 -STD_OUTPUT_HANDLE :: -11 -STD_ERROR_HANDLE :: -12 - -CREATE_NEW :: 1 -CREATE_ALWAYS :: 2 -OPEN_EXISTING :: 3 -OPEN_ALWAYS :: 4 -TRUNCATE_EXISTING :: 5 - -INVALID_FILE_ATTRIBUTES :: -1 - -FILE_ATTRIBUTE_READONLY :: 0x00000001 -FILE_ATTRIBUTE_HIDDEN :: 0x00000002 -FILE_ATTRIBUTE_SYSTEM :: 0x00000004 -FILE_ATTRIBUTE_DIRECTORY :: 0x00000010 -FILE_ATTRIBUTE_ARCHIVE :: 0x00000020 -FILE_ATTRIBUTE_DEVICE :: 0x00000040 -FILE_ATTRIBUTE_NORMAL :: 0x00000080 -FILE_ATTRIBUTE_TEMPORARY :: 0x00000100 -FILE_ATTRIBUTE_SPARSE_FILE :: 0x00000200 -FILE_ATTRIBUTE_REPARSE_Point :: 0x00000400 -FILE_ATTRIBUTE_COMPRESSED :: 0x00000800 -FILE_ATTRIBUTE_OFFLINE :: 0x00001000 -FILE_ATTRIBUTE_NOT_CONTENT_INDEXED :: 0x00002000 -FILE_ATTRIBUTE_ENCRYPTED :: 0x00004000 - -FILE_TYPE_DISK :: 0x0001 -FILE_TYPE_CHAR :: 0x0002 -FILE_TYPE_PIPE :: 0x0003 - - -Monitor_Info :: struct { - size: u32, - monitor: Rect, - work: Rect, - flags: u32, -} - -Window_Placement :: struct { - length: u32, - flags: u32, - show_cmd: u32, - min_pos: Point, - max_pos: Point, - normal_pos: Rect, -} - -Bitmap_Info_Header :: struct { - size: u32, - width, height: i32, - planes, bit_count: i16, - compression: u32, - size_image: u32, - x_pels_per_meter: i32, - y_pels_per_meter: i32, - clr_used: u32, - clr_important: u32, -} -Bitmap_Info :: struct { - using header: Bitmap_Info_Header, - colors: [1]Rgb_Quad, -} - -Paint_Struct :: struct { - hdc: Hdc, - erase: Bool, - rc_paint: Rect, - restore: Bool, - inc_update: Bool, - rgb_reserved: [32]byte, -} - - -Rgb_Quad :: struct {blue, green, red, reserved: byte} - - -Key_Code :: enum i32 { - Unknown = 0x00, - - Lbutton = 0x01, - Rbutton = 0x02, - Cancel = 0x03, - Mbutton = 0x04, - Xbutton1 = 0x05, - Xbutton2 = 0x06, - Back = 0x08, - Tab = 0x09, - Clear = 0x0C, - Return = 0x0D, - - Shift = 0x10, - Control = 0x11, - Menu = 0x12, - Pause = 0x13, - Capital = 0x14, - Kana = 0x15, - Hangeul = 0x15, - Hangul = 0x15, - Junja = 0x17, - Final = 0x18, - Hanja = 0x19, - Kanji = 0x19, - Escape = 0x1B, - Convert = 0x1C, - NonConvert = 0x1D, - Accept = 0x1E, - ModeChange = 0x1F, - Space = 0x20, - Prior = 0x21, - Next = 0x22, - End = 0x23, - Home = 0x24, - Left = 0x25, - Up = 0x26, - Right = 0x27, - Down = 0x28, - Select = 0x29, - Print = 0x2A, - Execute = 0x2B, - Snapshot = 0x2C, - Insert = 0x2D, - Delete = 0x2E, - Help = 0x2F, - - Num0 = '0', - Num1 = '1', - Num2 = '2', - Num3 = '3', - Num4 = '4', - Num5 = '5', - Num6 = '6', - Num7 = '7', - Num8 = '8', - Num9 = '9', - A = 'A', - B = 'B', - C = 'C', - D = 'D', - E = 'E', - F = 'F', - G = 'G', - H = 'H', - I = 'I', - J = 'J', - K = 'K', - L = 'L', - M = 'M', - N = 'N', - O = 'O', - P = 'P', - Q = 'Q', - R = 'R', - S = 'S', - T = 'T', - U = 'U', - V = 'V', - W = 'W', - X = 'X', - Y = 'Y', - Z = 'Z', - - Lwin = 0x5B, - Rwin = 0x5C, - Apps = 0x5D, - - Numpad0 = 0x60, - Numpad1 = 0x61, - Numpad2 = 0x62, - Numpad3 = 0x63, - Numpad4 = 0x64, - Numpad5 = 0x65, - Numpad6 = 0x66, - Numpad7 = 0x67, - Numpad8 = 0x68, - Numpad9 = 0x69, - Multiply = 0x6A, - Add = 0x6B, - Separator = 0x6C, - Subtract = 0x6D, - Decimal = 0x6E, - Divide = 0x6F, - - F1 = 0x70, - F2 = 0x71, - F3 = 0x72, - F4 = 0x73, - F5 = 0x74, - F6 = 0x75, - F7 = 0x76, - F8 = 0x77, - F9 = 0x78, - F10 = 0x79, - F11 = 0x7A, - F12 = 0x7B, - F13 = 0x7C, - F14 = 0x7D, - F15 = 0x7E, - F16 = 0x7F, - F17 = 0x80, - F18 = 0x81, - F19 = 0x82, - F20 = 0x83, - F21 = 0x84, - F22 = 0x85, - F23 = 0x86, - F24 = 0x87, - - Numlock = 0x90, - Scroll = 0x91, - Lshift = 0xA0, - Rshift = 0xA1, - Lcontrol = 0xA2, - Rcontrol = 0xA3, - Lmenu = 0xA4, - Rmenu = 0xA5, - ProcessKey = 0xE5, - Attn = 0xF6, - Crsel = 0xF7, - Exsel = 0xF8, - Ereof = 0xF9, - Play = 0xFA, - Zoom = 0xFB, - Noname = 0xFC, - Pa1 = 0xFD, - OemClear = 0xFE, -} - diff --git a/core/sys/win32/helpers.odin b/core/sys/win32/helpers.odin deleted file mode 100644 index b04e5db95..000000000 --- a/core/sys/win32/helpers.odin +++ /dev/null @@ -1,29 +0,0 @@ -// +build windows -package win32 - -import "core:strings" - -call_external_process :: proc(program, command_line: string) -> bool { - si := Startup_Info{ cb=size_of(Startup_Info) } - pi := Process_Information{} - - return cast(bool)create_process_w( - utf8_to_wstring(program), - utf8_to_wstring(command_line), - nil, - nil, - Bool(false), - u32(0x10), - nil, - nil, - &si, - &pi, - ) -} - -open_website :: proc(url: string) -> bool { - p :: "C:\\Windows\\System32\\cmd.exe" - arg := []string{"/C", "start", url} - args := strings.join(arg, " ", context.temp_allocator) - return call_external_process(p, args) -} diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin deleted file mode 100644 index ca6122690..000000000 --- a/core/sys/win32/kernel32.odin +++ /dev/null @@ -1,237 +0,0 @@ -// +build windows -package win32 - -foreign import "system:kernel32.lib" - -@(default_calling_convention = "std") -foreign kernel32 { - @(link_name="CreateProcessA") create_process_a :: proc(application_name, command_line: cstring, - process_attributes, thread_attributes: ^Security_Attributes, - inherit_handle: Bool, creation_flags: u32, environment: rawptr, - current_directory: cstring, startup_info: ^Startup_Info, - process_information: ^Process_Information) -> Bool --- - @(link_name="CreateProcessW") create_process_w :: proc(application_name, command_line: Wstring, - process_attributes, thread_attributes: ^Security_Attributes, - inherit_handle: Bool, creation_flags: u32, environment: rawptr, - current_directory: Wstring, startup_info: ^Startup_Info, - process_information: ^Process_Information) -> Bool --- - @(link_name="GetExitCodeProcess") get_exit_code_process :: proc(process: Handle, exit: ^u32) -> Bool --- - @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) --- - @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: cstring) -> Hmodule --- - @(link_name="GetModuleHandleW") get_module_handle_w :: proc(module_name: Wstring) -> Hmodule --- - - @(link_name="GetModuleFileNameA") get_module_file_name_a :: proc(module: Hmodule, filename: cstring, size: u32) -> u32 --- - @(link_name="GetModuleFileNameW") get_module_file_name_w :: proc(module: Hmodule, filename: Wstring, size: u32) -> u32 --- - - @(link_name="Sleep") sleep :: proc(ms: u32) --- - @(link_name="QueryPerformanceFrequency") query_performance_frequency :: proc(result: ^i64) -> i32 --- - @(link_name="QueryPerformanceCounter") query_performance_counter :: proc(result: ^i64) -> i32 --- - @(link_name="OutputDebugStringA") output_debug_string_a :: proc(c_str: cstring) --- - - @(link_name="GetCommandLineA") get_command_line_a :: proc() -> cstring --- - @(link_name="GetCommandLineW") get_command_line_w :: proc() -> Wstring --- - @(link_name="GetSystemMetrics") get_system_metrics :: proc(index: i32) -> i32 --- - @(link_name="GetSystemInfo") get_system_info :: proc(info: ^System_Info) --- - @(link_name="GetVersionExA") get_version :: proc(osvi: ^OS_Version_Info_Ex_A) --- - @(link_name="GetCurrentThreadId") get_current_thread_id :: proc() -> u32 --- - - // NOTE(tetra): Not thread safe with SetCurrentDirectory and GetFullPathName; - // The current directory is stored as a global variable in the process. - @(link_name="GetCurrentDirectoryW") get_current_directory_w :: proc(len: u32, buf: Wstring) -> u32 --- - @(link_name="SetCurrentDirectoryW") set_current_directory_w :: proc(buf: Wstring) -> u32 --- - - @(link_name="GetSystemTimeAsFileTime") get_system_time_as_file_time :: proc(system_time_as_file_time: ^Filetime) --- - @(link_name="FileTimeToLocalFileTime") file_time_to_local_file_time :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool --- - @(link_name="FileTimeToSystemTime") file_time_to_system_time :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool --- - @(link_name="SystemTimeToFileTime") system_time_to_file_time :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool --- - - @(link_name="GetStdHandle") get_std_handle :: proc(h: i32) -> Handle --- - - @(link_name="CreateFileA") - create_file_a :: proc(filename: cstring, desired_access, share_module: u32, - security: rawptr, - creation, flags_and_attribs: u32, template_file: Handle) -> Handle --- - - @(link_name="CreateFileW") - create_file_w :: proc(filename: Wstring, desired_access, share_module: u32, - security: rawptr, - creation, flags_and_attribs: u32, template_file: Handle) -> Handle --- - - - @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool --- - @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool --- - - @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool --- - @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool --- - - @(link_name="CreateDirectoryA") create_directory_a :: proc(path: cstring, security_attributes: ^Security_Attributes) -> Bool --- - @(link_name="CreateDirectoryW") create_directory_w :: proc(path: Wstring, security_attributes: ^Security_Attributes) -> Bool --- - - @(link_name="GetFileType") get_file_type :: proc(file_handle: Handle) -> u32 --- - @(link_name="SetFilePointer") set_file_pointer :: proc(file_handle: Handle, distance_to_move: i32, distance_to_move_high: ^i32, move_method: u32) -> u32 --- - - @(link_name="SetHandleInformation") set_handle_information :: proc(obj: Handle, mask, flags: u32) -> Bool --- - - @(link_name="FindFirstFileA") find_first_file_a :: proc(file_name: cstring, data: ^Find_Data_A) -> Handle --- - @(link_name="FindNextFileA") find_next_file_a :: proc(file: Handle, data: ^Find_Data_A) -> Bool --- - - @(link_name="FindFirstFileW") find_first_file_w :: proc(file_name: Wstring, data: ^Find_Data_W) -> Handle --- - @(link_name="FindNextFileW") find_next_file_w :: proc(file: Handle, data: ^Find_Data_W) -> Bool --- - - @(link_name="FindClose") find_close :: proc(file: Handle) -> Bool --- - - @(link_name="MoveFileExA") move_file_ex_a :: proc(existing, new: cstring, flags: u32) -> Bool --- - @(link_name="DeleteFileA") delete_file_a :: proc(file_name: cstring) -> Bool --- - @(link_name="CopyFileA") copy_file_a :: proc(existing, new: cstring, fail_if_exists: Bool) -> Bool --- - - @(link_name="MoveFileExW") move_file_ex_w :: proc(existing, new: Wstring, flags: u32) -> Bool --- - @(link_name="DeleteFileW") delete_file_w :: proc(file_name: Wstring) -> Bool --- - @(link_name="CopyFileW") copy_file_w :: proc(existing, new: Wstring, fail_if_exists: Bool) -> Bool --- - - @(link_name="HeapAlloc") heap_alloc :: proc(h: Handle, flags: u32, bytes: int) -> rawptr --- - @(link_name="HeapReAlloc") heap_realloc :: proc(h: Handle, flags: u32, memory: rawptr, bytes: int) -> rawptr --- - @(link_name="HeapFree") heap_free :: proc(h: Handle, flags: u32, memory: rawptr) -> Bool --- - @(link_name="GetProcessHeap") get_process_heap :: proc() -> Handle --- - - @(link_name="LocalAlloc") local_alloc :: proc(flags: u32, bytes: int) -> rawptr --- - @(link_name="LocalReAlloc") local_realloc :: proc(mem: rawptr, bytes: int, flags: uint) -> rawptr --- - @(link_name="LocalFree") local_free :: proc(mem: rawptr) -> rawptr --- - - @(link_name="FindFirstChangeNotificationA") find_first_change_notification_a :: proc(path: cstring, watch_subtree: Bool, filter: u32) -> Handle --- - @(link_name="FindNextChangeNotification") find_next_change_notification :: proc(h: Handle) -> Bool --- - @(link_name="FindCloseChangeNotification") find_close_change_notification :: proc(h: Handle) -> Bool --- - - @(link_name="ReadDirectoryChangesW") read_directory_changes_w :: proc(dir: Handle, buf: rawptr, buf_length: u32, - watch_subtree: Bool, notify_filter: u32, - bytes_returned: ^u32, overlapped: ^Overlapped, - completion: rawptr) -> Bool --- - - @(link_name="GetOverlappedResult") get_overlapped_result :: proc(file: Handle, overlapped: ^Overlapped, number_of_bytes_transferred: ^u32, wait: Bool) -> Bool --- - - @(link_name="WideCharToMultiByte") wide_char_to_multi_byte :: proc(code_page: u32, flags: u32, - wchar_str: Wstring, wchar: i32, - multi_str: cstring, multi: i32, - default_char: cstring, used_default_char: ^Bool) -> i32 --- - - @(link_name="MultiByteToWideChar") multi_byte_to_wide_char :: proc(code_page: u32, flags: u32, - mb_str: cstring, mb: i32, - wc_str: Wstring, wc: i32) -> i32 --- - - @(link_name="CreateSemaphoreA") create_semaphore_a :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: cstring) -> Handle --- - @(link_name="CreateSemaphoreW") create_semaphore_w :: proc(attributes: ^Security_Attributes, initial_count, maximum_count: i32, name: cstring) -> Handle --- - @(link_name="ReleaseSemaphore") release_semaphore :: proc(semaphore: Handle, release_count: i32, previous_count: ^i32) -> Bool --- - @(link_name="WaitForSingleObject") wait_for_single_object :: proc(handle: Handle, milliseconds: u32) -> u32 --- -} - -// @(default_calling_convention = "c") -foreign kernel32 { - @(link_name="GetLastError") get_last_error :: proc() -> i32 --- - @(link_name="CloseHandle") close_handle :: proc(h: Handle) -> i32 --- - - @(link_name="GetFileAttributesA") get_file_attributes_a :: proc(filename: cstring) -> u32 --- - @(link_name="GetFileAttributesW") get_file_attributes_w :: proc(filename: Wstring) -> u32 --- - @(link_name="GetFileAttributesExA") get_file_attributes_ex_a :: proc(filename: cstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: ^File_Attribute_Data) -> Bool --- - @(link_name="GetFileAttributesExW") get_file_attributes_ex_w :: proc(filename: Wstring, info_level_id: GET_FILEEX_INFO_LEVELS, file_info: ^File_Attribute_Data) -> Bool --- - @(link_name="CompareFileTime") compare_file_time :: proc(a, b: ^Filetime) -> i32 --- -} - -@(default_calling_convention = "c") -foreign kernel32 { - @(link_name="InterlockedCompareExchange") interlocked_compare_exchange :: proc(dst: ^i32, exchange, comparand: i32) -> i32 --- - @(link_name="InterlockedExchange") interlocked_exchange :: proc(dst: ^i32, desired: i32) -> i32 --- - @(link_name="InterlockedExchangeAdd") interlocked_exchange_add :: proc(dst: ^i32, desired: i32) -> i32 --- - @(link_name="InterlockedAnd") interlocked_and :: proc(dst: ^i32, desired: i32) -> i32 --- - @(link_name="InterlockedOr") interlocked_or :: proc(dst: ^i32, desired: i32) -> i32 --- - - @(link_name="InterlockedCompareExchange64") interlocked_compare_exchange64 :: proc(dst: ^i64, exchange, comparand: i64) -> i64 --- - @(link_name="InterlockedExchange64") interlocked_exchange64 :: proc(dst: ^i64, desired: i64) -> i64 --- - @(link_name="InterlockedExchangeAdd64") interlocked_exchange_add64 :: proc(dst: ^i64, desired: i64) -> i64 --- - @(link_name="InterlockedAnd64") interlocked_and64 :: proc(dst: ^i64, desired: i64) -> i64 --- - @(link_name="InterlockedOr64") interlocked_or64 :: proc(dst: ^i64, desired: i64) -> i64 --- -} - -@(default_calling_convention = "std") -foreign kernel32 { - @(link_name="_mm_pause") mm_pause :: proc() --- - @(link_name="ReadWriteBarrier") read_write_barrier :: proc() --- - @(link_name="WriteBarrier") write_barrier :: proc() --- - @(link_name="ReadBarrier") read_barrier :: proc() --- - - @(link_name="CreateThread") - create_thread :: proc(thread_attributes: ^Security_Attributes, stack_size: uint, start_routine: proc "stdcall" (rawptr) -> u32, - parameter: rawptr, creation_flags: u32, thread_id: ^u32) -> Handle --- - @(link_name="ResumeThread") resume_thread :: proc(thread: Handle) -> u32 --- - @(link_name="GetThreadPriority") get_thread_priority :: proc(thread: Handle) -> i32 --- - @(link_name="SetThreadPriority") set_thread_priority :: proc(thread: Handle, priority: i32) -> Bool --- - @(link_name="GetExitCodeThread") get_exit_code_thread :: proc(thread: Handle, exit_code: ^u32) -> Bool --- - @(link_name="TerminateThread") terminate_thread :: proc(thread: Handle, exit_code: u32) -> Bool --- - - @(link_name="InitializeCriticalSection") initialize_critical_section :: proc(critical_section: ^Critical_Section) --- - @(link_name="InitializeCriticalSectionAndSpinCount") initialize_critical_section_and_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> b32 --- - @(link_name="DeleteCriticalSection") delete_critical_section :: proc(critical_section: ^Critical_Section) --- - @(link_name="SetCriticalSectionSpinCount") set_critical_section_spin_count :: proc(critical_section: ^Critical_Section, spin_count: u32) -> u32 --- - @(link_name="TryEnterCriticalSection") try_enter_critical_section :: proc(critical_section: ^Critical_Section) -> b8 --- - @(link_name="EnterCriticalSection") enter_critical_section :: proc(critical_section: ^Critical_Section) --- - @(link_name="LeaveCriticalSection") leave_critical_section :: proc(critical_section: ^Critical_Section) --- - - @(link_name="CreateEventA") create_event_a :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: cstring) -> Handle --- - @(link_name="CreateEventW") create_event_w :: proc(event_attributes: ^Security_Attributes, manual_reset, initial_state: Bool, name: Wstring) -> Handle --- - @(link_name="PulseEvent") pulse_event :: proc(event: Handle) -> Bool --- - @(link_name="SetEvent") set_event :: proc(event: Handle) -> Bool --- - @(link_name="ResetEvent") reset_event :: proc(event: Handle) -> Bool --- - - @(link_name="LoadLibraryA") load_library_a :: proc(c_str: cstring) -> Hmodule --- - @(link_name="LoadLibraryW") load_library_w :: proc(c_str: Wstring) -> Hmodule --- - @(link_name="FreeLibrary") free_library :: proc(h: Hmodule) -> Bool --- - @(link_name="GetProcAddress") get_proc_address :: proc(h: Hmodule, c_str: cstring) -> rawptr --- - - @(link_name="GetFullPathNameA") get_full_path_name_a :: proc(filename: cstring, buffer_length: u32, buffer: cstring, file_part: ^Wstring) -> u32 --- - @(link_name="GetFullPathNameW") get_full_path_name_w :: proc(filename: Wstring, buffer_length: u32, buffer: Wstring, file_part: ^Wstring) -> u32 --- - @(link_name="GetLongPathNameA") get_long_path_name_a :: proc(short, long: cstring, len: u32) -> u32 --- - @(link_name="GetLongPathNameW") get_long_path_name_w :: proc(short, long: Wstring, len: u32) -> u32 --- - @(link_name="GetShortPathNameA") get_short_path_name_a :: proc(long, short: cstring, len: u32) -> u32 --- - @(link_name="GetShortPathNameW") get_short_path_name_w :: proc(long, short: Wstring, len: u32) -> u32 --- - - @(link_name="GetCurrentDirectoryA") get_current_directory_a :: proc(buffer_length: u32, buffer: cstring) -> u32 --- -} - -Memory_Basic_Information :: struct { - base_address: rawptr, - allocation_base: rawptr, - allocation_protect: u32, - region_size: uint, - state: u32, - protect: u32, - type: u32, -} - -@(default_calling_convention = "std") -foreign kernel32 { - @(link_name="VirtualAlloc") virtual_alloc :: proc(address: rawptr, size: uint, allocation_type: u32, protect: u32) -> rawptr --- - @(link_name="VirtualAllocEx") virtual_alloc_ex :: proc(process: Handle, address: rawptr, size: uint, allocation_type: u32, protect: u32) -> rawptr --- - @(link_name="VirtualFree") virtual_free :: proc(address: rawptr, size: uint, free_type: u32) -> Bool --- - @(link_name="VirtualLock") virtual_lock :: proc(address: rawptr, size: uint) -> Bool --- - @(link_name="VirtualProtect") virtual_protect :: proc(address: rawptr, size: uint, new_protect: u32, old_protect: ^u32) -> Bool --- - @(link_name="VirtualQuery") virtual_query :: proc(address: rawptr, buffer: ^Memory_Basic_Information, length: uint) -> uint --- -} - -MEM_COMMIT :: 0x00001000 -MEM_RESERVE :: 0x00002000 -MEM_DECOMMIT :: 0x00004000 -MEM_RELEASE :: 0x00008000 -MEM_RESET :: 0x00080000 -MEM_RESET_UNDO :: 0x01000000 - -MEM_LARGE_PAGES :: 0x20000000 -MEM_PHYSICAL :: 0x00400000 -MEM_TOP_DOWN :: 0x00100000 -MEM_WRITE_WATCH :: 0x00200000 - -PAGE_NOACCESS :: 0x01 -PAGE_READONLY :: 0x02 -PAGE_READWRITE :: 0x04 -PAGE_WRITECOPY :: 0x08 -PAGE_EXECUTE :: 0x10 -PAGE_EXECUTE_READ :: 0x20 -PAGE_EXECUTE_READWRITE :: 0x40 -PAGE_EXECUTE_WRITECOPY :: 0x80 \ No newline at end of file diff --git a/core/sys/win32/ole32.odin b/core/sys/win32/ole32.odin deleted file mode 100644 index f4ee52399..000000000 --- a/core/sys/win32/ole32.odin +++ /dev/null @@ -1,18 +0,0 @@ -// +build windows -package win32 - -foreign import "system:ole32.lib" - -//objbase.h -Com_Init :: enum { - Multi_Threaded = 0x0, - Apartment_Threaded = 0x2, - Disable_OLE1_DDE = 0x4, - Speed_Over_Memory = 0x8, -} - -@(default_calling_convention = "std") -foreign ole32 { - @(link_name ="CoInitializeEx") com_init_ex :: proc(reserved: rawptr, co_init: Com_Init) ->Hresult --- - @(link_name = "CoUninitialize") com_shutdown :: proc() --- -} diff --git a/core/sys/win32/removal.odin b/core/sys/win32/removal.odin new file mode 100644 index 000000000..09c16aa05 --- /dev/null +++ b/core/sys/win32/removal.odin @@ -0,0 +1,3 @@ +package sys_win32 + +#panic(`"core:sys/win32" has been removed. Please use "core:sys/windows"`) \ No newline at end of file diff --git a/core/sys/win32/shell32.odin b/core/sys/win32/shell32.odin deleted file mode 100644 index 3cedf0527..000000000 --- a/core/sys/win32/shell32.odin +++ /dev/null @@ -1,9 +0,0 @@ -// +build windows -package win32 - -foreign import "system:shell32.lib" - -@(default_calling_convention = "std") -foreign shell32 { - @(link_name="CommandLineToArgvW") command_line_to_argv_w :: proc(cmd_list: Wstring, num_args: ^i32) -> ^Wstring --- -} diff --git a/core/sys/win32/tests/general.odin b/core/sys/win32/tests/general.odin deleted file mode 100644 index 9a78dec11..000000000 --- a/core/sys/win32/tests/general.odin +++ /dev/null @@ -1,41 +0,0 @@ -package win32_tests - -import win32 "core:sys/windows" -import "core:testing" - -utf16_to_utf8 :: proc(t: ^testing.T, str: []u16, comparison: string, expected_result: bool, loc := #caller_location) { - result, _ := win32.utf16_to_utf8(str[:]) - testing.expect(t, (result == comparison) == expected_result, "Incorrect utf16_to_utf8 conversion", loc) -} - -wstring_to_utf8 :: proc(t: ^testing.T, str: []u16, comparison: string, expected_result: bool, loc := #caller_location) { - result, _ := win32.wstring_to_utf8(nil if len(str) == 0 else cast(win32.Wstring)&str[0], -1) - testing.expect(t, (result == comparison) == expected_result, "Incorrect wstring_to_utf8 conversion", loc) -} - -@test -test_utf :: proc(t: ^testing.T) { - utf16_to_utf8(t, []u16{}, "", true) - utf16_to_utf8(t, []u16{0}, "", true) - utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true) - utf16_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true) - utf16_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", true) - utf16_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true) - utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true) - utf16_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true) - - wstring_to_utf8(t, []u16{}, "", true) - wstring_to_utf8(t, []u16{0}, "", true) - wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't'}, "", true) - wstring_to_utf8(t, []u16{0, 't', 'e', 's', 't', 0}, "", true) - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}, "test", true) - wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't'}, "te", true) - wstring_to_utf8(t, []u16{'t', 'e', 0, 's', 't', 0}, "te", true) - - // WARNING: Passing a non-zero-terminated string to wstring_to_utf8 is dangerous, - // as it will go out of bounds looking for a zero. - // It will "fail" or "succeed" by having a zero just after the end of the input string or not. - wstring_to_utf8(t, []u16{'t', 'e', 's', 't'}, "test", false) - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 0}[:4], "test", true) - wstring_to_utf8(t, []u16{'t', 'e', 's', 't', 'q'}[:4], "test", false) -} \ No newline at end of file diff --git a/core/sys/win32/user32.odin b/core/sys/win32/user32.odin deleted file mode 100644 index 44d1f7004..000000000 --- a/core/sys/win32/user32.odin +++ /dev/null @@ -1,289 +0,0 @@ -// +build windows -package win32 - -foreign import "system:user32.lib" - -import "core:intrinsics" - - -Menu_Bar_Info :: struct { - size: u32, - bar: Rect, - menu: Hmenu, - wnd_menu: Hwnd, - fields: u8, - // field.bar_focused: 1, - // field.focuses: 1, -} - -Menu_Item_Info_A :: struct { - size: u32, - mask: u32, - type: u32, - state: u32, - id: u32, - submenu: Hmenu, - bmp_checked: Hbitmap, - bmp_unchecked: Hbitmap, - item_data: u32, - type_data: cstring, - cch: u32, -} -Menu_Item_Info_W :: struct { - size: u32, - mask: u32, - type: u32, - state: u32, - id: u32, - submenu: Hmenu, - bmp_checked: Hbitmap, - bmp_unchecked: Hbitmap, - item_data: u32, - type_data: Wstring, - cch: u32, -} - -MF_BYCOMMAND :: 0x00000000 -MF_BYPOSITION :: 0x00000400 -MF_BITMAP :: 0x00000004 -MF_CHECKED :: 0x00000008 -MF_DISABLED :: 0x00000002 -MF_ENABLED :: 0x00000000 -MF_GRAYED :: 0x00000001 -MF_MENUBARBREAK :: 0x00000020 -MF_MENUBREAK :: 0x00000040 -MF_OWNERDRAW :: 0x00000100 -MF_POPUP :: 0x00000010 -MF_SEPARATOR :: 0x00000800 -MF_STRING :: 0x00000000 -MF_UNCHECKED :: 0x00000000 - -MB_ABORTRETRYIGNORE :: 0x00000002 -MB_CANCELTRYCONTINUE :: 0x00000006 -MB_HELP :: 0x00004000 -MB_OK :: 0x00000000 -MB_OKCANCEL :: 0x00000001 -MB_RETRYCANCEL :: 0x00000005 -MB_YESNO :: 0x00000004 -MB_YESNOCANCEL :: 0x00000003 - -MB_ICONEXCLAMATION :: 0x00000030 -MB_ICONWARNING :: 0x00000030 -MB_ICONINFORMATION :: 0x00000040 -MB_ICONASTERISK :: 0x00000040 -MB_ICONQUESTION :: 0x00000020 -MB_ICONSTOP :: 0x00000010 -MB_ICONERROR :: 0x00000010 -MB_ICONHAND :: 0x00000010 - -MB_DEFBUTTON1 :: 0x00000000 -MB_DEFBUTTON2 :: 0x00000100 -MB_DEFBUTTON3 :: 0x00000200 -MB_DEFBUTTON4 :: 0x00000300 - -MB_APPLMODAL :: 0x00000000 -MB_SYSTEMMODAL :: 0x00001000 -MB_TASKMODAL :: 0x00002000 - -MB_DEFAULT_DESKTOP_ONLY :: 0x00020000 -MB_RIGHT :: 0x00080000 -MB_RTLREADING :: 0x00100000 -MB_SETFOREGROUND :: 0x00010000 -MB_TOPMOST :: 0x00040000 -MB_SERVICE_NOTIFICATION :: 0x00200000 - - -@(default_calling_convention = "std") -foreign user32 { - @(link_name="GetDesktopWindow") get_desktop_window :: proc() -> Hwnd --- - when !intrinsics.is_package_imported("raylib") { // NOTE(bill): this is a bit of hack but it's to get around the namespace collisions - @(link_name="ShowCursor")show_cursor :: proc(show: Bool) -> i32 --- - } - @(link_name="GetCursorPos") get_cursor_pos :: proc(p: ^Point) -> Bool --- - @(link_name="SetCursorPos") set_cursor_pos :: proc(x, y: i32) -> Bool --- - @(link_name="GetCapure") get_capture :: proc(hwnd: Hwnd) -> Hwnd --- - @(link_name="SetCapture") set_capture :: proc(hwnd: Hwnd) -> Hwnd --- - @(link_name="ReleaseCapture") release_capture :: proc() -> Bool --- - @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool --- - @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool --- - @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) --- - @(link_name="SetWindowTextA") set_window_text_a :: proc(hwnd: Hwnd, c_string: cstring) -> Bool --- - @(link_name="SetWindowTextW") set_window_text_w :: proc(hwnd: Hwnd, c_string: Wstring) -> Bool --- - @(link_name="RegisterClassA") register_class_a :: proc(wc: ^Wnd_Class_A) -> i16 --- - @(link_name="RegisterClassW") register_class_w :: proc(wc: ^Wnd_Class_W) -> i16 --- - @(link_name="UnregisterClassA") unregister_class_a :: proc(class_name: cstring, instance: Hinstance) -> Bool --- - @(link_name="UnregisterClassW") unregister_class_w :: proc(class_name: Wstring, instance: Hinstance) -> Bool --- - @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 --- - @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 --- - - @(link_name="CreateWindowExA") - create_window_ex_a :: proc(ex_style: u32, - class_name, title: cstring, - style: u32, - x, y, w, h: i32, - parent: Hwnd, menu: Hmenu, instance: Hinstance, - param: rawptr) -> Hwnd --- - - @(link_name="CreateWindowExW") - create_window_ex_w :: proc(ex_style: u32, - class_name, title: Wstring, - style: u32, - x, y, w, h: i32, - parent: Hwnd, menu: Hmenu, instance: Hinstance, - param: rawptr) -> Hwnd --- - - @(link_name="ShowWindow") show_window :: proc(hwnd: Hwnd, cmd_show: i32) -> Bool --- - @(link_name="TranslateMessage") translate_message :: proc(msg: ^Msg) -> Bool --- - @(link_name="DispatchMessageA") dispatch_message_a :: proc(msg: ^Msg) -> Lresult --- - @(link_name="DispatchMessageW") dispatch_message_w :: proc(msg: ^Msg) -> Lresult --- - @(link_name="UpdateWindow") update_window :: proc(hwnd: Hwnd) -> Bool --- - @(link_name="GetMessageA") get_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max: u32) -> Bool --- - @(link_name="GetMessageW") get_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max: u32) -> Bool --- - - @(link_name="PeekMessageA") peek_message_a :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool --- - @(link_name="PeekMessageW") peek_message_w :: proc(msg: ^Msg, hwnd: Hwnd, msg_filter_min, msg_filter_max, remove_msg: u32) -> Bool --- - - - @(link_name="PostMessageA") post_message_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Bool --- - @(link_name="PostMessageW") post_message_w :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Bool --- - @(link_name="SendMessageA") send_message_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult --- - @(link_name="SendMessageW") send_message_w :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult --- - - @(link_name="DefWindowProcA") def_window_proc_a :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult --- - @(link_name="DefWindowProcW") def_window_proc_w :: proc(hwnd: Hwnd, msg: u32, wparam: Wparam, lparam: Lparam) -> Lresult --- - - @(link_name="AdjustWindowRect") adjust_window_rect :: proc(rect: ^Rect, style: u32, menu: Bool) -> Bool --- - @(link_name="GetActiveWindow") get_active_window :: proc() -> Hwnd --- - - @(link_name="DestroyWindow") destroy_window :: proc(wnd: Hwnd) -> Bool --- - @(link_name="DescribePixelFormat") describe_pixel_format :: proc(dc: Hdc, pixel_format: i32, bytes: u32, pfd: ^Pixel_Format_Descriptor) -> i32 --- - - @(link_name="GetMonitorInfoA") get_monitor_info_a :: proc(monitor: Hmonitor, mi: ^Monitor_Info) -> Bool --- - @(link_name="MonitorFromWindow") monitor_from_window :: proc(wnd: Hwnd, flags: u32) -> Hmonitor --- - - @(link_name="SetWindowPos") set_window_pos :: proc(wnd: Hwnd, wndInsertAfter: Hwnd, x, y, width, height: i32, flags: u32) -> Bool --- - - @(link_name="GetWindowPlacement") get_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool --- - @(link_name="SetWindowPlacement") set_window_placement :: proc(wnd: Hwnd, wndpl: ^Window_Placement) -> Bool --- - @(link_name="GetWindowRect") get_window_rect :: proc(wnd: Hwnd, rect: ^Rect) -> Bool --- - - @(link_name="GetWindowLongPtrA") get_window_long_ptr_a :: proc(wnd: Hwnd, index: i32) -> Long_Ptr --- - @(link_name="SetWindowLongPtrA") set_window_long_ptr_a :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr --- - @(link_name="GetWindowLongPtrW") get_window_long_ptr_w :: proc(wnd: Hwnd, index: i32) -> Long_Ptr --- - @(link_name="SetWindowLongPtrW") set_window_long_ptr_w :: proc(wnd: Hwnd, index: i32, new: Long_Ptr) -> Long_Ptr --- - - @(link_name="GetWindowText") get_window_text :: proc(wnd: Hwnd, str: cstring, maxCount: i32) -> i32 --- - - @(link_name="GetClientRect") get_client_rect :: proc(hwnd: Hwnd, rect: ^Rect) -> Bool --- - - @(link_name="GetDC") get_dc :: proc(h: Hwnd) -> Hdc --- - @(link_name="ReleaseDC") release_dc :: proc(wnd: Hwnd, hdc: Hdc) -> i32 --- - - @(link_name="MapVirtualKeyA") map_virtual_key_a :: proc(scancode: u32, map_type: u32) -> u32 --- - @(link_name="MapVirtualKeyW") map_virtual_key_w :: proc(scancode: u32, map_type: u32) -> u32 --- - - @(link_name="GetKeyState") get_key_state :: proc(v_key: i32) -> i16 --- - @(link_name="GetAsyncKeyState") get_async_key_state :: proc(v_key: i32) -> i16 --- - - @(link_name="SetForegroundWindow") set_foreground_window :: proc(h: Hwnd) -> Bool --- - @(link_name="SetFocus") set_focus :: proc(h: Hwnd) -> Hwnd --- - - - @(link_name="LoadImageA") load_image_a :: proc(instance: Hinstance, name: cstring, type_: u32, x_desired, y_desired : i32, load : u32) -> Handle --- - @(link_name="LoadIconA") load_icon_a :: proc(instance: Hinstance, icon_name: cstring) -> Hicon --- - @(link_name="DestroyIcon") destroy_icon :: proc(icon: Hicon) -> Bool --- - - @(link_name="LoadCursorA") load_cursor_a :: proc(instance: Hinstance, cursor_name: cstring) -> Hcursor --- - @(link_name="LoadCursorW") load_cursor_w :: proc(instance: Hinstance, cursor_name: Wstring) -> Hcursor --- - @(link_name="GetCursor") get_cursor :: proc() -> Hcursor --- - @(link_name="SetCursor") set_cursor :: proc(cursor: Hcursor) -> Hcursor --- - - @(link_name="RegisterRawInputDevices") register_raw_input_devices :: proc(raw_input_device: ^Raw_Input_Device, num_devices, size: u32) -> Bool --- - - @(link_name="GetRawInputData") get_raw_input_data :: proc(raw_input: Hrawinput, command: u32, data: rawptr, size: ^u32, size_header: u32) -> u32 --- - - @(link_name="MapVirtualKeyExW") map_virtual_key_ex_w :: proc(code, map_type: u32, hkl: HKL) -> u32 --- - @(link_name="MapVirtualKeyExA") map_virtual_key_ex_a :: proc(code, map_type: u32, hkl: HKL) -> u32 --- - - @(link_name="EnumDisplayMonitors") enum_display_monitors :: proc(hdc: Hdc, rect: ^Rect, enum_proc: Monitor_Enum_Proc, lparam: Lparam) -> bool --- - - @(link_name="EnumDisplaySettingsA") enum_display_settings_a :: proc(device_name: cstring, mode_number: u32, mode: ^Dev_Mode_A) -> Bool --- -} - -@(default_calling_convention = "std") -foreign user32 { - @(link_name="CreateMenu") create_menu :: proc() -> Hmenu --- - @(link_name="CreatePopupMenu") create_popup_menu :: proc() -> Hmenu --- - @(link_name="DestroyMenu") destroy_menu :: proc(menu: Hmenu) -> Bool --- - @(link_name="DeleteMenu") delete_menu :: proc(menu: Hmenu, position: u32, flags: u32) -> Bool --- - - @(link_name="EnableMenuItem") enable_menu_item :: proc(menu: Hmenu, id_enable_itme: i32, enable: u32) -> Bool --- - @(link_name="EndMenu") end_menu :: proc(menu: Hmenu, flags: u32, id_new_item: Uint_Ptr, new_item: cstring) -> Bool --- - @(link_name="GetMenu") get_menu :: proc(wnd: Hwnd) -> Hmenu --- - @(link_name="GetMenuBarInfo") get_menu_bar_info :: proc(wnd: Hwnd, id_object, id_item: u32, mbi: ^Menu_Bar_Info) -> Hmenu --- - @(link_name="GetMenuStringA") get_menu_string_a :: proc(menu: Hmenu, id_item: u32, s: cstring, cch_max: i32, flags: u32) -> i32 --- - @(link_name="GetMenuStringW") get_menu_string_w :: proc(menu: Hmenu, id_item: u32, s: Wstring, cch_max: i32, flags: u32) -> i32 --- - @(link_name="GetMenuState") get_menu_state :: proc(menu: Hmenu, id: u32, flags: u32) -> u32 --- - @(link_name="GetMenuItemRect") get_menu_item_rect :: proc(wnd: Hwnd, menu: Hmenu, id_item: u32, item: ^Rect) -> Bool --- - - @(link_name="SetMenu") set_menu :: proc(wnd: Hwnd, menu: Hmenu) -> Bool --- - - @(link_name="DrawMenuBar") draw_menu_bar :: proc(wnd: Hwnd) -> Bool --- - @(link_name="InsertMenuA") insert_menu_a :: proc(menu: Hmenu, position: u32, flags: u32, id_new_item: Uint_Ptr, new_item: cstring) -> Bool --- - @(link_name="InsertMenuW") insert_menu_w :: proc(menu: Hmenu, position: u32, flags: u32, id_new_item: Uint_Ptr, new_item: Wstring) -> Bool --- - - @(link_name="InsertMenuItemA") insert_menu_item_a :: proc(hmenu: Hmenu, item: u32, fByPosition: Bool, lpmi: ^Menu_Item_Info_A) -> Bool --- - @(link_name="InsertMenuItemW") insert_menu_item_w :: proc(hmenu: Hmenu, item: u32, fByPosition: Bool, lpmi: ^Menu_Item_Info_W) -> Bool --- - - @(link_name="AppendMenuA") append_menu_a :: proc(menu: Hmenu, flags: u32, id_new_item: Uint_Ptr, new_item: cstring) -> Bool --- - @(link_name="AppendMenuW") append_menu_w :: proc(menu: Hmenu, flags: u32, id_new_item: Uint_Ptr, new_item: Wstring) -> Bool --- - - @(link_name="CheckMenuItem") check_menu_item :: proc(menu: Hmenu, id_check_item: u32, check: u32) -> u32 --- - @(link_name="CheckMenuRadioItem") check_menu_radio_item :: proc(menu: Hmenu, first, last: u32, check: u32, flags: u32) -> Bool --- - - @(link_name="GetPropA") get_prop_a :: proc(wnd: Hwnd, s: cstring) -> Handle --- - @(link_name="GetPropW") get_prop_w :: proc(wnd: Hwnd, s: Wstring) -> Handle --- - - @(link_name="MessageBoxA") message_box_a :: proc(wnd: Hwnd, text, caption: cstring, type: u32) -> i32 --- - @(link_name="MessageBoxW") message_box_w :: proc(wnd: Hwnd, text, caption: Wstring, type: u32) -> i32 --- - - @(link_name="MessageBoxExA") message_box_ex_a :: proc(wnd: Hwnd, text, caption: cstring, type: u32, language_id: u16) -> i32 --- - @(link_name="MessageBoxExW") message_box_ex_w :: proc(wnd: Hwnd, text, caption: Wstring, type: u32, language_id: u16) -> i32 --- - - @(link_name="BeginPaint") begin_paint :: proc(wnd: Hwnd, paint: ^Paint_Struct) -> Hdc --- - @(link_name="EndPaint") end_paint :: proc(wnd: Hwnd, paint: ^Paint_Struct) -> Bool --- -} - - -_IDC_APPSTARTING := rawptr(uintptr(32650)) -_IDC_ARROW := rawptr(uintptr(32512)) -_IDC_CROSS := rawptr(uintptr(32515)) -_IDC_HAND := rawptr(uintptr(32649)) -_IDC_HELP := rawptr(uintptr(32651)) -_IDC_IBEAM := rawptr(uintptr(32513)) -_IDC_ICON := rawptr(uintptr(32641)) -_IDC_NO := rawptr(uintptr(32648)) -_IDC_SIZE := rawptr(uintptr(32640)) -_IDC_SIZEALL := rawptr(uintptr(32646)) -_IDC_SIZENESW := rawptr(uintptr(32643)) -_IDC_SIZENS := rawptr(uintptr(32645)) -_IDC_SIZENWSE := rawptr(uintptr(32642)) -_IDC_SIZEWE := rawptr(uintptr(32644)) -_IDC_UPARROW := rawptr(uintptr(32516)) -_IDC_WAIT := rawptr(uintptr(32514)) -IDC_APPSTARTING := cstring(_IDC_APPSTARTING) -IDC_ARROW := cstring(_IDC_ARROW) -IDC_CROSS := cstring(_IDC_CROSS) -IDC_HAND := cstring(_IDC_HAND) -IDC_HELP := cstring(_IDC_HELP) -IDC_IBEAM := cstring(_IDC_IBEAM) -IDC_ICON := cstring(_IDC_ICON) -IDC_NO := cstring(_IDC_NO) -IDC_SIZE := cstring(_IDC_SIZE) -IDC_SIZEALL := cstring(_IDC_SIZEALL) -IDC_SIZENESW := cstring(_IDC_SIZENESW) -IDC_SIZENS := cstring(_IDC_SIZENS) -IDC_SIZENWSE := cstring(_IDC_SIZENWSE) -IDC_SIZEWE := cstring(_IDC_SIZEWE) -IDC_UPARROW := cstring(_IDC_UPARROW) -IDC_WAIT := cstring(_IDC_WAIT) diff --git a/core/sys/win32/wgl.odin b/core/sys/win32/wgl.odin deleted file mode 100644 index e6c414b0e..000000000 --- a/core/sys/win32/wgl.odin +++ /dev/null @@ -1,114 +0,0 @@ -// +build windows -package win32 - -foreign import "system:opengl32.lib" - -CONTEXT_MAJOR_VERSION_ARB :: 0x2091 -CONTEXT_MINOR_VERSION_ARB :: 0x2092 -CONTEXT_FLAGS_ARB :: 0x2094 -CONTEXT_PROFILE_MASK_ARB :: 0x9126 -CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002 -CONTEXT_CORE_PROFILE_BIT_ARB :: 0x00000001 -CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x00000002 - -Hglrc :: distinct Handle -Color_Ref :: distinct u32 - -Layer_Plane_Descriptor :: struct { - size: u16, - version: u16, - flags: u32, - pixel_type: u8, - color_bits: u8, - red_bits: u8, - red_shift: u8, - green_bits: u8, - green_shift: u8, - blue_bits: u8, - blue_shift: u8, - alpha_bits: u8, - alpha_shift: u8, - accum_bits: u8, - accum_red_bits: u8, - accum_green_bits: u8, - accum_blue_bits: u8, - accum_alpha_bits: u8, - depth_bits: u8, - stencil_bits: u8, - aux_buffers: u8, - layer_type: u8, - reserved: u8, - transparent: Color_Ref, -} - -Point_Float :: struct {x, y: f32} - -Glyph_Metrics_Float :: struct { - black_box_x: f32, - black_box_y: f32, - glyph_origin: Point_Float, - cell_inc_x: f32, - cell_inc_y: f32, -} - -Create_Context_Attribs_ARB_Type :: #type proc "c" (hdc: Hdc, h_share_context: rawptr, attribList: ^i32) -> Hglrc -Choose_Pixel_Format_ARB_Type :: #type proc "c" (hdc: Hdc, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> Bool -Swap_Interval_EXT_Type :: #type proc "c" (interval: i32) -> bool -Get_Extensions_String_ARB_Type :: #type proc "c" (Hdc) -> cstring - -// Procedures - create_context_attribs_arb: Create_Context_Attribs_ARB_Type - choose_pixel_format_arb: Choose_Pixel_Format_ARB_Type - swap_interval_ext: Swap_Interval_EXT_Type - get_extensions_string_arb: Get_Extensions_String_ARB_Type - - -foreign opengl32 { - @(link_name="wglCreateContext") - create_context :: proc(hdc: Hdc) -> Hglrc --- - - @(link_name="wglMakeCurrent") - make_current :: proc(hdc: Hdc, hglrc: Hglrc) -> Bool --- - - @(link_name="wglGetProcAddress") - get_gl_proc_address :: proc(c_str: cstring) -> rawptr --- - - @(link_name="wglDeleteContext") - delete_context :: proc(hglrc: Hglrc) -> Bool --- - - @(link_name="wglCopyContext") - copy_context :: proc(src, dst: Hglrc, mask: u32) -> Bool --- - - @(link_name="wglCreateLayerContext") - create_layer_context :: proc(hdc: Hdc, layer_plane: i32) -> Hglrc --- - - @(link_name="wglDescribeLayerPlane") - describe_layer_plane :: proc(hdc: Hdc, pixel_format, layer_plane: i32, bytes: u32, pd: ^Layer_Plane_Descriptor) -> Bool --- - - @(link_name="wglGetCurrentContext") - get_current_context :: proc() -> Hglrc --- - - @(link_name="wglGetCurrentDC") - get_current_dc :: proc() -> Hdc --- - - @(link_name="wglGetLayerPaletteEntries") - get_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 --- - - @(link_name="wglRealizeLayerPalette") - realize_layer_palette :: proc(hdc: Hdc, layer_plane: i32, realize: Bool) -> Bool --- - - @(link_name="wglSetLayerPaletteEntries") - set_layer_palette_entries :: proc(hdc: Hdc, layer_plane, start, entries: i32, cr: ^Color_Ref) -> i32 --- - - @(link_name="wglShareLists") - share_lists :: proc(hglrc1, hglrc2: Hglrc) -> Bool --- - - @(link_name="wglSwapLayerBuffers") - swap_layer_buffers :: proc(hdc: Hdc, planes: u32) -> Bool --- - - @(link_name="wglUseFontBitmaps") - use_font_bitmaps :: proc(hdc: Hdc, first, count, list_base: u32) -> Bool --- - - @(link_name="wglUseFontOutlines") - use_font_outlines :: proc(hdc: Hdc, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^Glyph_Metrics_Float) -> Bool --- -} diff --git a/core/sys/win32/winmm.odin b/core/sys/win32/winmm.odin deleted file mode 100644 index 0f567fbcc..000000000 --- a/core/sys/win32/winmm.odin +++ /dev/null @@ -1,12 +0,0 @@ -// +build windows -package win32 - -foreign import "system:winmm.lib" - - -@(default_calling_convention = "std") -foreign winmm { - @(link_name="timeBeginPeriod") time_begin_period :: proc(period: u32) -> u32 --- - - @(link_name="timeGetTime") time_get_time :: proc() -> u32 --- -} From f002857edce5ea53561608fa555bbbd94b7fa42a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 15:47:24 +0100 Subject: [PATCH 201/245] Clean up `core:time` to be consistent across all platforms --- core/os/os2/errors.odin | 2 + core/runtime/procs.odin | 2 +- core/sys/unix/pthread_unix.odin | 5 +- core/sys/unix/time_unix.odin | 83 ++++++++++++++++++++++ core/time/time.odin | 42 +++++++---- core/time/time_essence.odin | 13 ++-- core/time/time_freestanding.odin | 9 ++- core/time/time_js.odin | 7 +- core/time/time_unix.odin | 118 +++++-------------------------- core/time/time_wasi.odin | 7 +- core/time/time_windows.odin | 9 ++- 11 files changed, 159 insertions(+), 138 deletions(-) create mode 100644 core/sys/unix/time_unix.odin diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index f42f92eb9..2cff73ebd 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -14,6 +14,7 @@ General_Error :: enum u32 { Timeout, Invalid_File, + Invalid_Dir, Invalid_Path, Unsupported, @@ -51,6 +52,7 @@ error_string :: proc(ferr: Error) -> string { case .Closed: return "file already closed" case .Timeout: return "i/o timeout" case .Invalid_File: return "invalid file" + case .Invalid_Dir: return "invalid directory" case .Invalid_Path: return "invalid path" case .Unsupported: return "unsupported" } diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 5a1d11fe0..782efa773 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -4,7 +4,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows { foreign import lib "system:NtDll.lib" @(private="file") - @(default_calling_convention="std") + @(default_calling_convention="stdcall") foreign lib { RtlMoveMemory :: proc(dst, src: rawptr, length: int) --- RtlFillMemory :: proc(dst: rawptr, length: int, fill: i32) --- diff --git a/core/sys/unix/pthread_unix.odin b/core/sys/unix/pthread_unix.odin index 62e3701ab..8bf397647 100644 --- a/core/sys/unix/pthread_unix.odin +++ b/core/sys/unix/pthread_unix.odin @@ -4,7 +4,6 @@ package unix foreign import "system:pthread" import "core:c" -import "core:time" // // On success, these functions return 0. @@ -72,7 +71,7 @@ foreign pthread { // assumes the mutex is pre-locked pthread_cond_wait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t) -> c.int --- - pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^time.TimeSpec) -> c.int --- + pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int --- pthread_condattr_init :: proc(attrs: ^pthread_condattr_t) -> c.int --- pthread_condattr_destroy :: proc(attrs: ^pthread_condattr_t) -> c.int --- @@ -95,7 +94,7 @@ foreign pthread { pthread_mutex_lock :: proc(mutex: ^pthread_mutex_t) -> c.int --- - pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^time.TimeSpec) -> c.int --- + pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int --- pthread_mutex_unlock :: proc(mutex: ^pthread_mutex_t) -> c.int --- diff --git a/core/sys/unix/time_unix.odin b/core/sys/unix/time_unix.odin new file mode 100644 index 000000000..d9452c216 --- /dev/null +++ b/core/sys/unix/time_unix.odin @@ -0,0 +1,83 @@ +//+build linux, darwin, freebsd, openbsd +package unix + +when ODIN_OS == .Darwin { + foreign import libc "System.framework" +} else { + foreign import libc "system:c" +} + +@(default_calling_convention="c") +foreign libc { + clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> i32 --- + sleep :: proc(seconds: u32) -> i32 --- + nanosleep :: proc(requested, remaining: ^timespec) -> i32 --- +} + +foreign import "system:pthread" + +import "core:c" + +@(private="file") +@(default_calling_convention="c") +foreign pthread { + sched_yield :: proc() -> c.int --- +} + +timespec :: struct { + tv_sec: i64, // seconds + tv_nsec: i64, // nanoseconds +} + +when ODIN_OS == .OpenBSD { + CLOCK_REALTIME :: 0 + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_MONOTONIC :: 3 + CLOCK_THREAD_CPUTIME_ID :: 4 + CLOCK_UPTIME :: 5 + CLOCK_BOOTTIME :: 6 + + // CLOCK_MONOTONIC_RAW doesn't exist, use CLOCK_MONOTONIC + CLOCK_MONOTONIC_RAW :: CLOCK_MONOTONIC +} else { + CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. + CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_THREAD_CPUTIME_ID :: 3 + CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. + CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." + CLOCK_MONOTONIC_COARSE :: 6 + CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. + CLOCK_REALTIME_ALARM :: 8 + CLOCK_BOOTTIME_ALARM :: 9 +} + +// TODO(tetra, 2019-11-05): The original implementation of this package for Darwin used this constants. +// I do not know if Darwin programmers are used to the existance of these constants or not, so +// I'm leaving aliases to them for now. +CLOCK_SYSTEM :: CLOCK_REALTIME +CLOCK_CALENDAR :: CLOCK_MONOTONIC + +boot_time_in_nanoseconds :: proc "c" () -> i64 { + ts_now, ts_boottime: timespec + clock_gettime(CLOCK_REALTIME, &ts_now) + clock_gettime(CLOCK_BOOTTIME, &ts_boottime) + + ns := (ts_now.tv_sec - ts_boottime.tv_sec) * 1e9 + ts_now.tv_nsec - ts_boottime.tv_nsec + return i64(ns) +} + +seconds_since_boot :: proc "c" () -> f64 { + ts_boottime: timespec + clock_gettime(CLOCK_BOOTTIME, &ts_boottime) + return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9 +} + + +inline_nanosleep :: proc "c" (nanoseconds: i64) -> (remaining: timespec, res: i32) { + s, ns := nanoseconds / 1e9, nanoseconds % 1e9 + requested := timespec{tv_sec=s, tv_nsec=ns} + res = nanosleep(&requested, &remaining) + return +} + diff --git a/core/time/time.odin b/core/time/time.odin index 1f778a8de..6c6e47dc0 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -14,6 +14,8 @@ Hour :: 60 * Minute MIN_DURATION :: Duration(-1 << 63) MAX_DURATION :: Duration(1<<63 - 1) +IS_SUPPORTED :: _IS_SUPPORTED + Time :: struct { _nsec: i64, // zero is 1970-01-01 00:00:00 } @@ -49,6 +51,14 @@ Stopwatch :: struct { _accumulation: Duration, } +now :: proc "contextless" () -> Time { + return _now() +} + +sleep :: proc "contextless" (d: Duration) { + _sleep(d) +} + stopwatch_start :: proc(using stopwatch: ^Stopwatch) { if !running { _start_time = tick_now() @@ -82,36 +92,36 @@ since :: proc(start: Time) -> Duration { return diff(start, now()) } -duration_nanoseconds :: proc(d: Duration) -> i64 { +duration_nanoseconds :: proc "contextless" (d: Duration) -> i64 { return i64(d) } -duration_microseconds :: proc(d: Duration) -> f64 { +duration_microseconds :: proc "contextless" (d: Duration) -> f64 { return duration_seconds(d) * 1e6 } -duration_milliseconds :: proc(d: Duration) -> f64 { +duration_milliseconds :: proc "contextless" (d: Duration) -> f64 { return duration_seconds(d) * 1e3 } -duration_seconds :: proc(d: Duration) -> f64 { +duration_seconds :: proc "contextless" (d: Duration) -> f64 { sec := d / Second nsec := d % Second return f64(sec) + f64(nsec)/1e9 } -duration_minutes :: proc(d: Duration) -> f64 { +duration_minutes :: proc "contextless" (d: Duration) -> f64 { min := d / Minute nsec := d % Minute return f64(min) + f64(nsec)/(60*1e9) } -duration_hours :: proc(d: Duration) -> f64 { +duration_hours :: proc "contextless" (d: Duration) -> f64 { hour := d / Hour nsec := d % Hour return f64(hour) + f64(nsec)/(60*60*1e9) } -_less_than_half :: #force_inline proc(x, y: Duration) -> bool { - return u64(x)+u64(x) < u64(y) -} - duration_round :: proc(d, m: Duration) -> Duration { + _less_than_half :: #force_inline proc(x, y: Duration) -> bool { + return u64(x)+u64(x) < u64(y) + } + if m <= 0 { return d } @@ -201,10 +211,12 @@ unix :: proc(sec: i64, nsec: i64) -> Time { return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL} } +to_unix_seconds :: time_to_unix time_to_unix :: proc(t: Time) -> i64 { return t._nsec/1e9 } +to_unix_nanoseconds :: time_to_unix_nano time_to_unix_nano :: proc(t: Time) -> i64 { return t._nsec } @@ -265,20 +277,24 @@ INTERNAL_TO_WALL :: -WALL_TO_INTERNAL UNIX_TO_ABSOLUTE :: UNIX_TO_INTERNAL + INTERNAL_TO_ABSOLUTE ABSOLUTE_TO_UNIX :: -UNIX_TO_ABSOLUTE -_is_leap_year :: proc(year: int) -> bool { - return year%4 == 0 && (year%100 != 0 || year%400 == 0) -} +@(private) _date :: proc(t: Time, full: bool) -> (year: int, month: Month, day: int, yday: int) { year, month, day, yday = _abs_date(_time_abs(t), full) return } +@(private) _time_abs :: proc(t: Time) -> u64 { return u64(t._nsec/1e9 + UNIX_TO_ABSOLUTE) } +@(private) _abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, yday: int) { + _is_leap_year :: proc(year: int) -> bool { + return year%4 == 0 && (year%100 != 0 || year%400 == 0) + } + d := abs / SECONDS_PER_DAY // 400 year cycles diff --git a/core/time/time_essence.odin b/core/time/time_essence.odin index 72efe9f8f..b7bc616d8 100644 --- a/core/time/time_essence.odin +++ b/core/time/time_essence.odin @@ -1,18 +1,19 @@ +//+private package time import "core:sys/es" -IS_SUPPORTED :: true; +_IS_SUPPORTED :: true -now :: proc "contextless" () -> Time { +_now :: proc "contextless" () -> Time { // TODO Replace once there's a proper time API. - return Time{_nsec = i64(es.TimeStampMs() * 1e6)}; + return Time{_nsec = i64(es.TimeStampMs() * 1e6)} } -sleep :: proc "contextless" (d: Duration) { - es.Sleep(u64(d/Millisecond)); +_sleep :: proc "contextless" (d: Duration) { + es.Sleep(u64(d/Millisecond)) } _tick_now :: proc "contextless" () -> Tick { - return Tick{_nsec = i64(es.TimeStampMs() * 1e6)}; + return Tick{_nsec = i64(es.TimeStampMs() * 1e6)} } diff --git a/core/time/time_freestanding.odin b/core/time/time_freestanding.odin index 17a21d79c..7c67cc5e8 100644 --- a/core/time/time_freestanding.odin +++ b/core/time/time_freestanding.odin @@ -1,16 +1,19 @@ +//+private //+build freestanding package time -IS_SUPPORTED :: false +_IS_SUPPORTED :: false -now :: proc() -> Time { +_now :: proc "contextless" () -> Time { return {} } -sleep :: proc(d: Duration) { +_sleep :: proc "contextless" (d: Duration) { } _tick_now :: proc "contextless" () -> Tick { return {} } +_yield :: proc "contextless" () { +} diff --git a/core/time/time_js.odin b/core/time/time_js.odin index cfe54b86b..9a7163f38 100644 --- a/core/time/time_js.odin +++ b/core/time/time_js.odin @@ -1,13 +1,14 @@ +//+private //+build js package time -IS_SUPPORTED :: false +_IS_SUPPORTED :: false -now :: proc() -> Time { +_now :: proc "contextless" () -> Time { return {} } -sleep :: proc(d: Duration) { +_sleep :: proc "contextless" (d: Duration) { } _tick_now :: proc "contextless" () -> Tick { diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 0cfa196a2..ba0d91527 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,118 +1,34 @@ +//+private //+build linux, darwin, freebsd, openbsd package time -IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. +import "core:sys/unix" -when ODIN_OS == .Darwin { - foreign import libc "System.framework" -} else { - foreign import libc "system:c" -} +_IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. - -@(default_calling_convention="c") -foreign libc { - @(link_name="clock_gettime") _unix_clock_gettime :: proc(clock_id: u64, timespec: ^TimeSpec) -> i32 --- - @(link_name="sleep") _unix_sleep :: proc(seconds: u32) -> i32 --- - @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 --- -} - -foreign import "system:pthread" - -import "core:c" - -@(private="file") -@(default_calling_convention="c") -foreign pthread { - sched_yield :: proc() -> c.int --- -} - -_yield :: proc "contextless" () { - sched_yield() -} - -TimeSpec :: struct { - tv_sec : i64, /* seconds */ - tv_nsec : i64, /* nanoseconds */ -} - -when ODIN_OS == .OpenBSD { - CLOCK_REALTIME :: 0 - CLOCK_PROCESS_CPUTIME_ID :: 2 - CLOCK_MONOTONIC :: 3 - CLOCK_THREAD_CPUTIME_ID :: 4 - CLOCK_UPTIME :: 5 - CLOCK_BOOTTIME :: 6 - - // CLOCK_MONOTONIC_RAW doesn't exist, use CLOCK_MONOTONIC - CLOCK_MONOTONIC_RAW :: CLOCK_MONOTONIC -} else { - CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. - CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. - CLOCK_PROCESS_CPUTIME_ID :: 2 - CLOCK_THREAD_CPUTIME_ID :: 3 - CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. - CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." - CLOCK_MONOTONIC_COARSE :: 6 - CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. - CLOCK_REALTIME_ALARM :: 8 - CLOCK_BOOTTIME_ALARM :: 9 -} - -// TODO(tetra, 2019-11-05): The original implementation of this package for Darwin used this constants. -// I do not know if Darwin programmers are used to the existance of these constants or not, so -// I'm leaving aliases to them for now. -CLOCK_SYSTEM :: CLOCK_REALTIME -CLOCK_CALENDAR :: CLOCK_MONOTONIC - - -clock_gettime :: proc "contextless" (clock_id: u64) -> TimeSpec { - ts : TimeSpec // NOTE(tetra): Do we need to initialize this? - _unix_clock_gettime(clock_id, &ts) - return ts -} - -now :: proc() -> Time { - time_spec_now := clock_gettime(CLOCK_REALTIME) +_now :: proc "contextless" () -> Time { + time_spec_now: unix.timespec + unix.clock_gettime(unix.CLOCK_REALTIME, &time_spec_now) ns := time_spec_now.tv_sec * 1e9 + time_spec_now.tv_nsec return Time{_nsec=ns} } -boot_time :: proc() -> Time { - ts_now := clock_gettime(CLOCK_REALTIME) - ts_boottime := clock_gettime(CLOCK_BOOTTIME) - - ns := (ts_now.tv_sec - ts_boottime.tv_sec) * 1e9 + ts_now.tv_nsec - ts_boottime.tv_nsec - return Time{_nsec=ns} -} - -seconds_since_boot :: proc() -> f64 { - ts_boottime := clock_gettime(CLOCK_BOOTTIME) - return f64(ts_boottime.tv_sec) + f64(ts_boottime.tv_nsec) / 1e9 -} - - -sleep :: proc(d: Duration) { +_sleep :: proc "contextless" (d: Duration) { ds := duration_seconds(d) seconds := u32(ds) nanoseconds := i64((ds - f64(seconds)) * 1e9) - if seconds > 0 { _unix_sleep(seconds) } - if nanoseconds > 0 { nanosleep(nanoseconds) } + if seconds > 0 { unix.sleep(seconds) } + if nanoseconds > 0 { unix.inline_nanosleep(nanoseconds) } } -nanosleep :: proc(nanoseconds: i64) -> int { - // NOTE(tetra): Should we remove this assert? We are measuring nanoseconds after all... - assert(nanoseconds <= 999999999) - - requested := TimeSpec{tv_nsec = nanoseconds} - remaining: TimeSpec // NOTE(tetra): Do we need to initialize this? - return int(_unix_nanosleep(&requested, &remaining)) -} - - _tick_now :: proc "contextless" () -> Tick { - t := clock_gettime(CLOCK_MONOTONIC_RAW) - _nsec := t.tv_sec*1e9 + t.tv_nsec - return Tick{_nsec = _nsec} + t: unix.timespec + unix.clock_gettime(unix.CLOCK_MONOTONIC_RAW, &t) + return Tick{_nsec = t.tv_sec*1e9 + t.tv_nsec} } + +_yield :: proc "contextless" () { + unix.sched_yield() +} + diff --git a/core/time/time_wasi.odin b/core/time/time_wasi.odin index 4a6c8afc0..9360e3591 100644 --- a/core/time/time_wasi.odin +++ b/core/time/time_wasi.odin @@ -1,15 +1,16 @@ +//+private //+build wasi package time import wasi "core:sys/wasm/wasi" -IS_SUPPORTED :: false +_IS_SUPPORTED :: false -now :: proc() -> Time { +_now :: proc "contextless" () -> Time { return {} } -sleep :: proc(d: Duration) { +_sleep :: proc "contextless" (d: Duration) { } _tick_now :: proc "contextless" () -> Tick { diff --git a/core/time/time_windows.odin b/core/time/time_windows.odin index 397741126..20863c323 100644 --- a/core/time/time_windows.odin +++ b/core/time/time_windows.odin @@ -1,22 +1,21 @@ +//+private package time import win32 "core:sys/windows" -IS_SUPPORTED :: true +_IS_SUPPORTED :: true -now :: proc() -> Time { +_now :: proc "contextless" () -> Time { file_time: win32.FILETIME win32.GetSystemTimeAsFileTime(&file_time) ns := win32.FILETIME_as_unix_nanoseconds(file_time) return Time{_nsec=ns} } -sleep :: proc(d: Duration) { +_sleep :: proc "contextless" (d: Duration) { win32.Sleep(win32.DWORD(d/Millisecond)) } - - _tick_now :: proc "contextless" () -> Tick { mul_div_u64 :: proc "contextless" (val, num, den: i64) -> i64 { q := val / den From 2dd181e66313ac3a017c7133084d482d0ed2e205 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 15:48:27 +0100 Subject: [PATCH 202/245] Remove duplication --- core/sys/unix/time_unix.odin | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/core/sys/unix/time_unix.odin b/core/sys/unix/time_unix.odin index d9452c216..fa3a7a29d 100644 --- a/core/sys/unix/time_unix.odin +++ b/core/sys/unix/time_unix.odin @@ -7,21 +7,13 @@ when ODIN_OS == .Darwin { foreign import libc "system:c" } -@(default_calling_convention="c") -foreign libc { - clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> i32 --- - sleep :: proc(seconds: u32) -> i32 --- - nanosleep :: proc(requested, remaining: ^timespec) -> i32 --- -} - -foreign import "system:pthread" - import "core:c" -@(private="file") @(default_calling_convention="c") -foreign pthread { - sched_yield :: proc() -> c.int --- +foreign libc { + clock_gettime :: proc(clock_id: u64, timespec: ^timespec) -> c.int --- + sleep :: proc(seconds: c.uint) -> c.int --- + nanosleep :: proc(requested, remaining: ^timespec) -> c.int --- } timespec :: struct { From d224679619e4b8b41c62d3cf1909ea05a39f569e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 15:57:03 +0100 Subject: [PATCH 203/245] Minor name changes within `core:encoding/xml` for consistency --- core/encoding/xml/debug_print.odin | 2 +- core/encoding/xml/example/xml_example.odin | 2 +- core/encoding/xml/xml_reader.odin | 50 +++++++++++----------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index 7c20ac123..e9a1cb160 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -23,7 +23,7 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error written += wprintf(writer, "[XML Prolog]\n") - for attr in doc.prolog { + for attr in doc.prologue { written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val) } diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index cadfcfb43..f7e74840e 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -35,7 +35,7 @@ example :: proc() { times[round] = time.tick_diff(start, end) } - fastest := time.Duration(max(i64)) + fastest := max(time.Duration) slowest := time.Duration(0) total := time.Duration(0) diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 151d44e2a..b77ae97b3 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -36,10 +36,8 @@ import "core:strings" likely :: intrinsics.expect -DEFAULT_Options :: Options{ - flags = { - .Ignore_Unsupported, - }, +DEFAULT_OPTIONS :: Options{ + flags = {.Ignore_Unsupported}, expected_doctype = "", } @@ -51,7 +49,7 @@ Option_Flag :: enum { Input_May_Be_Modified, /* - Document MUST start with ` (doc: ^Document, err: Error) { +parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { data := data context.allocator = allocator @@ -411,10 +409,10 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err #partial switch next.kind { case .Ident: if len(next.text) == 3 && strings.to_lower(next.text, context.temp_allocator) == "xml" { - parse_prolog(doc) or_return - } else if len(doc.prolog) > 0 { + parse_prologue(doc) or_return + } else if len(doc.prologue) > 0 { /* - We've already seen a prolog. + We've already seen a prologue. */ return doc, .Too_Many_Prologs } else { @@ -481,7 +479,7 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err } } - if .Must_Have_Prolog in opts.flags && len(doc.prolog) == 0 { + if .Must_Have_Prolog in opts.flags && len(doc.prologue) == 0 { return doc, .No_Prolog } @@ -493,16 +491,16 @@ parse_from_slice :: proc(data: []u8, options := DEFAULT_Options, path := "", err return doc, .None } -parse_from_string :: proc(data: string, options := DEFAULT_Options, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { +parse_string :: proc(data: string, options := DEFAULT_OPTIONS, path := "", error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { _data := transmute([]u8)data - return parse_from_slice(_data, options, path, error_handler, allocator) + return parse_bytes(_data, options, path, error_handler, allocator) } -parse :: proc { parse_from_string, parse_from_slice } +parse :: proc { parse_string, parse_bytes } // Load an XML file -load_from_file :: proc(filename: string, options := DEFAULT_Options, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { +load_from_file :: proc(filename: string, options := DEFAULT_OPTIONS, error_handler := default_error_handler, allocator := context.allocator) -> (doc: ^Document, err: Error) { context.allocator = allocator options := options @@ -511,7 +509,7 @@ load_from_file :: proc(filename: string, options := DEFAULT_Options, error_handl options.flags += { .Input_May_Be_Modified } - return parse_from_slice(data, options, filename, error_handler, allocator) + return parse_bytes(data, options, filename, error_handler, allocator) } destroy :: proc(doc: ^Document) { @@ -523,7 +521,7 @@ destroy :: proc(doc: ^Document) { } delete(doc.elements) - delete(doc.prolog) + delete(doc.prologue) delete(doc.comments) delete(doc.input) @@ -556,7 +554,7 @@ expect :: proc(t: ^Tokenizer, kind: Token_Kind) -> (tok: Token, err: Error) { return tok, .Unexpected_Token } -parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) { +parse_attribute :: proc(doc: ^Document) -> (attr: Attribute, offset: int, err: Error) { assert(doc != nil) context.allocator = doc.allocator t := doc.tokenizer @@ -574,7 +572,7 @@ parse_attribute :: proc(doc: ^Document) -> (attr: Attr, offset: int, err: Error) return } -check_duplicate_attributes :: proc(t: ^Tokenizer, attribs: Attributes, attr: Attr, offset: int) -> (err: Error) { +check_duplicate_attributes :: proc(t: ^Tokenizer, attribs: Attributes, attr: Attribute, offset: int) -> (err: Error) { for a in attribs { if attr.key == a.key { error(t, offset, "Duplicate attribute: %v\n", attr.key) @@ -598,21 +596,21 @@ parse_attributes :: proc(doc: ^Document, attribs: ^Attributes) -> (err: Error) { return .None } -parse_prolog :: proc(doc: ^Document) -> (err: Error) { +parse_prologue :: proc(doc: ^Document) -> (err: Error) { assert(doc != nil) context.allocator = doc.allocator t := doc.tokenizer offset := t.offset - parse_attributes(doc, &doc.prolog) or_return + parse_attributes(doc, &doc.prologue) or_return - for attr in doc.prolog { + for attr in doc.prologue { switch attr.key { case "version": switch attr.val { case "1.0", "1.1": case: - error(t, offset, "[parse_prolog] Warning: Unhandled XML version: %v\n", attr.val) + error(t, offset, "[parse_prologue] Warning: Unhandled XML version: %v\n", attr.val) } case "encoding": @@ -627,7 +625,7 @@ parse_prolog :: proc(doc: ^Document) -> (err: Error) { /* Unrecognized encoding, assume UTF-8. */ - error(t, offset, "[parse_prolog] Warning: Unrecognized encoding: %v\n", attr.val) + error(t, offset, "[parse_prologue] Warning: Unrecognized encoding: %v\n", attr.val) } case: From 3fdb3dd7676145091ab73ec83388c4958aebe859 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 15:59:15 +0100 Subject: [PATCH 204/245] Minor style change in leb128.odin --- core/encoding/varint/leb128.odin | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin index f8fcc7de5..1cdbb81b0 100644 --- a/core/encoding/varint/leb128.odin +++ b/core/encoding/varint/leb128.odin @@ -13,7 +13,7 @@ package varint // In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file. // Instead we'll set limits on the values we'll encode/decode // 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`. -LEB128_MAX_BYTES :: 19 +LEB128_MAX_BYTES :: 19 Error :: enum { None = 0, @@ -132,14 +132,12 @@ encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) { return } -@(private) -SIGN_MASK :: (i128(1) << 121) // sign extend mask - // Encode `val` into `buf` as a signed LEB128 encoded series of bytes. // `buf` must be appropriately sized. encode_ileb128 :: proc(buf: []u8, val: i128) -> (size: int, err: Error) { - val := val - more := true + SIGN_MASK :: i128(1) << 121 // sign extend mask + + val, more := val, true for more { size += 1 From bc183101077b1e962ee647999fb462fad15376b1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 16:01:15 +0100 Subject: [PATCH 205/245] Correct xml test --- tests/core/encoding/xml/test_core_xml.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/encoding/xml/test_core_xml.odin b/tests/core/encoding/xml/test_core_xml.odin index c8b02b635..a17594b7e 100644 --- a/tests/core/encoding/xml/test_core_xml.odin +++ b/tests/core/encoding/xml/test_core_xml.odin @@ -218,7 +218,7 @@ doc_to_string :: proc(doc: ^xml.Document) -> (result: string) { written += wprintf(writer, "[XML Prolog]\n") - for attr in doc.prolog { + for attr in doc.prologue { written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val) } From 536e0a8c291bc6efe5d8d3f34e6cab483bf9b921 Mon Sep 17 00:00:00 2001 From: Aaron Glazer Date: Thu, 12 May 2022 08:12:36 -0700 Subject: [PATCH 206/245] Adding flag values for FormatMessageW and LocalAlloc/etc. --- core/sys/windows/types.odin | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index c64207e92..a0649c5f3 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -1159,9 +1159,21 @@ INVALID_HANDLE_VALUE :: INVALID_HANDLE FACILITY_NT_BIT: DWORD : 0x1000_0000 -FORMAT_MESSAGE_FROM_SYSTEM: DWORD : 0x00001000 -FORMAT_MESSAGE_FROM_HMODULE: DWORD : 0x00000800 -FORMAT_MESSAGE_IGNORE_INSERTS: DWORD : 0x00000200 +FORMAT_MESSAGE_ALLOCATE_BUFFER :: 0x00000100 +FORMAT_MESSAGE_IGNORE_INSERTS :: 0x00000200 +FORMAT_MESSAGE_FROM_STRING :: 0x00000400 +FORMAT_MESSAGE_FROM_HMODULE :: 0x00000800 +FORMAT_MESSAGE_FROM_SYSTEM :: 0x00001000 +FORMAT_MESSAGE_ARGUMENT_ARRAY :: 0x00002000 +FORMAT_MESSAGE_MAX_WIDTH_MASK :: 0x000000FF + +LMEM_FIXED :: 0x0000 +LMEM_MOVEABLE :: 0x0002 +LMEM_ZEROINIT :: 0x0040 +LHND :: 0x0042 +LPTR :: 0x0040 +NONZEROLHND :: LMEM_MOVEABLE +NONZEROLPTR :: LMEM_FIXED TLS_OUT_OF_INDEXES: DWORD : 0xFFFFFFFF From f27f5955495725b02be137ec896a4601ece7ff57 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 May 2022 19:35:07 +0100 Subject: [PATCH 207/245] Add `core:encoding/endian` --- core/encoding/endian/doc.odin | 23 +++++ core/encoding/endian/endian.odin | 153 +++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 core/encoding/endian/doc.odin create mode 100644 core/encoding/endian/endian.odin diff --git a/core/encoding/endian/doc.odin b/core/encoding/endian/doc.odin new file mode 100644 index 000000000..754ffa583 --- /dev/null +++ b/core/encoding/endian/doc.odin @@ -0,0 +1,23 @@ +/* + Package endian implements sa simple translation between bytes and numbers with + specific endian encodings. + + buf: [100]u8 + put_u16(buf[:], .Little, 16) or_return + + You may ask yourself, why isn't `byte_order` platform Endianness by default, so we can write: + put_u16(buf[:], 16) or_return + + The answer is that very few file formats are written in native/platform endianness. Most of them specify the endianness of + each of their fields, or use a header field which specifies it for the entire file. + + e.g. a file which specifies it at the top for all fields could do this: + file_order := .Little if buf[0] == 0 else .Big + field := get_u16(buf[1:], file_order) or_return + + If on the other hand a field is *always* Big-Endian, you're wise to explicitly state it for the benefit of the reader, + be that your future self or someone else. + + field := get_u16(buf[:], .Big) or_return +*/ +package encoding_endian diff --git a/core/encoding/endian/endian.odin b/core/encoding/endian/endian.odin new file mode 100644 index 000000000..08bde3139 --- /dev/null +++ b/core/encoding/endian/endian.odin @@ -0,0 +1,153 @@ +package encoding_endian + +Byte_Order :: enum u8 { + Little, + Big, +} + +PLATFORM_BYTE_ORDER :: Byte_Order.Little when ODIN_ENDIAN == .Little else Byte_Order.Big + +get_u16 :: proc(b: []byte, order: Byte_Order) -> (v: u16, ok: bool) { + if len(b) < 2 { + return 0, false + } + #no_bounds_check if order == .Little { + v = u16(b[0]) | u16(b[1])<<8 + } else { + v = u16(b[1]) | u16(b[0])<<8 + } + return v, true +} +get_u32 :: proc(b: []byte, order: Byte_Order) -> (v: u32, ok: bool) { + if len(b) < 4 { + return 0, false + } + #no_bounds_check if order == .Little { + v = u32(b[0]) | u32(b[1])<<8 | u32(b[2])<<16 | u32(b[3])<<24 + } else { + v = u32(b[3]) | u32(b[2])<<8 | u32(b[1])<<16 | u32(b[0])<<24 + } + return v, true +} + +get_u64 :: proc(b: []byte, order: Byte_Order) -> (v: u64, ok: bool) { + if len(b) < 8 { + return 0, false + } + #no_bounds_check if order == .Little { + v = u64(b[0]) | u64(b[1])<<8 | u64(b[2])<<16 | u64(b[3])<<24 | + u64(b[4])<<32 | u64(b[5])<<40 | u64(b[6])<<48 | u64(b[7])<<56 + } else { + v = u64(b[7]) | u64(b[6])<<8 | u64(b[5])<<16 | u64(b[4])<<24 | + u64(b[3])<<32 | u64(b[2])<<40 | u64(b[1])<<48 | u64(b[0])<<56 + } + return v, true +} + +get_i16 :: proc(b: []byte, order: Byte_Order) -> (i16, bool) { + v, ok := get_u16(b, order) + return i16(v), ok +} +get_i32 :: proc(b: []byte, order: Byte_Order) -> (i32, bool) { + v, ok := get_u32(b, order) + return i32(v), ok +} +get_i64 :: proc(b: []byte, order: Byte_Order) -> (i64, bool) { + v, ok := get_u64(b, order) + return i64(v), ok +} + +get_f16 :: proc(b: []byte, order: Byte_Order) -> (f16, bool) { + v, ok := get_u16(b, order) + return transmute(f16)v, ok +} +get_f32 :: proc(b: []byte, order: Byte_Order) -> (f32, bool) { + v, ok := get_u32(b, order) + return transmute(f32)v, ok +} +get_f64 :: proc(b: []byte, order: Byte_Order) -> (f64, bool) { + v, ok := get_u64(b, order) + return transmute(f64)v, ok +} + + +put_u16 :: proc(b: []byte, order: Byte_Order, v: u16) -> bool { + if len(b) < 2 { + return false + } + #no_bounds_check if order == .Little { + b[0] = byte(v) + b[1] = byte(v >> 8) + } else { + b[0] = byte(v >> 8) + b[1] = byte(v) + } + return true +} +put_u32 :: proc(b: []byte, order: Byte_Order, v: u32) -> bool { + if len(b) < 4 { + return false + } + #no_bounds_check if order == .Little { + b[0] = byte(v) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) + } else { + b[0] = byte(v >> 24) + b[1] = byte(v >> 16) + b[2] = byte(v >> 8) + b[3] = byte(v) + } + return true +} +put_u64 :: proc(b: []byte, order: Byte_Order, v: u64) -> bool { + if len(b) < 8 { + return false + } + #no_bounds_check if order == .Little { + b[0] = byte(v >> 0) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) + b[4] = byte(v >> 32) + b[5] = byte(v >> 40) + b[6] = byte(v >> 48) + b[7] = byte(v >> 56) + } else { + b[0] = byte(v >> 56) + b[1] = byte(v >> 48) + b[2] = byte(v >> 40) + b[3] = byte(v >> 32) + b[4] = byte(v >> 24) + b[5] = byte(v >> 16) + b[6] = byte(v >> 8) + b[7] = byte(v) + } + return true +} + +put_i16 :: proc(b: []byte, order: Byte_Order, v: i16) -> bool { + return put_u16(b, order, u16(v)) +} + +put_i32 :: proc(b: []byte, order: Byte_Order, v: i32) -> bool { + return put_u32(b, order, u32(v)) +} + +put_i64 :: proc(b: []byte, order: Byte_Order, v: i64) -> bool { + return put_u64(b, order, u64(v)) +} + + +put_f16 :: proc(b: []byte, order: Byte_Order, v: f16) -> bool { + return put_u16(b, order, transmute(u16)v) +} + +put_f32 :: proc(b: []byte, order: Byte_Order, v: f32) -> bool { + return put_u32(b, order, transmute(u32)v) +} + +put_f64 :: proc(b: []byte, order: Byte_Order, v: f64) -> bool { + return put_u64(b, order, transmute(u64)v) +} From daef39a206657586f14c7ffc021cfa14a675bc27 Mon Sep 17 00:00:00 2001 From: Vitaly Kravchenko Date: Fri, 13 May 2022 09:27:15 +0100 Subject: [PATCH 208/245] os_darwin.odin fixes --- core/os/os_darwin.odin | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 21e9e54f4..64e195422 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -276,7 +276,7 @@ foreign libc { @(link_name="__error") __error :: proc() -> ^int --- @(link_name="open") _unix_open :: proc(path: cstring, flags: i32, mode: u16) -> Handle --- - @(link_name="close") _unix_close :: proc(handle: Handle) --- + @(link_name="close") _unix_close :: proc(handle: Handle) -> c.int --- @(link_name="read") _unix_read :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- @(link_name="write") _unix_write :: proc(handle: Handle, buffer: rawptr, count: int) -> int --- @(link_name="lseek") _unix_lseek :: proc(fs: Handle, offset: int, whence: int) -> int --- @@ -295,13 +295,13 @@ foreign libc { @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- - - @(link_name="fcntl") _unix_fcntl :: proc(fd: Handle, cmd: c.int, buf: ^byte) -> c.int --- + + @(link_name="__fcntl") _unix__fcntl :: proc(fd: Handle, cmd: c.int, buf: ^byte) -> c.int --- @(link_name="rename") _unix_rename :: proc(old: cstring, new: cstring) -> c.int --- @(link_name="remove") _unix_remove :: proc(path: cstring) -> c.int --- - @(link_name="fchmod") _unix_fchmod :: proc(fildes: Handle, mode: u16) -> c.int --- + @(link_name="fchmod") _unix_fchmod :: proc(fd: Handle, mode: u16) -> c.int --- @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr --- @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr --- @@ -361,12 +361,12 @@ when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 { return handle, 0 } -fchmod :: proc(fildes: Handle, mode: u16) -> Errno { +fchmod :: proc(fd: Handle, mode: u16) -> Errno { return cast(Errno)_unix_fchmod(fildes, mode) } -close :: proc(fd: Handle) { - _unix_close(fd) +close :: proc(fd: Handle) -> bool { + return _unix_close(fd) == 0 } write :: proc(fd: Handle, data: []u8) -> (int, Errno) { @@ -477,12 +477,12 @@ is_dir :: proc {is_dir_path, is_dir_handle} rename :: proc(old: string, new: string) -> bool { old_cstr := strings.clone_to_cstring(old, context.temp_allocator) new_cstr := strings.clone_to_cstring(new, context.temp_allocator) - return _unix_rename(old_cstr, new_cstr) != -1 + return _unix_rename(old_cstr, new_cstr) != -1 } remove :: proc(path: string) -> bool { path_cstr := strings.clone_to_cstring(path, context.temp_allocator) - return _unix_remove(path_cstr) != -1 + return _unix_remove(path_cstr) != -1 } @private @@ -546,7 +546,7 @@ _rewinddir :: proc(dirp: Dir) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool) { result: ^Dirent rc := _unix_readdir_r(dirp, &entry, &result) - + if rc != 0 { err = Errno(get_last_error()) return @@ -586,7 +586,7 @@ _readlink :: proc(path: string) -> (string, Errno) { absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) { buf : [256]byte - res := _unix_fcntl(fd, F_GETPATH, &buf[0]) + res := _unix__fcntl(fd, F_GETPATH, &buf[0]) if res != 0 { return "", Errno(get_last_error()) } From 9e2a847ebce45cb16f3740419a07ecfd27026ca7 Mon Sep 17 00:00:00 2001 From: Vitaly Kravchenko Date: Fri, 13 May 2022 09:32:04 +0100 Subject: [PATCH 209/245] Typo fix --- core/os/os_darwin.odin | 2 +- demo.bin | Bin 0 -> 710357 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100755 demo.bin diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 64e195422..c36823e3f 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -362,7 +362,7 @@ when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 { } fchmod :: proc(fd: Handle, mode: u16) -> Errno { - return cast(Errno)_unix_fchmod(fildes, mode) + return cast(Errno)_unix_fchmod(fd, mode) } close :: proc(fd: Handle) -> bool { diff --git a/demo.bin b/demo.bin new file mode 100755 index 0000000000000000000000000000000000000000..5f8c90ed9a208aabdfee04741d4f2304c9c4a40b GIT binary patch literal 710357 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

aXk2E4CZqJkm!Fw_X0kQ}z5LGf6Lc;+ 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≪;KOZDJ|9qJ4{PR#&Ll84#Lr@lIocBJ+?GBb4YZ(d~K=D)U3|`X= z(g!YoLE#jQIqwZJ19XlPEPTR2X6=WXwUq%pzwoTy`RB9U(DDytPB7G*aOR&6f}MXp z40rzdD61hznXw@VW)5iVQ5;m3?{@h4vf3F|SA2Zw&HVF)Kl9HA%OU;)oe%N?MW47J0Z`R4;?=bsPVoqsB2Hv}DKfSfz1+x&m}%k2(7L3gccFfv$z)>VSWP+zbx zn1R`#F&!2LbFkT)(ag4nnr+Yg^8xgpn5OK8Akevcpz#SYP#A0mm1&UhbcBWHdNgy4 zq2`z~|9oKV{PUr?^Up;{Ze#(ualOM&P+t`6#(HP)nf#!2jAz*xLY}U6_z8C3a-^`; zhMK9*{PTgf^UsI+&Oe!QAax2XY~O*#(V%OUIV>3w@x2($eacX?)R})iPA-E2GQ{z`{O* z2^#jGb<6e6pf>7=iOpKd9Zt{PP7n^Unv&&Obrt zektWP1TnKB;sca#Je&Vdf7K6(gBKusr#t+7`rYB@>uTqp*{lo`y;vDOzW&Yh^VNSQ z_Og|rfX9CatJ%+mLVYTzmNA=D>-T(fd4q8(Mc27N0n7oGG zq41vR=Y!WyKOeq#`gtg~0eo*UEZu?JrUc3xpfg6FJNyKhjgq$?GyQz=oayJo$4);V zJ$L%4^Y{PsAD}w}o+Fj@)o5isXx%Po&0I9Y&j-H+CW6N5;AMS0!_S8uj8i~s8^CK( zL1hnU?JhUet)M$2`I&w`;CA}?kl*PiQ$AW*UksT8`3f2@1(o&DNM(I8D9tlWe8J2F zDeKvpem-D!`uUI@a(4B;TmPp&1=aVUwk7E9$={4WAO2_j`QZNn+Xvi@w*Nmf{`~)) z@#iaXCrDYJ&hYak=zi7rj6WZ|cKrG9z2i@%d`MZpt?B>t*P!-kI;iaqX{$decKG@F zG2_oy&l!I{_WhHRP=J^9pgSEv?fdVJhhnRs}*53h{1#087I#_bR%KGn) z;CWDZc%O!vbDr_%gVT;bAD(yonUs%N*3SXuThM&PXGcU?f0*&-i{p$xA3TQm4_wxR z-0BbUBixSNP&@WB{(P|8@#n++jz1UWBg*11{@9=D4G|aW&MO^^89stakkQaJ}PCr2>Q-J3(#) z-MbDdTS4^^=-g&!$hpJdvK};l12WehDbFp2nz@|u=Yz$LKOZi4{Ml51TGkhX+y@%R z1;r7ptOuC`T1$)UPb}xfgUmuM>k~j`f#z&MW)UjuKRf<>{N3@V&4d5bA53Qa`EWWT z{<0o)*Rnao&!^%}h&0#@^xkq#sq|4)AfI-3+!)@!4c z_4FKCPeX0JZ9 ztpDtYDC>(Ef4(YbM3nW#jz1rlJN~?S|Nry{*^ECQ<};#}^`9MoKKkzX^UQB(Sr2lL zI8vCv&M-zgzu2h=5--SQ{c=$JfX+{amG#JZ8+0FGJm`K}NASJ18-M?w4!Zy2;d6(d z50W`2!p<^nXlI-PYD<9b*|ZmAumr8~1D#u-#miu6&&puQ;mGij0n|5t@9>kOk>O(l zjLpdSk%5UJ1XN~#+UX1jlI1uU)Z{p99WFC4rq6pI%+KxXTHFHdamq)_T^a9#PThb8p!kB3% zculT3cs_0dM<~NY(4BW+F=fV|GS&a5gX(9HKOYD?{C&XB@E5)91a8;Xg4Sh$_U1MO zfz~ZN;&%M`nBVbd@_o?$NynYA`z|;ZG8QT_GK6F@Gfc<;jV&v3Pt;5W?bUVwuaO0< z-vOPM2bWLeo~W6ND*yaDq^^6w@9-DYE&JN#s1NSnuj zHr8wkx)6pgCL~1~bt7C3r0uXwBw)(D(|ZT*zf-2m#A6Lgsy+`aApt&vh+i0H1*i8@GQn z+u`Tq`3^ssLHTGh!_SA)8Ng$3;ITDOS)$JX)(2h>s1M593_o9~GyK$K1&skh`uL!= zNnD`yph$Lr+J`VZm{=Nu%I^K2{!$&JAJXOkpQ8yi{{?8=0OTi#Tg?f%^~Syb(;sv* z{CwEY@KYW%j$-fd^NF#;&!?br6f|cjkCe}wq4Tiq3_l+spZd zY=)l?^BI07GBAid^LP09*xlhLXr31qAF7Uw6JhqafY!)9`#&Aj1_aI5hJe-xgT}m= z0e-516&QM*X!&5Pk#xXb8-NmrTiRp?{#LT1!!#JX|%&nP+J#0KZ4eC zfyOTUzk$vdbNC6;4@yJeu~%p~>;t7E(AXAe?wFIo5}a549ezHX4q3z2{uMOV9lG*Q ze#pxI&8*^KDJ7Z_~`3N)y&+hQ^p)|u! z&^l2T^!0$vptXyvD<7bl37T&P=W}+3pB$YGA5RFv=T$Fw85&{cbI|&6LGao!Gq7IJ zT1U`615kW}){LX&WpMf0$uJRgClh!*syf5ZN6HRAAFDh3%&**{3ikZAiEziBj)X3`X7A#KRpyQk4Zp3D6X;Tzwq_{bXOwu zdw}O%G3`I__5XBJBJ_jSm|(Mi!`J`QRnhc&GBbSe0PXuGBK#J7{Xbol0{s)dLg#Nl z;Rjla%I)y;(ic#gc3t_unGu?vnJ@mW=D}Fg4VpuG30lhyT3-cQx2D}-`ykxm=lTG~ zDG$OKe)?7XpU%<1FcCEF%VF#AlOq(`E|GTt?J4~!4_%LsyoUUtw8PH_j~OR&K+nf_ zZDpJSTKfySBkp0m!_PW3hA9us8Gb$l%@LS8`~>YgcyZX#l7oZ6>;*_)BEv**{Uyxs zQ-hIVD`>5@JtMWDimw?*>jGV8#SRiZZLF>FI%rHBWS=6##Fx&HHUujxxV(a#$)L{w*|T8G@biJb!_SAt4nLb3A!i{4 z*ZrRkHWRe&S>E9%L**+Q1;z$jP&*ObeW3OQXnpn#P+5d0+(7k>JR<|vF#YcgYCj0C z{97%u61G0%ku<~4$My_6pMcu$pf)Pmfa>e%pgl*>eM6HSey#xR8v@0(Fy=g5 z1~UU>?@%`bWbaTv!_P^++d<>xAuIpn2e16^3@Il;<>9e% zX!-!nn?uvb0S1N;P#N>k-eKnhVTYf3U;a8BqRz`eS>Colih_(1FTmVemf5pD#dlZo0$IN7)WPIVBmUfaZBX?tCyATpxhW zd7b#*pW)~KV1}Rn!x?@W{r^Ax#bPJR2hAsK!1Wy?gBi$7ke?n#L)PAb)`NHc{Xg9Z zG^dLczM!>0pt}DFJED&SZbu(vnE1k-;im`a+&OOs&|LD*$KDPV)(Q18e_J z2b&4Hb3>azIRLUpp5Z5`9IynnQInY_a=^+uerQ>z?eLReS;x%)ZtH-`6;N9Tye11) z)`9#8ny*9mBS;KnAIy);XnwSZmUT#XSvYk;{3rqPBS=4J-i?qSLF%|6egy4Z!d0Fj z=GcTTJ_W7+1l?Dt%=q)MI^)kr+KfLR>NEai1ci~h3K{HA`hiO_ux4Gd@1bs6V!fIWIbT}@Nt9fgZmA(p#5MPA8RkaU}pTO`LSm5 zOVC+Jpn1mM3_n5l?3}1&obvKNXdQ&(&j60!OWn=Y3ncvwEhETPau+6nv4!RU!G>%`SLvD&J!@RPD9Lkah`D}$eb7F zLFRC1y@a$q;cl`=GDm^Y;pc<<3_l+{X7~v==f1;F2Hpd=Kw=ffiJSAgn@?Tp|tTF_W6_zdjzjF9ofnT!)(tY(DljrM2WsWAz(-kf!reEBsq$Ew$hL2HE=z-xw9FfeQdmAf!KZOD3<bzQfNqptVo!3_o9YGyHtj52<4oF+=x0Hyn1psAt*vqTXdEI6qah?0i`bI;Wd68x}t>H-gTq zfa?=vn5ZepFcEgX4BXyo&^({R&zH#zKVPLY{CovklLeZOV&Z_Ru8B9U^ zr=W728+6uzBX}%GQ4-R|VrF&t$;9aJ)9lv&=?^C}{(R8S_!D%G2l&1;e$c&cjz5_l z87DGII{ai1b@+KmongwuZpNPv+9CBENFC^GJceGUAIu9GCO%|lUiHu!niky|!1voE z@izpmy!n4R=&sn8&D;}TdV}QUSG{az{K@cyA^*Yt2HOX_8*Din87962?Qh=RVEbTm zgYAR$4Yn^2b4`53%(?1SFvCyHg$xs4hBN%+@P+i}4l+X1E%=^pho7(f9ez4693JXww>Lq9|LO5uRtApjMc!r&@x=mBi;U_1OK5*H| z%(3bf2!qBY%|UMGSoIRr2egO8<15fy?r(>mpuP8?_Tw9Cho5il9e%!*XZZO>8FW4$ z!_ODmpuEQY`i1#?DNWFs$L65D?wwK{f(+(hHys9*YlyqXvKW~@zEYnr)x*f}@eQ-Q zmM>$E6lk2?OY!uqY{sfjZJsdlwU&{g&`YpqR<>ZzEKNr4E)GVnE>N8c zDmOr8KLFjiC(ZB^T%Rd}`gHx#s5o>5#htA@L8||F(i1S|2uZgWH9mJ|nn|+YD+qfYx6@!U^2Q2krZ1 zWta#KPf*_r)c#|IxCOiq8q~K1kMkkgx{53i`6nQ`a>zY;PpiRo4P=kLGjx34o$=>G zcgLR(oE?8In%WQqI#+ml6;glK9drf+=w3U=pB#c*-HNOZpnCl$EDw}|(kQqO!T9rm zHRDePR)&e7a|OgeWgN(EafYAg|Nj>Ug(-5lf!%%B@uw0aS2yTBCvX^o*9LQFDct%$ z9dz!-L-3v}gqa{SK>g-dpnd7ukTK6}R)&qBc=clB*#&AJ!|%U?rnNMv-Jm=N+WYqc zDb5!0Hw0a{@qaqV-2cu(C~G+2`#*#kem(?^FT(CRgN?C*#viyHeuC}}e8tQFzUy0) z7gW}9z6OtlgZk&t{x|X%s}f^F(B>PUwkv210%`py)ZAD9QTOcrZ)UmpCtqOY-)g~? zuyK?}_6$ECJ2U)z0-B$l&am^DKf_P(n65dbzyCs?0kUVt7||b1;%*3<3bGeG&d%_0 z4QMYhXe=7EuU_8)ye<;&~GU+6>jti6&)*yqI95L9{N|8(&A2=Wd;J$XTOJ!sy5VWKB5v^)Tv-JuPcUjU6y zf#w)M_xyp!pBOn`XR$JbJoIpuNz0L?Gt|yyQkoqfqyQ{0lZ4N80&)9W(9x$=|i|S32X$AMs2pzlAfe{Nm5D z@^3Zk%KzM;y9+rlzF>El$l+)(@x_0ZpD&tqC%yokch1iG^C36u&qw^MKOd`e?R+B6 z`V+K=5PV;}H0#e7{H{M=a=ZR~sV(^Pg}&g=7utb8UobFidBF`bixb?(fAO2;=L`M7 zpB~H%Tc3)%{(Q;q3f?yl8m~bL&kf-7bd&`lV`A!pKOZRv{(P(+_|p~?p3;IpAIb~< z{Lc+KlZJER-)h&DU;JHGehYVA`6J$G<*#(dm4EV&tpJ@P@dC7m<)OpR7vEWap5SEI z@`By^fuAp#7(QrT zWS#i(yTDIQmWH60zXg7R_Ab5rFYptzPvI4_;Ln%rfGhHy!h?%^D)S;pz*NxEy_#=cD%lKi$j!Pk;5_ z<>!OXEI&CI7(TvWpD(4!&=ADQ$jRlIC;{5LZ}#G|%TI8dR#@=o3*o?@pflY)m?8d= z?_{ui@!I9*6VRFY>Rvm+=iF-t{(Ph#_>+Or{@Mcu26NDP`VXOUpm9=;4hBp0_y4C8 z6^87tKS6dp&=35%vgrTx2lrWig8TT7Ss-IdtPCGP=go6uGJNDnW(s-z+y%7%Zh}{$ z3C0|XfG~r|i~lY^Up{vE`RcyQPY2EewhXC_whF8VY#A~eZ8?M)L>@kN`T2m`VIqSA z>qHK&h9J<`|KxhcDWG)o;x^0APNs%SoDR=Ef%+ogx%t~JKQ(y}VhkP(Aun#b{Nx0Q zDZBxzJHW{hatAaPpdAP?djSi4e5sj{L=C7I6FW$#oX^7~Z4l0Y4wl z4){6uI%w~o>(3XLU4A~k4hi!I{Q^H9P8NWxWnygzl0#DWo!A?KIIsVo{`kBLIM0CWhns7UFt-4kS@i-xA2uV* z0-f*i?HZAB4~i@8Ku90zFblY?%V5}O%V64QtHH?d@x}7_QZM>BcfLH$@^b|PgW1c& zF5vlUP~5yY&GPfbX_ucb_OtxtbeI|BS-iXmB+euWp0|Xwdy)kp&pJO5aM`ad<5Gl}D zFetBKFIO&bTxFd2B3j@lxL%1D`1vS0;OFD`fS>Bu|4)AqEb#MTxBzkG%6^xhoE{xP zFBunr{gliMIR^sN)_$>>1vEYY@t-%;fBphLA9x4+eCQwWQ)wmS>?%;%37SKN`A@du z|Mb_O@ZRk5^M$nQ&r`e&L0Of;mM^!n{Cu&S<);G!gNQlb)&w(&j;E8KOgD`{8U6a}}EZ zUu<{z`DC}t&nL|+KVP&X+0o7N^Mx|ho_>~}FVqEoK2Q$$`A|LJXVNOjI4UfRpH61^ zSq=(=W|yCj_PhLi+z!dZFS#8iYC1Acd^sI-p0~iy7xDr>A4muMd?+9AGrW><%FAw- zpD+4dem-sS$?)d z!}UqH%g>k5EOcxYR z;gE28nGOx7*ZeNM=8H%>VP@bN-)C9{c}%lFjn- z)pP%!uZmfIzP!!<^TmDspAT;P|9p7g|EJPwNEiu$@^-q*&zISdx)O92|EtUVKVM$w z|Jlh7I?s($>s3C>PfpHLvoveDW-~EzzJ74o|L4Q&{y&RBc0h2i6aV3wbpYz!eUyrKTpM)I#ZNDWK(3vnd>g3hqt z4E3)(%g-0v`F}px?EmxOcK@GFYanZd;r>--`T3>n|8&rq&#*J^pDMfje4_30lM9qr zLH=FM|MSIq{+|z4`~Q5n-v4J3$PA{2pjqXh^+ql~Uue7heB=-D^UKBjKVK~8|M_6C z|IdfZ{eLoo@<1@l&lkZiKVQ_d{CrXG^7F-FmY*;BJ$Jrb?DF#^Kg-XT!Yn_*XSwl1 z{RcWH8k%1?7+Jbsu!H>uxdVDO)L--Ye?FM)|MTH||DR54A$1GPPY25WPk+Vk^793^ z%g>dp4MCoub+W=NKVPuB{(K_r^7F}WX2_a-W+ZbbL(QGe|MS6Q|DO-1`~PeLnakP` z1Tq&?);{~s3_k0oy8Qq2H@}^KzWNV3OVah{3uZ`L;5E0y#B4|AiP^9_mAmw~Mgh$=}KOgt||7^Glng{0p`LLb;Co%1{hvKf_wl}!FSkM3SLB0P^aC^SddgA|L z{-6KL`G5Ye=Kra6`2TdU+G78oFHVE@1o{7b0Xj3a+W+T^>&ys!iq;eVr}O{(pUwaC ze?I?DTadof&fxo$K<(NW>Ha@o+-CmyBHRDx3(&c)`Tjp&JZJv-qTU}~@4sT^)Z*kl zHS2YG{3dRNnV+hsiwDZfpf&+W4#ozZK?^!B4AkzMS`KNOf!em0bc-|S@)&{kKL3KRHj7P7Te>RshPI3NQ-#}AKPhgcheYC(G5Bm4te8wv^!2PAz@zB_~4rm!>zZd<%%ocJQ1|0k%8 z`XZVC=c9Q4pO2IMf8M+DfBJ)P{+|z{iA#qsHV6ECv7Z^VhIZnM!_45m!i(d~KRJ9E zJ}v<5!#nN_o(EhI%@Fby)HXj1N>dIK84g%X1f87(a_iI@#wjn|K}ra|DTWf{eMmdg%vaZ&xh>9g%!+QpuQ0YqZjB- zwL(xo@I^X1`0NqT8N8rA@{{$LZmqcTfBK7b_ni-Z^Zk7IpAWomF@w7y=!HK!_*|C^ z&^c88?BKKy%15B{dta<}{`tt?9o`@LbQx3*y8iSKbg+D3&%P5pKD3w_yl(eHD` z1f3D|P@jD#tZ%1O!#L%kzWdG>{{E1(GMgEq_JIj}&9)>c9n5wHryvLhoy$ivyt z^a4@`?I&{9faYsmz~^CVJY=;5hv!3A%NN@0pmSL!GB}t`e8}!FQ4vYcpK8V_FSOmk z^Ozv@FWDU?YCbiXsPOT;4MS;zEvQWoUf&5ihj=pRJYwgcFD5(xe9_MQ^Cjqf;$VO9 zItM2W&>CO&ogJWkX6>MR?-@R7g2s)+U4K5o5^msiYM^nW>3op%Gn?<{qv?J>AJ6vt z$qY(A{d_+kPUidh!rpx+c<&msyp{%N-!38Z+M(uk^Zk6(?)UR?x8KkAm;XI@9Inn_}mmua*6OCRDz$anNnB1&#H+%m$s)&0zi_8xqFgu{lCv z5)BQLc)p*HqWyk8j`#by3KS;6d_NzCL&6xe-xpLLg6fWxU;n3r@+5LN!P5JqWWS$} z)BS$Vx(qENRy%{^7o`4yH{Z{P{)q4aml3K=6JI#t?r|kGH$+1eyCv+W+UPcxJGea9isoJKxWT%zi%~vHSgGU}O+FyrUuL2~$H5D^tTI)`Ul&j6RDc6i~hd#SLhE2m^0}?F(VQpD(oeem+q4`w2R?nuEasyoWbXfnkaRo;(7M4^yUz zFMjhv#uoqc{(SV?_vhpPzCYDK>ESc)&xhZ6e`))1s#@_+iT(rrT^1kc7w`4XK)!0&Xdrxap%AP;-E4ETK<0o zmH(R<7(_sGY5!02{``NQ7qfgYhn5f4%s*e)Gyi;P?)>wGwe!zc_Rc?F=`(}vcwr1F zA6^MV%Ljc(8hm4nR6cOFK*|SgX!)RxT0VfvF_7C}`50dQ?uLfXe%_ytcKiN(yx;dH zXfN0zP#A6I{rPY^FSrawE+1lk;wc{v`~G}<-1p}sP&l!>g6m6AIRY*pR`dRRxSkhY zeuCo&R6Z=`g_IA=d4E1y?ECZaa^Ig#Ap2+Y{(Lx}_vaI1=bta6{eQkthU91PoC9d@ z>11fSo6h_5!DQc`52yS7e6$;~PPVi7|MZt2eV~2T;;ug#Dl>mPP-p(xAx~r;>4xT! ze%_ytx_y5>?)Uu}3vyF4@6U(rygxx}ufgsD%-c|;m5k5oh5TF?9QLACGChxNWc zo%S>YIkPnc#TA3jBys-vO4|A7OL^y?FVqov!>cm;2Y4>2nD^)Za^9aWi=laNz3>k~R+HCs}I*0Jz zoA>8`f8L*uy?uW^@%Q}++IPSQDjz{*1awZ}zccU8|L&l03;g-QnfE8C?a#prT7$#; z^P#iv&qwaQKa+p{pDw`5AOdzfR3FR^7Cwe4oM>_{?z{ZtaCE4A@!O;lrtTLn!<7F# z*v=Dgs!FHT0#T*X81yu?D#yf0`x5ENev8798c4g~Gz2lsJd z<&>B_!;}a5ygwfr^Zo?iC#UYU^CfIdo|*Y4$3e!z1E6xz-1ldPFvFG?pg3iA{`p^; z_ve3k-k&d}d4Ik%_x%Z)4}U4o`;%eoVOxfs&9)EBeSbd5{y+V}f2N-Y1R1ux`0oT> zm-6B_(@zdd=)T9_PT)IiL2YhM(Asbi-gH4$$}vhbm}Zj|o&ie0&AkQveOe z7vG&gViPq~8NhRkuy8yCK7Ubu)%FXZeMDa1JOpa%JyiDn`AFUO=k6bn_MC<)xbN~2 zq@S4a7VvsTV*Snx^*cN7&qvI@KOeLE{^S7p{Ws6ghyQs<^ZREke*cW>cjUDWApck3 z@OurJeg}>JJW}`C`H&e>UN8Ohf4Vp*&4beDeV3o0wMZ|&^ZbOT*Y`|_^!nWgkzU_B z{rvx!=jZ?DJU?GP=K1;ZyALG2KIi$#F!Qi2!`x=u2j6{uT7c5)YiN3X4Nb4lk<#mP zwDbz%Bd1poAC_LlG@p+%0F(AJm=K1;XIEjA0kHzoz z@%#PEd9=I=_4@_T-gZ!#Nn&1wr`PvR;PK0!AOBC!=4KE9jWL1eq(S|f`!0}vO=Ghy z=sfC|yLo(8gi zb>nWIpO3fu{Cu(5=O+uV!_Nob{!h2(W`N9*gT_-7R3>t;L*~d&l`~EOmy4h^L86dx zn5UqzV9;9P^Gx8f@WpW^$e7n@#5pbCwxlo9#258EkbXil&(BBoK0hBf`}}-(9x^WU z;=I$(2jx6JA6D}~)(%}}f{zV>$40I*{d{qo>F3MqPCsAVcKZ2ZKhw{bhnar9oa_Vc z*K6@X!;9VZXYaTF(;w}3f{fF4`}}-3-3Ky0{ZMJ*|9GCC|C4!s{!i!m>H7Kqba36O zt_;2p?-jelM6aiE6CFODw^4{~wgufE0B%d1cKZ3^xD$9@9A4J5HU!z8hm_|axhJQc zz~de;`A6A4KOg7&{9Jh+G^WY(^ID*6+m^X&^JUJJU;CN?(4$b1X|a2<=p@26QFHL zPT>F3MsPCsAlcKZ2Z zG1JeN%Td$ai^ZUI-_SK&;Bg|SpD$KJ`~q`}2WTH2Xe>@18a~QAKOf2a{CuqJ^HTv7 zKH@w-A4>Cp)9j!-ajAR_WsEVO1H~Fafg)dpz#Vyci^;!=CG(obU7#wC)wO z2659_9Od_J?w=3$bN^&uJ#5Rs*=+mpu=meL$Gv~1zlZE42Gt{=_BbOWLkOs@0p)=g z^PPS&GCKTZ;%f+s{qTP}Xl?p4q;eiE&+72=@p|EC|}g!FYlar6ST zW(rzAf!5f*nal*Kr~WoU#@{w`L(2GWXuj!3F3MM-r(}Oi3911q8mrPSL&~=4+&>>q z_Wt>3y7$i-E`}*D+d=L`N+VD|fYvjE(+C##9b#_?+I{x_^df9&0g2I#86`l{^b$m7V&xiHgKN+4LvSoPLWc#q$`{$!}@1OVH;YlO)h%|EL zJ(e^AlLw`de(#?zKQH+|VK>6D5EOG98Q4MbIPkfQi1er5BAOV?Qy3Vo_Hiy_%$~fgg zzV}bfjQ`UgUU%6EUb~nNQ!h4=Ljcl#Y5;{-z7u4Q$(P|Hc#bI_)J}Am$Z$XmJ||gF z$~XnIhVtcdiHRD2?Jb|@JNd0E`Z0ngPDH5yvzj|?+ypGkGOt5 zyzKS!(RDBIm^btFh9DLW#F+OocF35wtSjRb@O&A_KcM+4B>MwO8K=AqcKZ1u-0A24 z(_BCQpXd7dO4|G9t7xX5PvyOTzC6tJ^TlzlpAQau{d{=b>!;Fn$QT>Q&7k#W&3T|Z znw@?!usZyFlKy}CgLo#$dd_5~pZ_;={rtb3>*xR7T##^ZWcUaw%fMp_@lHP#K*u5O5dSM*ZwNZVhVXwI z8^r&2T^Of;?0h)gWhX=9AzOytCR=cLBnZRfL8O#%3P}FNX)nmUp+7WE69nOL$_r~)pgm;5V83DbNge7ZZLXgW)xCZ`(uVlS z`FcZ;3p2t`usB`e0*%uIVaOaLlKr zcKZ3s-3h$U?}a(2?G4%6;3dcq^1>XgoW_!;JV5K9!R;F^NI9*{_4ARu*U!hwUO!)) z`9J-EIM>gI(p*1Znmhe`W$*M8oUb??e!|+GpnZklH6)3`;5m>N(o8>J)_eVY$<73x z2LYD@pz&yVrk^kPxgc{P%1l3B2y^{>!0+|*p|ICaryC7HptIjV>oP#;@L?{fodc>1 zoPL7(SsaX<-7mzUamc_w@c}mzXbrU%?A)$L{7gTmmoQFw$nEs=5x*07jSfTOAsdB; zCL3_tSin2+fiTn0juOTx4}_h5z7U7BH~+8a{P}+~=g$}GIe)%Lht@5dIe$J}@A>o5 zW>4^Z%Hw#JosT&frhv+#C*_dx2vqjL+8W@ot4OAaFP3wH=eS<1=KT3+x#!Qvt37|t zI0HJT&FSY$d8eN*l%0M)n9uq1;bP98uj{>jzE)@Y=?XdzbUNqH7qdBkKA7(L^WkjI zpO0=p&e#O4y#$5DJWyDuL&D+#yX()#@h;%;DbSc5C|v&cbN>84ne*q1e$JmSvY~#M z%=z?`#m)9A8ayB|zzP!x5le5*)^5u2rot&MHmM?EJ@8s-tw0wD=c_-&YN6VLwnRjwd zb+ml>oOvhbOh?O?ubFpp&ULhW`JQVowm%kZ*a#%Y2d;vNS6Vxwm-~!hJusVPf zlqRk_{(QdOdFQj;&O4v(ci#Eru=CEx$DMaRI_i^UgQVop-)|?Y#5Vd*_`me>?ts@!#?1KW3+&|AIMx{t4&&`8%5P=dXCqpFfj1 zfBs14{P{hb^XIpG&Yxe4Ie&gB=luEQIQPWK|LiS4pXQ#J4x-ORm$@gVg6Qkq z6H`F+ZSIN5Ao@P{#3T^?n0sR4KYPmu^_)LHv-3H3qC7qSepbe&3kF|@u(=K$9?FVZ={;q;=K8M00V zWIw3h2bm4k69h85+8MG=1vJJFTBoAQ3|Xggw9yt^J~whro2xD{(QL^bhfPXPA^`D!k3d7f4-Q``12slO}q>rpY%iB)Q!bW z?PzYg4t3LQj-L;%d;ENO+v8`_J&2p!L2hby{Q08W@#o8aG&e!*eL30j=L^t2d#D>< zEO-3*a<${nm*tEd|B=I^A+eW!F0!;ud_k-q%r<{5zP4WRX8Ni;UWS9>(|IR& z-B4vCWLz}F2Sg#)atfXB;ZXgE&i`1xqE$Ir*pJ$}vsg=06z&xiex zcmb7T;IUwK*Pme@q3Z&$nE7b2$Ir*hJ%09p!U#0ZciHhLC=Nhn@q=cLpAXv+VF_+; zs4`7_QOyAvf2rsA`Ka3C=i_>hpEV%+i#dKiEa!mdX%1F~!iR#8@Ov8W`4iqA(+7n; zG~A3Cf4<1)`1v5)?X>f8 zzSB-ne7p+w{0X{e7G&OafUF||g%4NWsjc^)jfVLdejhfn5`j5H2eSbx517- z-^e@u1f9$CTHEpGt76BWFVsQx3yyU}(i}hk%X9pEDa`>HQ<3NR`B2*9=OcL!aJyHH zjbRGtEDlgS{}<=@35sKQ+F@t>`GOzn9&W~;FN8UMKH&HG`B2#7r_$qwphwcsv?I^7 z^IaCGd~p2vg4^-uBWb6dkL8iljxZzG+?VVeKVNWj{CvRf@$(_K$Ipi#J)p1=cKpdv znfU{BmoR93)eC9Hpa1`}|NPI)0jWoI89qJ)trrHJ8w8q1|IZFdBkT;2Gy*yof}H_9 zjcfq-zrV9X(#UW2pAWyg|9te@9h^p#AETy`XDpC@r@bTN6i{A%@!$RD3vrI055zqn zX@Z&Y=PogVY2pG0C{4U)hop(m>^~p9cmMhLv-{8flmDkbc+URw;cIsAT{EEY2Jesk z58A7aR^R@HoDT&qgFt<%`|QyAmi_00`|dvDIJ3)=VX z`155kB0XeR=KSDbc&xfbkf4=f|{Q1J) z@#o86_&MwoUxDfdXuVMN@4q;xKEc*z1FbhZed7Q07x@r>!TUDQdRPwMdb9oPKmQ+Q zhpabiyxwfO z^G?t?%AhrmZ(ck6d>!oxS&zyHtye&I#emlQJ_hy4k>(k&hZ*ENiq+6CThIRU(Q5af zkJr2ZWCMlSV)ma8m$Ux_g*|e;a^O9ldS$cw&&S){e||dw%7c(P8dPS1%B}~q*?&Hq z&knDn!EpwvS0=MV>Xqs2KOaqY|M_^j`_E@5Kd53 z@U++rO^fa9KOZ!^|9sf){Ll84_L(tpI|I=TB^nvc~0+q3#^=9`Oe!dYUGT&4~ z^G!Yb&qvknKOfh-|2znCQ!)F`hvn>$^=2URL1iiEP94x5b>w#HWwd;g4Rvci`_Bj2 z?mr*qyZ?OjtRbkGts&@8=KtxhUpxGKbs5wLb@=(>zQa#YzZ;Ye;p@$k*?;~|XaD&! znH^GgrnCQinC$-ZQ92}#TxTI6k3>V`JD&aLqiFY^kK^5cc7gmB%>MIXIQ!2RuN{7Z z&bfLCO_SjDW}tKjn&TE^umtsEpnVm{dan7-h_zw!8NvN0@Y=BXjNowt0tS?opC4US_jLQ-HbaqH#%6p>}TA`xz)k)@Fb)dI#T4^}(;e7xS_=cCOIKOb&)`1x_S!_N=( zjyvBsJMMhf?zr=9x8u$?{f;|dPj=k-YP#djm$Myrg4R+!wr2nN$e#V@LudA%58T;* ze)MMl`61cL@_o9M<-2Sv%eVPfmT!u!EMJ#fS-z^avV2)@WeF<(@SQo}0XozCqRqq? z#?X9W&i?a}vHQ=*=I%cgK=Gu_{_~+eJ5l{!Q2hb&?^6MWDGKZiW}tE&G~Nx$kKlMj zJ0}=!w=&djb@rc+l-++mR(Jo&2(nw6{pUk@_Mft#y`k3bKVK|o`1#b{9n{8y>@gOG zrgL%jpAUrHe?Am<|GDTTq+R@kS$-9J=Ktw0mP67vXbuLH#zEl$TA%lyoBij1es=Ks zoR{3}KVR^(|9r^p{__#P`%ifmhAG6Xe|iDxi)sh{eC6!^6TD9IH`~wu|Ji=N{LS|B zrMo+19nXKZpA1V6*fOkauzkVq{`19R2GCtwmpBz3fY-q-U||S(vDo3~OVHXls2Bri zALC+&pPHck{!p<5s8}a>Z$Cuu0Z^ZDvBS@kV0AB0%*$kJxWuUd5n}+&X)Sj6nF-bl z5d)uhy4d08N+dDRJ|ocGsxO$`L1!*lg3clXol^|qH-P!zds-p#l^}UtP~3p|4PZXF zj|=8I>;%b!*2+TlgZW72{{+c{;})VG%m?kK2F)LW%j<(o6JLC0`*{L%7TtHYpASB} z{e1Y{?dPM%W)tD%@_jaF8-eX7$D4+r7pHk4_XC{g-3c~BmU-ff*KFYZx-Z_d{S-+C z-2v6%RKSrdA6ULj156AFSCK$Sx=MxPbWJ4?`DJ4 zN&DG;KHBZ}^YMPSpN_}>Pk*qP?dQYoY(IlRVVquN`GT3j>H%RgY2K}0G_)dn3rcm{W72J=cCzfKOfI``^g9L%Vf5n52v&JRDhcG z(%Sv!%gGFoF_?ZdzjQO_;yZn5RYz&_-+?5BKpKyiGXTsLQ9(ehGx)Kv~ ze3%(&jyj9;6*{u92Y#!;}}z4nLo?gU)Yq1&?by@Min@(4P&p z&Ev{E@r5(gPItDSkDT3pK6ZEex$@Zm>7aZDo4b9%%(&_y=v+T*wx2KT*}!x51uyHrRsJn7!b4 z`^m`b@Uu~f0X$Fk7`lcC=8ylsS%3cj&-(M_Z`PkLx!s^;FzZhS)dRK+nhmxOncaRq zVt4!b@9qETtFhUm2({sEAK>K7saSDoy)2u&V zoM-*{;dvl@Z)x7|p&4|=r0o|_)x?hYPu`e2&Urp^MzE}*6 ztL3aeA1!wM`FOeO&s#_TPk%6*_2QTV^VM-z`26Aj$*e#BPiOu4 zVlwN`7l&OT?dj>PKOatZ{rPCR>rWOYhAA(?A^PBbJg6Vw>pQTx4>W(}eDweHU!XJ2 zLFL(FZFqUsmdiK=lm|g!2o5)Y$Q>e2f)U{c_TNE=i_YGpDCbt zjc5J&Fc~dg?HzuC&k1Zt#Oupu*PooVoU=i7Jb0cmob~7bXx5)E!dZX5sE5XLH0#fY z;jTX)MZ5m&Vq};CI$I884k#?a^OR6Oo&Nt{928$qu(%i8&H;@z_(RM|z2yIY@dQxW1lzjfG8QgmWe5S?LGxJN;pZcBhn*n5KQMOq`_SCs??YyWzn%;YL5#d7 zXFX(R_<8Cf_}rzRpgR&zFfy1wV0QS+p^zY#4ch+$N`uh*W02buNvsV)i$QUz&G7S~ zKEqFtJs|r)c0FWw_z5y&%ftWEL1zL!k%yc$iL76Vw;^aUNWU_}&xfG%|3USsyu;6j zApdha{9Jw;bS@y`uKB;!2=;$x&^ed41XV~GyHw5&F~lG zo=52nJ0FAY9Zz@I`9Ry@??ZKmzmJq1{yvs>`1?4U;qRk-hQAMs8U8*fM+)C`r0@l? zVc`p6!@?KDzR6ga$j1=!K-%HwW6(Vd=?*(VW#EHyhrbWA9sWM#X88Ls-{J2=evlmw ze?f8F2@7v=hM#$$@CM~yRtHOPcyl9#w>jjjQc#_M9A2RCb_a!5GQ&^MT~Ek%KLp)5 z$L;Vp;^F`4PmuJ3?wSCZ@fhi@2~fD39{E2VbXWHS=-H3(c;`oT$79f${h+h`r4i>} zg504Baz`-3&xhd*KQY|F@9@_QoALNEd=?*)=;UMhrR}7TyKzETNxdCQ>5^qD$*Tes(KLFj4VbAcB z6O``E9ezFpr4wm~pPb-y7qIeAzW>Vq&XBWA|5l^&;dc};b6tF(&w#k+qMTtT=w5oz z*{9&U!VYsz1kFvouxI@F!rJktCg_d@&^?Ftjz3>&L+@bGhTg#fs=xFh`2^-xaQO|| zlV;2a8M8NM{Q1b(@#kZ6$Dg3FlZ7CEK<`BO&&-8#Chd!Ihn+9=9ezHTf529uvDtpmQzd8GdqbFl>1My30-8;pczQ+=)En&zFbUCxYs< z|Gyc2o@8RU06xd^KLg|(OJ+upyMkV_GeXX>1l{Gp&j>lkQkd~4=)Q&*zZri1|IG07 z|91w^8mv`3X`r>F4nH4*+zUF#QXF)SJ!Jg+;b(`RkG?znoSFo>gP8&249k~~IUr|P zg7PEiTy|;3pD#djHo^=)HJBK-ybyK(hr{D?hn)}f9ezHvcKrFs9&{Ik{j~+4vn%Z# zem;cCRo(hO9X%{S;f#DHqJ(7?m8-W0G}!2$iWcu z6yzspx&YP1p!G0M_z`WmNB13mK7Q=*Q|>Tme$)YUe%Q~){17)kxX$qN;cbLkCf0_a z`G*kdK=-kM%zt#c5k3YB+dl#-GfrYN6MB~cERBNB4eC1de>y0ygVG!5Oj@|P=Mm;^ z!)DfThMx~lBiyIN+7MKJ2r~>pY4|~WgYAR;4nO(L7^gg72Hk(b@RLJ?;o|}|(B4jm zpB%CbA00xV?7NH~4_HFk4;eo$uz|9lGJb5Zhp;mlKx1!^F**k)h#2ztUV=MB40(KS zfhR%nhu});MXo%QJBr%6Lh#03J!aRmVh?pmmm_iCftP@GBAsr%?$=h&=GXdfc2U&<% zCz99$sMty*u?9Jax|2v^4Dt}Mmq=m@pkkbSNOmYd)M+A#9e|2?B8w?P)MX-xEl`4p zb%MkiAZ|`jhKQ|15@S$>h@C_dgQX=+P}(>E(F;p2n#>KCI3Ga74)8$qz68ZDR4f5> zjvuqbPfn2EpkfSs5OtbJVhf;Ro=9R2;Qh%CKRZG8LdSy_m_zg;j~gc#Ld1~AjTab0 z#XxR>>P^ssh#`*~FVKOAWrEWhWPI5HnlDx&i8a_k)V)L!JKz8j(*&n0h~5X#G@gkh z#^44~w-QP00O-71P#XeCOu-wXP7|EgAm%yvLBukV#1f$S<0Us}PdY?h0%%`1v%^nM zkoyim#6V%Nh>1Z2RQ^ALmc=i2gZf8^^IaGj8HCDi{+~XN2z5C(|4*NSU0o$?od?Lg zq?`YzcVSnz6Iorv&HvLIu&V>F!2+G71v1a?=KtwsObjBRdKXsTfcya(UwIJSVEb^h z!_Ph>}m zP?7_k6$nyy_}>5Nf!Njk<=|)t0;$<`@BefU>}pW#+;H#zbUWhlZeK9V3v>|tRf$r{m5bW^xVYtKJN6`*{AIF3GACNSi{^$Sn$)Is^(0##3 zWeOu>gC%IM3KJuP5a{mF$IKjB=C}V(@4%v#gVDhf6tqKEu%faZd6UA(( z`oFjSPxr&39<+ZDZZ=0l5GYJO-TFV>8HZYUctF)Yzx98*1rD|7=H9vWf4VLXwdm$v zy!C&&5|L_;-TFUW95jz&55CI*+}4Mez3L6Npu7DZ`8)g+dH8=iFP3x#3WFaH|4(Ow zngMPL?}ps{gWh*q&C4+50kr=L8XE?+!JnX}F^qID@7Dk6??LB>qoqe&>0r{W|I;61 zQI9PhwBPza{RS4bxY9xOt^d={U{MbW1N8VRxb=VfK^$t)<16*n|LNPXs0H~ERHk#* z3IxAk=G0=eb(jpd2b%7~ZvCIWoH)Ipd*igg`4Otu{nr2KGqCI3$;o*j3T$UBlAX}} zV0r8R^e!CwK<>qshjecJpI(by&ri@DaBzP?^9JaCn?gM5(Zf*W*8l0LptBn69ezGV zN>iZnl~HDa9|Ma-oFYToJSK*;c_6!(LFJeL<^?$lM znf8Lxwgr)T(e3TO^?y2OJp;O%85s}QD#$GKQ)H2d(_l!O2MSvbkiU5k+(P$v-L3!A zC9v3!&kS^TgR*T3eG&k?9={l28{!Au6)4Hu=61|!_P(HM+Xu!DpfOhPo${c&<)2tP`~;OhLZ?9E zt)46YH#33n@1d6arW0@<50UN*z;GY*-gI_`pBUjM?(p-8umgA;1T-G;5;P|Onom(@ z`1x3x;pY>12GBX(6BwpC?0l%~@bi&6o1Y^~uVZHAwmX^d0AcSnmm`~>A?(EU)4qaA*>IWSIn0Gbm4-zf+2 z%OhuopWjm%r#$p`*a^Bj{f)cB&)41#KVQvv*!dDP7Z>jE^KHJv&$SO3C%(02`1zLE z@#kB8hM#ZQ9e=(x2JzV@zBOm~`Q|Xg&)3Hpex7D)2zou4ap$Y)p!-r8e!jTO@biH) z>%<543_l;IGEM=Hc^ZS~kbb@Zm2J@uKNCRivIgG;4K7D6r!r1?TkY@@n_HelJN$f? z@9^^+Bjdz(@eDuLu`+yIaCH8xhs=&YAF(_Be7u-t;+yFVKVQ#g`1u;-7Hh_xuk0Cj zzFf=zUQ77GnPuYtZib)#`x$=zpUm(x!+~+i>wJfw;QJes9ezG=KVX|6*kB8~yD#e@ zgC+RBXV5wa(EXC2yCJi|=cP>q-;rP!v=;2BA_*&s~$0POqBiqfBMUO zho3Lv9e#qwELi}PT&BgiDqbeXlMBOpxNQ)!*++C zNt_Kq%uEeIm*W0Ue*h|TKzG{lJN#6r)c66qWBktl|Kk4-gYJX^-2rt7dx`PJGDBH1Uly!_U|53_rEGKxu?w=d0-qJ3;qHg3`B&1LKsJ zpmBX^(3%&tJZSC!8s^NPJKR9yFr2TwKSFIWvBSpP$h0=5q$w#{!D>`1#bB;pa2Z zd@86sGI#h1iu+ffJH+k`<HZe%`T%xQ8>50X*jfT37r+n&BsC{`0lC!%rSo zhKZSf<4@Q#a=cDtU}DW8af0qgWoG!vA?g6W z!|??u4>1#A20Oz~kQtB69e#q$0mUz<4GQWX_~|iDd1&qcy7%j+f*#`()HDhz8@N}# zP-po00M@?KcKG>F-vJWd@(e#^LE#NrQv<5Yl)-bUKTmKlY;)mIa4F;mo%ZTtBNb`~=m>pmOQ~ zGbHVDK-&?LAUo9^euB~}L&HIv2g(h$pgnn@d+b2!LG?B`ABZ#j+^)+w<)OO6&&Qzh zOxfWl!$Zc2k8qS<9g+<}FVM>`SJsIykjgJDP&!t2_{n*YVIn9^a!7*G5(79ry_O~- zKICEX;qVijj=7=f7_{bxA5s_aurlCJ7yL+OfYJphF9>4f1^i|}^8zTm9*8^qOa{k= z-^%}oVQ~TK7jc2t$2*53Gx`ju<3_l+n=9u`v9Xt=M1sV$m-wOgV+uh;kqGZM?2N)Pk9x%(V`rnK? zKM&TY&G1u^p&@8?GUF7`x-t$1hC)!8^Iw?p=YMg=pAUr{e?Ag-{Q3AX`$SDO3_D-)GwlScPi313TEq7eG>6X6 z5cJZX;pa>w&klqLU3_s1$!+kfy&;R=wem>mo@bl4rho6s?SrOq5x{Gx=!%t37 zxP$84)eJv7xf_CBMl(Xf-JD_P%XmgaxXUyA1m9H;3U^SuXgefKPK5oR4yyYeGP6$n zznI~ta5CeRx55rT--tW>d~NQq^A%{lm9oQ6l(3)8@bmwChMx~-JN$e!ALK5UiErB( ze!l5u`1yvrA?S@XDF-EpTXD2%)rc0Oo#+$o>TIOPTCj$Bax zgOOnihz&X``2c7QnZLtN4o-%Tp!H-N3=ATmv5Xhq4m&wm83bQAL-ugJ@ORh=VuQmE z)Nf^Go%ksUE$!Ab{QTbx>7PAncKG?&nHdp=+0gLIX8_HU2EBaD013P242WKOJPWPU}j!*h>2l>Q-H+8t4WMg7}yw0UVzrHay$Iw zDg~Xp;qX(Nnc+irBkRQ1;S4{y*&BjhM>G8F=4}Xiy_;cYHbX-`Kn!D>?3CcaK) z`1u+n2D+EtoAKvMf5x943=CU^L2EKW`$L&Qcjq!}K z=A8K7p7G~@XU3oZ-5J68`6;vfsz=PMs~$76u6nkZX`%w7{WVaSO-%x=UBF%z^nv7@ z9e$#h6aSkr`~9HyGN+@1r6wbT5vL=AC4(ZvL?azgordT?|957%2&y+hZ4}U%8ytV{ zb8s-q3313W6oKX&L22Z_Gjz-V)_3P;_}P`jI0e+c1dZi3CNWNFU|=vq9)|$Qfy@K9 zg+XRk$_c#?X4uKWC~x#aoMGonafh9+gdKK*`WJ7RxwPIfb82<`jpvYO)XfI9uloLS zb9DdzZ^|vpAoQAJH0_^ z!5o@CTG=MPmS_0M&Daq1TAAVJD^U4s4oMH-^Z~lpm>t3grw?|ApU*+-Z$NDjPQb&RM0I)V1sP6#YuMTRv*@F9H9~D9O5`pTs!weHSpy#$cNo1S? zYPW#mlZk;rgawr5L46ouhM({L{}%_X=|r~UzccH_Kl#Ed|5l5D`%a*7i_;L zUOd9vZO;4`UtDMS`QSFg&xiLJem;84@bmF=hMzB1FZGwy5!)lbJAe!e>G@bkrGho2mOoiD%G&hYcqZje0;;4%ZWR}`kc z5?MXyjGg5SKSBGd!Dk7rXZZPIGsDl9+Z}$sTJG@k^=gNoFV;K!e6!i%CuqD5v@i4Z ze1@N|7K7SjoUfCZ8A4tzb^!0$1g{x*&iM1ib4SSC%#Rs=zI=@4&vwS0ksyCgclZg~ z_xO4-cntHWmm!BTnrOI;~B4)GyHtDn&Ib5sCz(TXrO(eAiF?&zhCSJjafSU ze6`!*=ga*LKVP;p{Cw5T@bgta19KT5%Y-ae`!Ng(q613N<9BfzRi+uLV7y0g$nv4#WFSFSzUuL^kawtOTHJDwX zc_+9YPKJq^oD36R)-(JB?I{Gs;mdl5pRbx7e!c?lmty$o!N_0+-ZzyGw!>1B5wyk$ z)l6mv1`${szi4;d`C>lf&KL6?LG^4AsDI(1!(ay9zXRIClAAAWqUn(6Ems+6v zDv}+3J_U`Rg3g|bXZXnh+LLq8U?S*zDe%~LJLAs>&5l1Gwmbf8a%c#8%+wGxCG!9D zm(YDsp#3(W^$#444226p?aO3v9W)U%4*D2$=3lbI&u7yee?9|^)5FZJW`vBZ*E9Zn zQ0@5hVZGzeM-B}^%!~~|Pnp?P`A7Yq{t9G%G${N*X^X3ygOTg?%VNf#FUlEzKG+S( ztDv*8KAa5WA6~@P+z(DbQMfP#r4>%6HQpcD~?m2m-ZpUbN4b(yV1FeAzxj0zu7bVd^+6`5s%4?kg!f?{P`f+@#n*I$DfCsAz`fq^PfG!e;~gtWMT+;;tbl? z>-ZBiHi2SZG}OF!#-9(O9e+NIhnNRS7knV|K>Dna%IO%J>tsCjWu8Q$;kcsl`-Sbm!SD2&^*%V23zo6H&7c7)Yk*$AJF(4Bj;-^Hii(; zo|mV}(6Ew5%0Jprzvwgme4y?4^P#@u&qXef{BtDY|8&r}H)w1Uo_{(S3KxL#BWN5K z6pzAa;iC*SPo44S17*jb57ixi9&%|2Qf6!j+5j?77&J}<8l&gv29*_>g^Y!uc>wTQ ze|c!0gtjTcX~>-6CwQ+Es2>VSFN~b8L1`%zlm_J;KzqR_KH)}l12e%qTSJgDQ$vs=C=Gzd`9X7=pnYDT`jngT=M#R$pAXs(*goio#t%Q} z{2S0&RE$3#FgyNy$nN-4$qf-dexSGpjq`x^s7*#H1Aa67d;ywgtA~^U4`w_5d^q3n z=c8c9pO3>Ge=__2pPsJO1=y1=mdaK0mh z<$q^>l>HfR{{9z77yA#JBY@6HfaexgI#@D*?yi?-*x3QP-%A)2XP|Zd3_n5Qp#J*< zd4`>!y!jLqE+Bc(nmu-;G$#$6uat-E*Lf)K@KY(MAt;#>wC+QGm0ASo%u2|72B?1( z%EB-OWaa~Thn;_`k>>|Ma~P~R=d5Alr#uV{Q$YK&K=T|gLHlqXJ6OI1%~dRBumtrN zK=UT3bM5RG|K!W8{97%%6130xVKoDIPvQ$uJy;E@XB~dR#)DqmcKG@7K4{(-x__qF z;im>8!`AZ?z<#~pmoDB>UHEkV!YH>1re3cH`8`KcwCCTvd<#mRgFY+0F zW<)TAfa>G7=?*{7FfmN%5j2~~#n2GM!N4HUUAcA#=q#&O*BN%c%mUqn4uBteWJ1T^P}yzjt493qCi?;rsxhO+NK5~2=e-+>5340+#y0#t7& zXuUM_oDv2Js5&Gu1*jPEz5@rS81lY@1kfF*@eV(c_Z={R*8j&l{6yJz02M>tcklpo z9(26JPvm_E4@4nuLEd-Z0J8&WJ-h>G%{|Btq;pgpI3aqG*TW~k#E{m*H-PpX$D^L3 zvH&WEydFM52x1<}dU&W9@_P6MP%-57@CTsbjJzH`0UCbD>){_j#a<$){`WGlU!mmBZlne}knaXq;?4!%ol~@KJ<#C9*iEetiK^zY|$}CtSV5 zPh|1UP;tf!BCsYo7Z6t@S!zARm0pF(uj(-R68h2zl(3(4#y`c5%$a3H_gibsB1li5N zA`u5l1L$fraJykLvRQHnb@26+9JLN8YD5ugexlpM2bII;7H}JxS$-904*exGPrO|3 zuoHBS1g!iHW@Hfgf0*GXxGWB4_=&u)X?U^&SB z37nw&6Al_o1ob~xvNZ&~M4B@IjjKK`Z3tpvYzTVB4LY~+#ixrpj8k4TH$vhZT9+7r z`X-?Iq0zze#eP;xkeiVARJ{Q0igc!G@~RI%xXc5cqXo4Wyk7{HI?%W>R2^vU>mx38 zDB%iq^UHFFouGL)Sh!9CxeXMq<_tfP_rrnC8UxMKf%?m*`5G>9H$3?^%7c$3`1KpbnZd+Po%7Meh9w}U)=7Hu- zKyxcFw}8%=0+|6C>jQ_2JLFuZ2cW$>-ALiX&ae|Sb`N(?Kc*bqJ(Drz!0rL<1A>Js z)I87}3~25M=AM`8(6z|WaD8#zVJB$K9BAC@g))mJYz^GsYSec3f7m)&euke9g&BT6 z0`)aPXN&NI_JcG01g%vDt!DtO!+gMh!1jS~gDq%%7-;?id5>-asQt%{b_O44&m}kN z8GH;-G30i!0yjelXdN(e8~6ceA11fMPn5m4P%-2-FiahC8~6aIZN`n-28M|tw}Ihe zNNv^!p!O-Z!%yTkD_jgzra|{tCa^=?jJ$^vCWhQ*Z2+AG!|m`BrOgTzLvFLe)FHQ7 zVPT5WX60cBc?s%AGRv=8CD3q*OX0;QO-8QQpfsky!w`}JI?D)j-h{HlPuB?0nQRO{ z-!@Ap92;b#(54AjPfiDg5@ypi;lLd8J&5~i*mD&~l!t^+D& zgCsT)DrSx(HXABtge0~EDh4XwVRo#Aih;^InAmox7^r-Qi5-B7f$B||*h#1usCf{KCe+k}aIhl+v9cbFJsBqZ!X>r7Gl(y+N)(EL1T4I?{z zu22hkE)_h##_sU*)sO$vL2F|`XNz%w=HECOJ~o2JFhT2AnH_#=IyzLov}dRU*XOJZ zA3@{Cpf(P&Sr3@yQOy2Nq8m>B_&=S)$KfXjFT{LMJBE{ylj~(YgC)9Mq?)}6X0|Hz z&7KW2TbBA}x4_KSrM}s@FtbC6F&i}I!-g{E1KXzpTE_w^SHb%$Kx4D|3_m@5|4)Am zIx_>bmK}5!2WX9vzQa%Om=N@=pO>I?7`uT+0VPZ>yz(mhYp!>%Ke?DXu`uT!6W#^0cJUd@7F_^q~@3ZqIf6&jD z-vxiZ_^iD1#rMFUFY?)bzW5#Z^F=Y+&lmk};JLb&{cb;B@dy3XU<8eOb9HMlg7z`E z{d|z`205$uumH-K;0ykspD*4E{`~(~dFPAwfj?iQv;BPWIq>HT&>5Ea%*=NC`5+yK zncZ%X`wrsSAZG=F@^CWSPmWB6j~*>dA+M9&Abkr)bBw;l!+1B)y3~mb3ViVO0yiQV zryz&pqvL@;AD<3{huNQv|EE9LFZlD}VZom-nv-|F*bWV|?a(mWF8K3BvGUFr+XH{T z2xj~FVt3%r7vTiLEZptqgJA6b`zXvH0*Z4^M~BK+i+Lw{{P*dp)$7_+qsnB%Q1m{P}2g;LpeF5q{ne^7CTB zpAVM{{(Rw`yz|9$sGp}p{XARn=L>7)oiAnw{sf)#`C@+H&lm0l{Os=b^MNyVKmP;m z2SiQF7dSrJOnfm}@Mi~T4tcuZ&qtF3e?Fd$aN{(P8@mO6KI|9#`9eB*=Zku%8|$HN zY!>|af?Ij#i{`+eFU&z_vIhQq0Xk486AC=+m>vfIxG^4Q%6 zN{8UI4K6<#f|zPKXT#h9S~CsWXALW>?t#KCTJYz?c)_19b|>w8VGa#DbEw;b1%JL+ zt+ew+aNy4u!fZcZga`h7Ax^+;;-K;pyW3uX!fm0K#;U*I&qv;YKOg%e(!wiH_&N*zeCRIt^F?>k z&KJ^9|42jqV=egeMYYn-7uJD4U$BGD!wvlTf}4PUxZQp}V8`ws&>m7yc*DXM?8dEZ z6JHoZ-DocO^O14j&&TEnHy#AJQCslmLw&)YFQSunzF>#CksazrWl(vbwDW~>;LjJo zS%1Dz5B&M!KP&$F;lJz82ftmh)(_i+7(|fW$N{<+TGe*q3vp<^mlpi_NIdZ8V`+pN zXMo(uFZlDJu;9-Z%1Jw4yyu42Vcw8Bj9u{O3t^?5FW3WrzIf02^96U{&ljHwxbd^= z&j;_ZyRlb@K?Ia%URJw->tc>Z2TKh_R!dm89^z>Tg5{w<>;F%GaGe{Hhpt22^IPEO zi{FYnU;GaE`QkC_&lmp#e!h54z&+1he?EAO-94c2A~p~4g7VO3fu9e*3;cZXI&tTV z{m`)54|UsXfuApKEAD*pI^gGv>#RRtybt*K;x+-d-FE%?;5v4ku9 z+#8XHKx|_2&|?8e9(peD^U>pgpO2ph!0Td3P~6`Z`1$a@z|R-E6L-E?4E4`qsDCaC z{Cu%map#N60Y6`W&L6%W@DqFnF}^bYyz9>gr?LA7XC68Yb>n$~pN~!l{Cs>K;l>Z3 zG;mnp=fmRyKVNhw?tIY?bz?u&jk^VYzNl8*`C@m#&lmeyf4sd)<77zQ;UuEmPXNX7bb+4_XAAs% zVVt=0MLg7P@ldz*3;cYcthn<V`=e?FLv-HoK=c>z%PWefa#m=DU^2|HitL*1qibz8E)&ljf^cD_gs z`1zur_2-N90LVGf`0~hP*PjpivAfMxkU<2L?_YMi{nTu9u;gT9ump`ed$2N?f!qx% zC&Bg4LAHr6!lCIhTHxoS@PMC>qY>e%2ntt!fu9e91%AF*oUrqSIMnUpP`A4a{CqK4 zVdo3?fS)g#S%1Fp4*2<^oj|y@yZ(I8jNR?%`5RpSwAxO5VK4CW1gPEVEb#M@eZbGh z&ImXDSoeSW19O3&53L1$z9>%E`Qkqpr2hHu1*w1Z1%AFrR@nJMKj0_$oNMENpD(Hj zxUt&x=Yw+WZhR{M=?{SV0Lb$Oj;t8%`U@NjZ704^7J#&w)dhY&QV#g}SRLW^lOVTC z3;cX2FYxn)b;8aU&!KLA4t2Y*z|R-j3Oip22mE}I&HD3&c)-sW`2^ga@A~sWHg>mz z&d&hVov<|Egj81=g4}YR3sP5}huY6A@biVV!p;}m0Y6{Fv;KU+AMo=;gYua3}11u^k#V+o5jz&HwYoZ~2`se*6D?5e%xw{UPUW zh1qldpATR2|9o*d ze&>t%P&dwpy74~$&liW~cfPpq|MP`A>(3XD{eQjyozsoajoz+5AGl+8qaQXm9<`nL z;xa!Ze_ZGP`RKC$&&SshZZrV7@ihO>hv)f!zL*`q^F=$RxrIdz1NpzBnzn^F^}%&llXFI??~<3w{Fb<#+x0 zfE&Ae!Qobo8E*f7{h$6In*Zm+c>bR+cE{~}!4Gu@Khzz;{6Al;mfQIv*#GB?|13XW zg!}(|!A!s%%&tEl{CC0Hzlwu}TfE!Pm-TKxUv;}d?*Dw+47p3j8!a3~?Iymk=7-cD z_WVB|S^NKdY>x;>OHeo(^Z$Hk&j0g8cHGVv-#H<5-*-<)-KWj}^F_4W&KKJLKVN)i z`T0WM|L2SEEcp9}-(7w__>A5CFPyRFij<+Df|C?td4LeKggZZ z{68Pc^Z$Hd9k=tveW*L{L)|IN|MP{m+|C!m{y$$lXZiU;-2dl`*96@8+U4hi=h)r( z2t3E?_LJcWLq5aNW?P1n&9)%7zqro=8LNEE0y-0BB7=iDcrOub-}n9y#wnnC;lT40 zo{;;iLGc64{e1Y?@8_fEe&D^U&SnikOPCshSeY6wu_iqF^bC6UNt_Df6p(qK zvWQ{lVOy~K_Z|lO0jX^Iz;Tg%;)~mSkh1AM-_J+4{eC{a?+34&Hm&(T{lR6vpAWC| z{d}=HcIS)j&@kT)4fE4{KVQt2-TC6Q-_IA9S$@7a@Avb?bpm02-R0+l%h2`T6p+%g-0*U4DYs{2pfk-|x`{nm0V|^7AFL|4+@zj2|x#gTxs=>SDH? zHgJIM=Qzv^WlEJpD(IocfP2H`mY}9zs-CDZzWe!q`h(ScKOe5=`}ra| zcIS(9s5{c3?pVzC^M$wU&KHaQe!f`E^7F-Vzn?GG6L80Rm!A(-V|T}k+@?FJ4eg<) zpD(0kcfRQM`}tx%$c=tKUn~aEc;*`xyZn4GABS7r{eNa~GHd~*Wu&ybfy2{o;)`ZJ zNV(R|_w!M+-_OVG2zN4r+*!@{^I<*T&lkUAcD^u&y3-u$&SJiwFJ8;+d{ON8^TlMA zpD)V&e!iGaz@5`wem3%<7bQ5q#x6985?bzLMjh8_LRNlObhxE@GI1fPYwKtlmklSqQ z04jG1n{C1SW9wOda1e`CI%|IPV+g3p=BX8HLdpXKMvY?q%e@}Xr$I;d>me7y>^hB@5@ zQeQ^<{dA~&VWSY)Y|8<=ll7>I%emK z<52$|hx%6-ls9B{z7Y2N`63!r7y12s5l_Is@h(3fL}T~wlXRD#FM|Dkz6fUd`83=Q zGB3!;KJf)N-_H!ThM*Vxd_Ny>`~7^#@As3*vLUFMsUaxJ=l}GVV0|u-yP?BDb+;dQ zZB{QQYCrRlw%^ak`UwA-fc(eI_wyk;-_IA^F*{$(hx%_m)PKKuf4=xFz4OIy-=8ns zS$@9w@B8zGHv#{7yZn6Mj@^G4c{@>m;)~C`kaGJw@6Sh{eSbdw?hCJ%ctGxZ&HMA= zd)}WfZb$EY(GGQAJJfxTd4Ik*Exq%_W8a@ItXY1(c<%f2g*^fH*}MFFV2#~<;Jh7< zS#CFg)+OBL{rT`d@6Q*zqj$c@hq@yl>W<62KVPht-udFP@6Q+dEI(gd_x<_8n1DNs zU4A~$$L@|7p!m#Z`RNYYTgC2)Ew4h#@6)`HI{iHF&qt?ye?C5s2)n(j{!f2!nD^(y zcK3tQ=A+HNa5sX+50U4z zG(l;xoA>9#e%_xiq@#DfP=~rl9qOKD-k&eHrFXt)_Wk*So8{+=cHf^b_zAd&-{t26 zZrtucss}G{JY<;oq8b`r^}IhHRr~&YT#pDZM^Jbb^ZtBT&inJl>!_VC_@VCOhq^Bt zl!v5tzR33d`QktG&lmZ=KVL8ta38bF&j6Doe~`@k^IadvCopO4Iae?GQGgy-9p z|EE9D=l%K6nD^(4pGZ)M(}kK}!SK2}D!?Ew>W=kLcl_u1`GQ$$=ZpV7KVO_@{`rF0_veet1l)1i`R9Z4*xi8^P8-1a;yVwd z9Q@7m^U-&opO1h0!0V7|P&mEk`T6iO&(9Z+BX_=-4t3vjsQaGt{Csg)a_5WZK0jX^ zX8!r&wa?EN#|gOaxbx2khq1d498UI_;q?C7|LG6z^Zb1HnCIt~{Y7U^{kq_;Ewa<9fHBpz(bLPSBmwO}0pB zYywBE-NYA%c_4QkALse`=&;Yv$Hx(2rvnPR-8?@Z?&taWqB?Tti*%@))1hwO%=7a_ zw&czin|*%1Sk3(N#de>cFV+)q^Lpo>4_0G$GdS!{`@qX!Sedc_6n3k5em-2!^YcY? zJioi7&q{CqK=`R9w}K0jY9Cg6_6&OaZ_$L@~*Tv)8&Zy1AL>=L>Gh zoiCbwe!iH@{PRV-&(9ar3AlN>^Unv9vAY=@cC#_VE)W!U)jU5R*7N*)@jGJY3wfwJ zn=9hO?(l~1L@mE^Za}i?(_3;G$IUpKw;?5^YdXa&(9Z&BX+)Ehq|2|>UMXYpD!j$ z?0n(w^YcYD^UoLFK0ja76L5RI^Unv>*xe2e!+6XvWB`SsJ{a^o2f1u9u z^Px7+&lkZFJ74UFhQWTQJLGwOzHpY<`9j|3=ZkRWpD&bse!hq%;ErhLpAW*ZyF(5+ z9Wltm&)&K1&p72py8^gg=VW9k1n-TJb(r)bm>IlgS3{Q}j)D; zcQBxig-qZ$YB%x4ZEncDcK5k|KDzDw^YMLecpdTz6z-R~e?Gj<{qx1@@SQK_L;XG< z>i5&!KVQri-}&OS_sDC4w)oB$o4tR&&;+&^DLhwpq54h@5Fs5=&O|9s&szVpRm@1HM}L3M)n z&lllPX39JNd?1b8Oi(<- z!WCQ|-UZbu+>rUX>D)gbP4@ozcse2-dVs>aoBQX(e(s+yq{DZ<(1-e2AL{33?w>EX z#dp4F_Wt>TA5^D!|9l}#zjFCPQV@P&OaY8V|NEQ?6bLl{=Y4@^F_Az&lkU$ ze!j@}{`ulR6aId~f2W@hemi09zhH#@PrHdPlDU6^&+1L*{`n}``{(0yMA*Mv2Acoj z{`oMT`{#?@VLM;EXNA@Qu8=w)7*sZh?R*jJ{qx0prk^juy??&=Ou&7goqj%ekKKK^ z!af!h_TJn-ANqsJoUolQu0!2%9qJBeP?;dM^M$kb&liuGe!g(`{`ulL0e3ui`uX57 zc6Wfo-kSU8|7x+FFRZ~&p zkBq&4J~l^$eHSR~wYh&j)CcADu$?c~L;buS>Stw8UKiW>LfQN0i}OrBU#NTkd~un8 z`z|~Ed~hDS`(C(1>K82i#t9sO_7h)7bN>Y0xAa1u`{yHR@1Kw55pInKxmB3^=RuAeV{hwgk)4|Quj)UBVne!h4uy7R?n zub(frGyQz=-RtLz-2~ja+v(?n?Ks@(4{eky_KVR$?-TC6S*UuNLnSQ>w@AdP=dID}; z@AUJ*YV2+WxeqjF&BW>e?~j1$V&pNQB_KCl=KA^YI@iw^t3!9b@Q1p|AL^#lTt8pT z7Tx*cwAarU^O=6WIPdlI#bN?(TI}@m!F=p)0+k7{`hp2`?+zRJOXlDBPvfk*wS32)DR`+|teU^I<>N&ll36 zJ6~Lfy5&05EzMj%UvP`=e9`Rn^F=b#&ll}pKVPI1a7((=&j-nb-2x6P(Aa%7G_2~m zem<)9`uVsX;XYZA`--`KJ}d{7At5_o?1#E+bAbtK$KS6nmsWS5iEWBZTuEtNGdY|j(!+22n60-Bfa;QI+L;Vp9 z%KIWaUj%#oeBlnN_q~3;@Fw67Z>OIR+_C%P1;{;Qk?&`g;S%L-vU;grW6}IM>fd!d^cg zizD2c4{|Fv*UyLipnMgw^F=t+t>I9&GK2D!$j%qcUO!(bGyQzQ?)CG9Isvz;JNqhybj*^!XD~Y zd#GDqbN+mBTX^S-*PcILh%^0s@!s?23uyvwm3I31KpeYULFEylI`KZpO^-Q$K77vk z^Tp}loiEg(Zc>N3={D!j7rTXbzPRoA^947kp7#9tf}en!_?><};KuGIP`-ubS>!sg zV=?FqU}zrUhuVFa^XH4z!aHAF_Wb$cKjY6A*FAr}U?yNUv(wK9{~fXRA&~7xt`jps zc7JDv^Ie$Lf&-wF3b?{E`*`=WUX8WQ3+syg%MYizH7n?nQzPQf# z^Tl@0pD%6`@ZW96pAW8M_a7*1A3b)2x4mHHvFu0C8XC@@57%@4d=VYI^Tl#zNFBT! z>W;;nKVNtY?|iY?^XCiDdAG|w!Drs$U88#5@#lln*xdm-Hx?AWpfxlgH^I^xa(VoA z(f{cW`l0dN4|T_E&Yv%=g?GM~?fLV?e#W0K=6n8pahO1O9CrNqU_W+uM6n{3#|k{~ zaaD0|)bbcSj=;+>@kKo+WIU^x^XH>_&!3N*5pih-ipz4&pAV}!f4=w}wDUzdGz`n3 zZqMiZ`QowA&KLQfKVNKS{Q08T^XH501l+#e@#llh*xe2aw@2-s7;(Ak!~f|I(m8)V z%;x<0;&RZ=7x7Sc#6#T?&-wGkVWFKb;yr)9SkCzKMY8A57of9^@vVto?fCP-a_sH^ zm0z&<1Ba6;=nPY6nvdrE`6%4;=i_KZIK2VIt3T(@hrygbUn~yV`NAFQK6j}5+&O=~ zm@KsOg}dj^7qc0EzVP<^2|A}4Z(5u0_!D#<VER<7R>($4MngtT+-HsEjPYD4|4 z&-wF_w&%~s`Uroo1NmE-^XEf#P+kh!`9d7(Z*i!pm1J>r~UPD;s5Cmo-;wp_vcV|FmwKV z!7a4&1+(YR7uldQLp^`K$S2^Ad`IwkzSzPfjs>Y-K4XAT@h71#5 zyyk$6OT6d!`RKLB&&TgQ;B5sF`1xYD;LaDf zJ$}B3XZ-o%zQ@lO$pqY=?D+FRJoa#W2x_~2_V`)z{{M8)+E)%ng=_}Ung396DJ1a& zEDRx_GlszB#AgqTa$>=I(E3!4pAWBd{Cu%GaOaEdP`7V~y8SfA&lj@=cfL67@$*G6 zsBZQ6`68Tv+ru4yJ_yF{_NNRCA|=p$!Y_V%`~M!kY2ti{&2R^N8`5VfKzcA6Vmd-;4kF!)zxgEzain`EWkR&llE#J745O z-INb?(`1gHFSG@BzL@Os^MyXB-1GSP!k9pq89V-bppV^6;5&;!d*^>6(iZwyjv>fR z-5ft3_H+DvAsx8$ML5(=;ZQdw0rz~p-#X}>W<)Zkg?@& z_W1d@9ube8pm;3i`1!D$|q9S-=qJy!|N%?J;@wDAEtxKlYpHs)S>QC zhq@;kRGtXzd=c&O^948K&lm9?KVR?@a1X!Z&j;Mt-SgtR2gdqfaJVHhOneax4YzQP zpO1n)em)LIgxl{0ptBJ;em?XEl@S3uU+_cS$q#j>GbrB*?0n(u0Y0<&g}cYk7t93Q z$?W*^!G8yweS$~d5#a`Fx8}e5KmCC<$IplMpzft@dyJ$}9b-POhJ z0lu#bZy9#q;pcHWL*4V4{pX9< z{5xNKcK`X}Jj2fy-`&A?+2VE2Wrv@j^PowI%k%R=d&;13IUQ>EYxbWnZu9Sa@!I|8 z3()zZ@7;gCI8GoP9e4Qo;4t>E0Hvcx(ulBtrRUvm|4)DLnEmI&=j=aUoc7=Oq8=Is z^-y=*X8-wOH~-ETx7~k&?)`Xi-~H!{-2~jR+u`Sf?bzKR1xr)N>zQ;BZ6I(u>SUPs z;xs#C@ArB3pN~$v|9pJj9o`1|0Sd3f>^~nKXaD)4+kfYabf}xtp>E#I{_{mO|IQb? z-G9DV&G7TZe)pd*KzDuM%LnTnem+=@-Ob>zyY3E8>#(rP0fpUW_MZ>8v;TaN?Z5Md zKhz!mPpgV~1xnr@z&j<6dy91P-VPye0oVGGd ze6g4v(q>rB{`1jd_n(iKBf@DND4b@q|9m)~{pSm7|D7+)q3$z>x^FW3&llSKJ6}w8 zhulLl-Tmi_=>+0-y2H;0ld-!G98Q-p!$}DgPTlN3ANI5Vd?D?>^MyRr9r93jG_(JF z!Og$(MYH?Q7wrr`U$ndbe9=w79o-H;AGBk4MutVL<4s~-fD8KOSe39(_^9AT^`E>W6;IrlN#VzP; z&uZ*$28UfeX4qYR0~)tx|M@T;ln?!OzIe|7sc+spKZ{Ctp%-F@J2s>TebPEa@*v;TZ( z4$6yu;QOk<=c?_8hLbiZFY@htq3!+?bl=GfefOWB^T+X)<e zi-)@BINQ$`lX-W(IPUfnbm#Jm({4XOXBp!SFKq|#UBlSg5TN)&3a<~~b<_LVAnT?N zv;BOu-|gq)!-(+G1%=mkwx17ov;BNg?7Q=YJJfydQ1`88`}rc7cjt@sZa=|ySZ{Xw z2|70yulwX3euBOp6&J% zbOtb9zi~T&_6cL{6Tr`pbmq7SzMt2d;pZcNhMzCJ9e%!YcL48kdsWTw6LiHB+y;$#STBUDzkq4&t~}fA9N>|GV{d$ zpnF5p8GgRZW`Nugkk9b*Rkp)V(D}%(nHWA~GjdFP9nA3aG+RT^>u`pjubCQxUT=op zL%N+|Cs@s0j)|}18GdGi?wL%6++hZ~bL=JPt})QP>(&fEUxMx$0^Okm8izDy0M9pY zf$m)c-9g#y0N#uCl8NDirXcr3(7DVjLH9#|?n49JAEwRl^JTlk&zJfPKVkR8o?u|u z`q&?GpE&3);783&6NOzEr-07Seqqh<^U44J;-Is`LE*CN|9^4NSm~=`$bBrYZZrIR zd7t4Y_+FK4(3#B)KSAdd7q&B=y*B1LFpBAmMo(p=uT$# ziLkxhPOgkoUc3hBVfc8KgCPWT-wx>fBMn8+T|1CFT|sx?f!g*DPCNX3c;4aXa%Je< z?u-sULF&MJ6{Q(|va&k-1efQI+!Mj+vzg)N3(#IZP#SG#_z63!TIpp&&?9|@ouK=P zKx;fx?EX)G>F@CKEx*IhH=ujY^&NJC?qbqngxLRfJHyX6yBU7Iu4dfX&Cn3^x}Fgd zca8iLUms@p*$s-<;|xDvF*E*r$&Pe~EVCmxErags0-g2ylH1|ubAN}QPozQV*YW3z z#q1ORL+@Aq{~ya8p^I53Lhg`dLEL-I-Vg*DBm3pTI0bb6D(K!|&^hRyjG%a6_&N7K z=zbv%l=DRqd4l`mgM5ac4~rRoK6=lv^Kmu9&nNW^Kc9laiCKOXxLubIx?{)T=c{^$ zpRcPOe!hOp@blGkNSXtm84kL4*_j)~d{EkWoe#-d|8Fz={C^*GFCN=O@ZCJu8GgRL z%<%Kobq4TVKAxbod7t6utJ{$Ke871Clu!0U^T}a`pWK`cL9e?RA@{NNL&KVvbK>jM z(EC_HcSnC_`1$fX2s`|I32LikGyHrBy0ptW_JAfgx&Ec6C;CAQ4YhD2lfyA}FT#S+OJ&^>sL3=APA z3=ATmv%Wz3_rbCL3eg>z1G~=HH%A;VWKOm!%rTfXWhi$lYHLUOW7J_}<~CQh#I6BX@?Kk69phYCTbB_!(gP zfBNfUho7&+9e#rE!IF3Q`N-X2=M!~@pV_PqKVKU&`~=zg5;O*E&j=ph1>Hw?n5`km z(f0rJm!P(VzQfOl#-K2Voc}q$`~P%My#k5{E=G`h8GdpdbgpAW+we=-#| z1~oH7?sQZI`4eF9|&B4eGK6m~VXzbpf5fTp|cY(qSJN|s=?)dXTGULyO>5M-`^%$qTOb6X#+7QH8%Q;)6`~P&% zy`rGD{sT}O9xZSFcV@ZxC!c@i-)e!C4~!XpJ~U_e`N*2#C+MDy*Pu9MXqfarn&IdF zcu+aXH1U5h!_WVq_CYYi&sX6LKVL>O`~;Vipt1;b=ViRZPk1?L4=pF18GdGSgUU(h zz198D_Jkql#Mj=?a?&5v9%1+ix|a+T|Dd!DO4p$D^+F$7PO3xF0Jxk~clh}NRDM=w z{(!e9lA+}!sI8Oi@beYu&ck$vpD#goViz-j??MH)C#)TQK2&!2`2dvGA2Uw;@5nd> z)Gh$o2P!AQZ5U%vzH|5qO26EU3_rCP8GdRXbg%@aWA1|t;Is_7(_B%JVd6t^Xg&np zXU76bw;UV};C3emkHb%J+7@sCw})YE2_t95Deuf3e!gXQ`1yw0;pc09ho7%NX+a#M z&f(`-R)(KCtPDT3IT?Ox@iP3>5M=oIw>n_upM3w7|D9PT9$=2Y2CplbIW9g;XZZOj zo8jlfe1@M7K>hV{hM!NW8Gb&lXZXnoDsNzIB2YaEsxP5+|bX1*)qUIbU}%GlYQr@e*_oDztut)rs)D7ORpD#i8FETJ}1)1|W-Qnj$Z-<``{2hKiVrH9I2TB7Vvy&Nq-Ur<&4yupR zA$LnLvL3K~2)bj%yTKN8o(3cD0b3@)1Gdbf2W%h5H`qRkZm@j_x)Ub2!S(^D4)t!Z zeKg(S=flYkKOZ-f3|m0`7+w!=j(6>P#y9!i_zg{ z4l9J6!^-e8ixFJ6{QS?1+CBoMd2k$cgWAfVJPB&cu}t)IWSIEMp5f<9XHZ&X_~^(5 z4X=EMpD!LWZqg8(_(`MIV>TxvXSc>**U21zJ-c5rbF2c@VH}JNZfh zxtbAbhO@)Z*Y*xSUop$C%7VHrgP|b^bXGi!4`ROq)nV2SKSAX_C=b7W%(zKgaN;NJ zTJPC8jGW!we_bbM|MltaVQ&b^uH~7n&B*;a=WqSwOh%@UFV*Ku^)NDge8ViSrNh`G zrOD6`q^Wp%RyJeRr`OE#t1<;UXZ0{L6lw}~&jO!WQknIGgORiA1p_oZndMi3^t?0% z&5q9b)BsL*Qfg> zGyf{kU6h^d4MA^eIcNJZ^1Rk$ysp?fW>!_Re$d|hW1FU~sm*YWZLWIRssUDbR$W--donYUrw}QR11eh3#&I$IB4SOjVyi z>5osaZRu3cJDlbOfRiHEtic9n~4$c$MatL&X_nUTypD(&WWf7tb0_g+k z2kAvGkKlDsGy6qQd-h3zyabi8pgXAh z9d^Ec?(p-qJi||IMu(r73=Kg#jNGp^4|dPeX5@OUd9Z61s7>=y9o+9T2lc5zcQS*@ z2XNm8bRV_6!_SxMpf)|j&kRkg3dtJ{#a$_r*T$QT3@!vzjd z+x0MXEaEuB&kUi)pcj)FcY^o7O$X0eT;O07mr+~}`hXp63&E3ENx-YIF=mj&wPk3LAnc?RHW{01kdwKs>JFfhb ze`p1$z4iYvsI4rx@^7`!$_LsEKOgEd{Cs50@bj@b!%t8-_|n+n=W9?~m7!tMYiL^j zpUm(RH1_uLG1Ej)8~PQf9i0qKp(aO5@(pH15yvvsy3_o8%#|J@o{({m3XiOM9mZc79LqW!}IA4R?%%JJ@s~J~7RtN(9Cx;P^*g5n8Ow}aZK;IUGBq<)t@=)QQgG}H}EL;avJVTYfu%o%=y$Am%s z$k_}(U(N@YQ(GU$JN$fT?eOz~IjGIeJaM5N;}lR{1lb4bcY(&PUN$@Y1oc;6g4Sz* z#%`Ti;p0S)Kxqy%7X`W}I~+7d#PAW+hX&>O2h1E=p#EznsGZ^O@DtRIc+JeI#mRdb zTvl@No}T4Z%RQR|bWa?(AIb3X#r648FTxpig2tOWK;uTr&^)8h@DtQmeh3=ZkY@P# z)R}eSe`1$DnfAJUL4m&+q7|cN9!mqp?etIf0OazT1y<%th zsmcnyzn7cgCkrbBI8VXLQ_xxhkp0UUem+?2@blqvho4TV5c`i=pyr#`>Y#f|xw<(N zPtOAN3$hs*KXMp$&EjHZ_y`)i;b7$I0<{-FhAFKA!r;;-QnjWXQqj_Z5gM4#ymh{ zhTwbw>MLeDfX7Ec_xZlq52|xn;Q2xZlrKQ}DjqU^3vOF5Bia@sAbHSTue=N&xj=VM zT08uF1!@!ZgU0G(VYg?T0vd;Wq3-w-G`9e1gTUGzTr3Si+Kmh! zLG2JNMvm97uFscx1?p!oG8AbFc7XF6xXl5Y2LiP@#2J3R5Qoe!ypVPTkBhuu=9mZ? z7lEfe(Aqjs+GA&gv^j*CAZ-qDCeZo>NSlM75mJ{6GyZ(w%s%mfG-{jUfgR%%(7lbI zdjlWwJNyLQ@dnBRPn=mMu9sz;0;;<}br`J8anX)(3i!TYdxxDXm>A4JV?r;iVeJey zL^}gC4gzx9ZD>1VH?*CxAE}-37~0Nw&hYcGGt0zXvW!!}^)M(5(Ayg9NNo*vhMzCk zLFEdP7`*+#i86QbpPBLE17U`rpz)@c;*jwoP=0tN&G7RjXsip=<^$cQ$PcW{02Paal&l`1K0t_%*0Z{m%@!>kjNj zeukf~Kw~4Ic@?NQz1u|ER#@`wPiVdc&3B>aTV=>x6F4qt+$MT!1DWdswZTC77QIb0 zFNkOHTy}%f4yY~6$T1N#p8+28 zcW3zd0NTcCvT6uA%-j$ZZvKBdINrG-^){$I2O3uem($?#n&Ice|Nq5d?oDKH_?g7w z@bl46hAFVJ_{CvI%M4H*sqOGn{vdI1e9CO6n}9CWaJ@t<+0=0VWBi)MDCB16cF|BgFfGCTg%ILKi6kePGh zOJ&EOpz`bGbVl$#oCnO@a5K-_GEM=R_k!K==d0x$6CFODw|TI+!4@>$3+i)uf$o$B zt+V~j@N*S-zQFP4OOP9&Vh@-de}cv?U;K6euPp`5GlRy>UOr~{37Qjr37UswZ~(8D z)na9s`072wPY#xbAg@M-kBnD4XFX-+p7=P~@#m9tM|hj!YAVB&2cIExP7gji{Cseo z;U{R`3pCgF3N$~OisR2W z#~psYz3%{?$K+;(&RtYy{s4`gtgX!a;l;???ZwE`omHv%12neA&CA&h8jtk&TXWg# zt-~Zx-(QoJVd6`uosU6njN=YJLH9ntdhGBM)K>+E*M0`@+R_9ThL9If`Ip-n!0S6- zK6m)}V!Ol7SGyg4z5=bC+zfGN7pP3y40Y#vOg9qcE~p*PLGD@)y6@ZJC+NO=&^lL8 zdU&$m;pdCP4&b$$PeA=a*xsq-@b=dRaK9HcKLaY~;~9TGfX=@>;%Nw4%-9grX7+#j z>%|T~UoCg|`EoTVULAgVR%(OVT^k=VFob~YL7C5*4;h05trq~vfzk%3PYYhRIp5*u z3s9exk>MkFz6+FQLGxXc8Ggd&yQV|J2Rz?38N5~i;zrPZJCGZ9GyZ(F-SOv(-HtzB zf%XxC_7Eb^cTINq`Eoj>j|*xezd+)H=b5HE{CqOm0lcs9;bGMIu1vH4(_hYZ`1xYG z!_U`~LF2xTsPkQ*cK&)s$R0o@28g>r`|v>STFvceDS~Ux3uFcl`NsKI6|9iy41DnD6-W z;bO<156(0Ge0Z7hXQVpgl$Vzg^IaJ&pu2({e?Da9o_H8k-d<<;`QSQePFfhHE`7!A z`13WpBe)Fu|C#aU|L=@HUpn(o{QsKq=l}PNKVQFQ{P_yBfA%vYWPa;A+6g^UxU`m+-Cf#Jq0u##SB>ou%8*U=3+xOBmczLj~RcS2DK-jGyZ(_ zoAKw%{~+x6^Cf6qDrjs9I^G6uPc}p19NeA+^@Dyp!q&@d0FOs)XN0T+fW|$z@4p+g zzYjDA!1VJaI}_+m*R2ns>p~wb=9~DKnRBAMHRF^QAoIE*eRWv52kLKw)^>u@=F4)3 z-3g$%Qs`U}D2{qTWgn=`me25071Y0xcLc8sRRXa=^Xj0xTC*9zb8(<`m>$eOw!Z?+ zxp6!G1eL9z@`R%@>&J_D2JkuEp#Jtt=z0gRUGWY-UnWD+X(y6hpu44CKdjIjElnTHD0!`12Jz$W37Rji9@qLGxLlxh(Kn08p9D?fCO$I0JZnCMYky z2zU7TD%#=aD{BVunnO@sf>CFH&PuRn`uV_FVB!PNoC!sj@&o`iUDw-RJvKO>=L7CwvxJ(DFg=1yFUd{?b%UMt#iP;ex_8>Qa`xf9i zdr&-}m9y+fmBW9amW$e# z0?p&S1g!&OU>3aG9F^}}~N{Cv3I z;pZZehM;CP$U2Q`PuOw}8e`L2JOleho(RD`>w9$gk@e!24Mqu6Ovk zNVFkH8M-FL0p!a{JEFk}a${Ix6zJ3hqr{zQXMURRdem(@PW6K7uDPx1DOS}J|J2Du4Dljr^0rk&7 zX%DoX0#xsy#}O!Ak>xoKfci6R6Z>)a6_lR9bq;8p_Mn613U&rl@Ekm7EeCAg3$zZv z98~8y{Cov1(?NPb@%0K6CZP4X*$zM7=sSSt-H_`H&2jy$xeS^Q<9O>Z z2^24&zAI>K4BStE+6k&NKyG_tj1=DLXyH8>8s5_x!25t6PIvgZNTvZi=DE`N|MWMY zITdw~n;jtIU)c^nvnq9dK;v^F$ZjK0eF;h@&@~C5^bC$$Wi-36jITP$LF@vpt?f1b zKOH%(JOqUca#}&G+lAy+&{|Yb-auNf3o##CkPweTTGe4qVS5@xk>BXr2$W=3UzH z=R_<>IpK>BxEX&wyYP};$u@mSFMwAT*cxopt-Y|z>> z&|EaAJOj6bFN5Z`9e=(#@9^{ObBCXxaSG%zjpVTpsGXoP?ZtVApD#h$iNx!d9AOQ>5w{XB4+2s93~nc?S?)eML|272k1->P+6AF z`13)s;t41R7TB4Dx>Cu$}nh~95fEW!~k(4Xq*G&#>0$1U+s7N`Qk9< z7z4PB0*x8Whx94IWfT%0Tt>}z`1u5F%mG$LX&L>W{&KOy&lmF@e!iX!NqeBVGx%EH z=?p(#f%*o!89{Awh`T^zAs}~cX8ieTz2napn;n0?I?wp?#brd<33kU~#Fz}&9n&3t zJ_YU1J@5GQ;bqh^io@vt^cNuY+Z}(t1dXk%W(1#K^bmB8(RIe34{tO6lu~A#^71yK zjM8lQKOK}eA3AeSY)NC70?I=V?t|LCsBLmk`Tm+8I`;9K@#lZgm_#%GMA$gU>(7io zUxCI$enZDT{)5IY9Dlz24<7rN03Q3e4;}k>3?2J84ITS94<7rN03Q2z4ITS<&-n8d zGh}??CA-s4(4L_epgHG$=v*>ruTVE6&cS)N8&tM9!Nxu&fX6=eL&rX#aSxt9I}8~| zdBx52^CdrY?4#WQym#i&W4?)xLFK49;}p<(CXjugF?m?I2Wmfn_Su5cCTM>ZD1Cy* zBdQ^D=^#FM>;p80Tn-)kP6GwcM(gWUESG-h(#VQ1Ds220R5321DF z12mokE$2bx@C70}w;m-Ylj#{u~}duXdfGFU&l9d#wnom2wKVg)cKZ2595Ggs`tASp2jS2<0@VMp zhK`j4L-Hv~9RZuK1&vXF#z{bJUv1DC77XBh1mJWAnzQA0{P{-P;pbcE+AAD&1aV^} zP&>hO1ZbQ@AF}owG#>{TrR`fj-YiW+(=_3*xHUDy`XX#f7=mK{$VSZ(Z(deCw1)p-Im6FK&^7!|ni+mRZD;uT5Hwy4T7y{c@be||SP7_H zfsU0(fbt!vOe%Ny`81pGSc!Q&!xYe7JMg?DXdgfNm;uswa3g5_0I2T^9YbgYjUg06 z`gfo;{NR39I$GNT%XkTsQA1EObPPcs6sDlE5LBju`}&CSk|t2!8ni~P7&?{^jb=8M z@e(B?#8|?Uc!r z|I;5jgVtv;tOBcbX8_OHg2o{7Qy8W^a0j&~(8iQNYg<9_1KJY@8iN4EAuGejgP{I% zIV5d>{c4RCcUZ<+n9Lf2VEfZng2E59_6LzJUW4mNP`$_K@bd&4!&X=vfz3BZGat*? zf|41czdsRVKGZA@R)&w@{ywsM_0i13GJXIu57w`&)&D>JC8$oRM(URvL)UdwJAls* z0J--SXpgk9!%q*;9uLr%#X$y3P<;&=1JD4CWkB;TcpLzw~&X7 zC&KIm*K43X=CJw&ls~Z5FQBmrXnFv-=LNR<1*DhQ`h^Z-6FQ){L#|(n@s3SE@+u9+ zCb&RplEB!6i~{P|gm&%!>7cv{8k=ZK#xpkI%y|(sCjKy+;pd}#hM$i?ZCB7dS~+N+ zHDY`Xv^M`mJ!p-x!%qzsho7K+{fqYuKOY=so%kT0;U}zpS7*vNu#5vE*9+fu|4#?)F9n4GDEz=>qBf*n0P(@)c{+5A zTN``506GWtHOLL1GYObEv_O5G`hyIXpmjQ+^*NyRf8aS;kU5~TA2hBk&hQgdri1#p zAUm^|7(!l%L-rfIk#_j04cbc%S`Sp2@dGj^tMLOA7uviW;PpSAe-U%Rp!EqbJHY)6 zb8tLD=43(cLaqm3bF$_TyI}TXos$LW1=Rz1=49dF3>q5-jkEAGLdFC^LGo$)8!U7#^! zkh}ha&SP-+`QpFBPxP^Kusd+g$s&!F!`c!Zpfm$k?}%vUe|Gr!@Vmp$2g-~;AF4C{ zoF&IN<)u1e{AXn~=-h0FpAQeSPGkY)!Dt5XSrGr7QQK=Md%n#Xem=Bj_zB9t;C;{5 zp#A!wv`}L+7GEdoiLNe!hrz`1vZC0dl?=a{5B*w}Rspi4RU+uzqZ^ z!%t9Iik!ZLKro`bVXs;ajd^V`N!0rIG z8?eoRWJBg8LGFO1uMaw~ek@|o#{=lPQCQ!T36#FT?PJJU0)o~5r$4lZ?B4*blLn17 zf%*lRi40TF_on}E2JMv+SoybFaODGihMy0O8Gb%8XZZQpn&IaYd(irRho2xbK7b?I~U(RN9nDiR7Mw^vu6}K5Qu~Jnq%MWDYe3=d%rx;+ z0w``#!xJ%1!F%!PVuqiOmNWc(xSHYTgY^tQpKNCM`FJ~IFaL|x4nJS6clZfjH@Vs2 z=bP;gKi_CG{(Pm+`193a_K9zpxmLZI%^=wXZ;XpuaQxeDxW$_aAgV4g!&kowpxYNtMA?Vd^#+|P~ z=N8;%_<4$n;e(eW_eAiSK=zE_v#>#H?qAwF{(K2)cg=_R6}(;&H0JkB%!pdVCz zBAr_R8tb-(tmgxtTVT%k^CavXEMvx>ugo1G=N5qWtb)$02Ax~b&G7S;J7`@ZLc)?tcL{Y1C{Luq5ImOg6vuC@bdvwKMSkFPi98YxPZLYlTaM`IT=1W3PASB zKZNN8tskB4@Y9nKQqH}qXZ-oHn(^mTXRe8lm|0hW#gwSXkX)`(QbiGZuC? z*go3cVEb@$gYAR$4Ym*V9{{U+!OXe})K7Wh@A&hvx8u)8%<@`$Lm8$#WM)|Pu$kfK z0_fQQptH0dlr#Jc1D)Mo4fPXf{EV4l73e%PP6mgcilBVP%(x14{s^*P3!kRPT>TFOQ;_wsH&jFR`ptGAm?IG|Ueo$YE zk@Gbd6C}()V@0n(XQ-@)w9R-v)?Uud%=xkMZS`d@R^CM>n&e^ z%7kc#pB~JRa}b_@&d*ry@RO6(;pa=xS{_aZ$h^KeQhUXi@#jNOdNX$X*#s>U{Ivg1 ze+{bdKznpSZpe1{iC!jv{PPeRes4fyhUJj759$;BZ^ledFPY`FUe0IO$-xM58z_x& zvNC++VB~xSTBrG9KEqCsnJ?x$?9^akFaxn4fz~812c47D5cH6lLu*nH!<2`hJ;vu5 zz~>-?<`-Uo&O~PB0H5&zJO2T+Uk}|4pfvmlw6_YD7N>*ukwVgOXAEW<2C0XochDMd za2(l#&VF(D>B-74QL~ZZBWQj?@oLvB`T!4x5JP&R}VDptgbybdu=V>Yz{`=)tZdlyS!N)esY1<^k?e)(D-;_vgY5K%i#Iq z!w~zR?XHQSy|17>Ax}W#S+Mk^&G3^ImY()AfZD&1{kFRqz-!~{FM$Pcn!ewWt& z>2LKx<-NmCkRL#6RYCjaULSV&*n}t)~ukFX$W~WyqN)t9c;#2y6x;sD9&E1=`Q7rN}T5+z;XeiE*w1oeKmCM=frM zdQhL}Boo60O-JsDFO3<0zGQ0%dTGx1^QEyPxLkgHm}lZ^VTPZt<}?0$Ih*lk2kg8Q zanM>=$o$rK1!^C>ZswWz8q~g+%=icJesDbkaeFu8&zIefKVS7b z{(Q~MJMlGWzt(cbpD!1K>JR7{FUpX;&nWH#ojC>SFY=?h57t&pg}IL#681+OJoO+BGrz&x5yB1^ z|2NxQd?D;Gk;74N;*0NWpuO1>IULz1zWB}d^F_1u#25eBem-Sp|M`d=a<=UQe)gYF zgxP;S7H5Z?Z^Z8Y^A)rE&zHjPKVOTx|9tJw{_|xp`_Gq$Ehd7)?={;`2gU=oj-YnN zCLt;-?ROEnQk^w0kk)$ zzu6WvrUWkEKePRWmucMYKjGrf+2CiRJbCT*^8vs6Ptdux$aQZ-B*T>d!VVMvH`}1r zzufLWU$VP{&q)KFGv&p|o&Ab^zSOJZygNa0^{|BzeE!jk=Wah&g4zv@pnf0c>+Vg^ zbobir=d1T_huDvVD;)^7Dalm+b@nF53s%UA8ZnSysKc&Gz&0^^l*B zE{FVl!0j-Rp+R*b===zQNN9a~pY10D3#8t7blwfT=K6)d$j=wvP&X)d**=i(vVFnr zFp;BCb>a(a5lEV8RGIj~9>!Ll_`(^+R+{+29m+naI1yw{2WVd0U*zXQ|B#;#yhDCk z1cTO0xcz)^n(e1GD}%^WkiECve!k=er7g}?ulBQn*O$Ng%&_Uys;*C(wO+Fo!RIJ3 zu6lWx?I)~GfcQscBB(u*5CQeiaV-8Z7y0?Z80sJKF53sfNd8fVx)tOfbr@TD;tOpU zTWR78eJGnzaU#eZuz$=&em*o0`T4*&JE@w`C)A3i7$jct6uzz*f?dQw=Zs2hD`dNSZH8a<$*PGdXDl&4tM)iXd z*bgi)KWxY12X>L4FPNcz_}^*!;CCk?{d^Wiq@V9Fw(`UmzhP{pi7)=c*zyxW=79ac zF7opsd&tiR%ppHlfc&r>;)m5N3?eT#yZr>Y|HXc{pRXp1{Crg`0xl~+`T0e#$j=wk zLw>%fX8ZYcb_nFW#_4Q7U)T#k>Q&HLj6hN5Vxdab4z&0&sWRYem;#3 z`S~)P{pX8h_MZ>a-G4qvcK^wg-w^c3o_FUgjsMe;?SEwNyYtCrXqYU9y5qg@&lj(S ze?EL4{PV%<;GfPM4M9C1w}8&9UhMYs!E&fuf+22k(r29V@Vpzeyi%F?U^UxMtyl&m zG3AMBD14=fO0f)6K>6+AYPX+H&bz_;VURLHb>b~0X!)=nOL~1S{PV?QVMv+#zSH)> zYozpg8I~4RCcd~1V=GU5aT~@~n)u>Aj4d}2WDYpJJ{SJ^@Okjh2akh){t0B5@?bqA zz5ZuLly|Uv^^n_PqGE%}#7Eo?6P+5ACW6NQ**`+ty2V)BdtUhGi_=i|KJK)Aa39IN zyJ2oonfPKqjIBKJ#bFp*Y2u6HQ1(IDi6C>p?maL3^Wpj6pASw4|GWTlZ!yHZm!a+j z*Ri+V;AJnWo0TU@eTBL=AB%gp3;%qv8S38aowg4yBe{1m)GeSgZ8?msJn_Y97+Y!L zi}g@8qwGYGIbip07ykKhd+^T(n}dHY0l7CH;@;&@_kz*__V85(hwpk=Um_ced*=&- z?h1vZhtr+54~`?bw;SpfkbC=KY~_hBCd1fD6JJb+vK?h6zL+ii6YSpk!apC*5B~XJ zcJR*%kbAQs?yY8K5CNrEkbB|n7if9_r2`#Ux=qL8&UWFSFPfp@y1&!*!EPjX7DL?t za%VY=tvvBXHH@t^@kKq1EjLVo(7mLPu-x2f`(Qni8>3aHE_ngGD_aE`3p^}@mSm&F8uRFFf>e;ciKK!jO1Qt zs9Qi`>JDQoPkiAGV=GO3;SXgqN=*cr0}j)0;hzt~gMU5<4*vNwfMLpmc!+!dfbP_R z*1xc{3Yw<^&HF*}7bLCjfYr6pSlnwb{PTr1)V;GiZ68cWa<4YjEg<*m!`R9bUl_yK zN)un0L)ng!6G7&H-D@xW^Pzq4&j;4QKhJ{P8x3*q1twf+6;ft3DniTHa4har7ykJ| z8S2jdPTL3FNbVGdx&h=)aTr^9;tOdQTWR78c^F$_BFG%DJJp4MK2#6>`9L}N=VFjM z!y)cm1`SuxogJWj1q)k9n5s;Cz|6F2{d;H{2*%=8evn;Iw>Ed$KBz}>>u(`M`{h53 ztvvAsGe{4pjjS~B1v`{|P<-MGZfKh27ykK>KltYZ?%ywmnUF_K#!!`!Db@x^l(TY2J(*D$uy#24?OY)0{k zAalUs`d#Sf!|y>qAAAn_=?ikJKg6v8P`Ba^SH@K{K10LR8;e`-3;ld?8|v2VPTL3R zNNzn1bq6R7oQJWMC%(80V=GO3aUIHb6q^V#2kh4SLO&ng5BmAwcF<2HkXyYWZdHZ4 z6RCwM%7MAp9gBO93xV#xg@kQHHx&`Fk?J&0T#233^Y^8}W_QTks z6JHz_g46@Yg?>If9`y6U;h>-2{6XuyAnyGMy8Gz7+fVd#0C6iMe>uY3>Wsy$>xF*4 zSPc!^;7;2I{zz_}4ReRe#252nY~_hB7Q@&|6JIQcvJZ+(1epU4+x0>}AFdDj`CxU> z&(k2cIz!xg4zF8P!S$;c%&qoV+&W$8=Zncux4L)QK5#~IYctdxpm1%6v6Uyj=!UVC zCcfy0vKd7tg3JNCb-K{chtq?8KA0Tza{pZmk#k z`LI6d=Y#5?pQRwTT0`7gf$mmT&TdqQ?RW zO>hS0Mq?~)^cVX1!W-&FJ}5X5WDeMk{z5+= z`Um}d;2rc+5#&Z=h#OU4ZUpstklY7}ca@2YVD8k%;!bm+pD&D|?iBB|eIShFPGzVY zKw+s4V}r&FU~Hv{FZ7{oM!|_7bHMI27y9|oJm}{G(6|AV?Ifjr$O%3hPd|})V=u1s_So|ZdJ$PR(7GEFPNcW`@h5X!S4>F z@c}_Z{rVlo28|EE*r4$N7@L10$Q*FkvJ3ru$R70b0dvsL1t7PoL)^L;uUkQF0mfBp zU~W~$;@0sCm)+6Z&2JQlZJ7yS9+GSsclJ8U03Msn+6s5?Mu z;5dw}Jn_Y87+Y!Li}O%6Bi}@jIbgS57yS9~df?9omji!#f!rz&ajP!_g9vEc`31lG zPw-f+IB2XEbQS`~s+ZDiKS6VxtD*BJFQnamzT|iRsl^I9OO5TPDko@uh~eWCem2OQ znLl_e2C_faTj1wI|A3zlyaRqJs|1^)eJSqt6FQd;UT1d~ zG)Kn|87Bsvy#;a~$le#s@>-yI9}pit#>vh0^TmF_pD%Vp!|Qg3?Stz`;k6nX7NGE2 z4`VA&e6bnER+{)?JCyCnI}v0KIK1`?{(QJU@aKcwfj|HGGE8~E4GAxh-49N?{d~aA z_OqLfK?FL!d_l7kGQPaJ2RgnC8drMl_Ve|7H}F~Y;JZQOC4Rn=miYOU+hO8T2m6T+ zm|0gnc+UD$f$@N?B50ibcem|>@7=ZvoCjf8-eDXg0=i}Gmkg*;I zJMh@zThLr2Xl|LA?dJp7*z|K($k?>H_|F&0P`CGY+dk;-wtdjv4Jkhy?Iyn97KfA{ zj=a|X)WH_)ryVdq-Dk!06TA4&7tByU z)py%IsP49XP>$rM*J21iy@#=FCcgL#V_Q#r@g2stn)u>3jBPpb#eW#vd?LsWu%Fn) ze?DXn|M`G9{AVc0PxoEHemaQcC%Aup)?bG8Nx=1{gALd}EinJw#^RsnVn1Iz7K5a( z{BGL^+1<7e(vkdg8s;Y3i7(E>*ftYiT!yi&C%(82V_QvpaT~_AocQ8CjBPd%WCz$k z&&7T|d>;1m!Q-%>iXi{ohWMwKDF0Z4{SyH5&vh*RIWG3|#bKy_;=64hM0eXh2uJeI zYM7gBC%#w@W7|x8u^Gm;p7>%rjBPdX#cmkea^j2qFt+JLkR4$E92fif@OaqI2ZzIc zzV%_4^58neKat4(`R)2s@n`*IQ2+43c~8DPyXGu z54^i=AGjm=sT<}l+lepwVQia;FDAp-))QY$hq0|DzL*VTTTXm2AI3JB2(kn0r{!Wl zA1)93`CxI_&mAB?U55Bc1<6my`3Q7IG{}FbY0nbuucv{~Ht=aI{%RNd`Jx%>FZ*uW z2iD!T56qGLl?`*7?Zg-PFt*La7sW8P^~4wDFt*ji7u7Jf<-`~DFt+hTkR4!uwTu0H z*dF%tL37y8CXl~QL;UrQi9zJWZ#Q_^@anWU=uV@F*^agoUms=#mlYsCzFaN-^X2LA zpD&NI{^U4XZn=U%0K7f}e6Q7h)}Jh(wJ)H(1N&Ja^RN3|e`Y|}K3IVEuyDIW%LcoN zp!tqO==`_=OzybrPfbqH{W_elIW~6AdU`qhCnqE8YmSYrvtDdw{rTd2_|F&HSt0Wx z;oLi4EN1=r0#YAO-~i2yENA`s0=Z7^Zwz`A%#FC)YCY@EnM%+(fW@vqUo3b1`6$?X z=i_kioln-gLgq$xvqI)Z>;+KfS-O?}Pk*u5_2+}_u0J2{b_LIgyefdqXM^g?7wf}+ zzL?MY^XcYr&|D3~J(F2~zIe?Jac@8C&lm3zb1jR~KzI0Y?*z@;faYw9Veaa8{rO_D z>(58}-aDWChPr7s)Jy)eV||2F=?@X);a$ zyAL!c3aWG3S%1C&#UW^|VmB+e?b8iw`*gehe0e_n=gVf+pP;Y@pC?++3h@u<4ghZf zcpC`4-Q%qEfBMUM*Pkz%T~XUT?XD>8o_nBn&*^aRnRFm`z5ETH$JNp}Xl@DOKY`X$ zD1Au>tBK$~hJ)S2$uiLVRE;G+rHlQ1kqpgG`rWnJRyD+XvF!whzRS{GknVi|xc0`Y^W5#23aew)Mmp z<}kL^#23~uw&lbZ_As{LM35a|f4GbNeCQtb^MP~N&l-?F$|3%E0UA4j#s_NIW&`zy z9i-3aU^}tx6|@gkjKx3dVn1IfL;b_wZTo<`+x7uFl7F~iZUVJ~U~Eu32*w7rgJ5h> zI|#-GwS!=6gNYzJ!2VGe`}t5k?B@gJu%8|v{}e;~vjx=0hWZDVz98w!20RY*M;e;8 z^0D}VUF_!zW~d+jciBGp-DUgWJ9NGql&@ZkLd!PWi7(#6*r0X~j16k{z}TR64~z|J z_rTct6G3)>{lG5v^C5fK&j-w5KgB_Q$cOl$8E2eWL*v8>8Yh+$6=89bjm1CDMSs3{ zEDCA&yzjDo@Vd+P!E+@4oQAmx)b4??LG2zG8`SQBu|e$~7#q~?fwA=_g6shM=eg+5 zhtETQK6o7Z^RXAhln2=m|M+9^4=hf=N7qwmK8KZCsAX-FhwhvZ!**;i~f5*Qm)m%!Ls z6G3)>{gN*F^I>}E&j-n&Kczu_iH7*49W>7J+!eBJ?7u6#?TqRl%ZX|*zl3A)i@WI0 z7tT<>%`Vvb zHXn2xMqc6n^q20gKVNvGwMYC>+aq^D?GZxbFrc&qYS%im{(PY>`tyY{G%WkOY#(%Y z**<7T3QKNSc!26M7#mcV!Pua>48{i4WiU3VE`zZ(CW7n$ho!pc&xh)vKOZQE{+tR5 zOJ_(}g4#+C9=ra0V9)wfo{2%^<#RXio_vj;^_w~VvVZK+fR52Tcl*ilm+>PHjE}x1 zuwL-z%W6UBmU@`BqPoOYk;yF$j^j3IH($jH$R9$ztM{rSW{@aJRiK=4}q znSRhR(wY^qR^Qt7=L2=tpFE&FwV-%#7yS9cS@7ozWk^5crMc_R7s{?bU&w>Z=6wAK zy5{$lyz9>w#;)M;9MBqb@Ld&#U9-SzKiOG-dNFdo2Cp6C2I=E^tX^U4Fj&@AC5%v+K{d?5;oGaJ&9|&Fv1} z7uUnc(VbJ7^J6U|$Lrk6+#lVwXJ_}+^3L{ReM2JN{-wimqrUfvaMo);t6YE4GY zU9a5(f4*@J{0YNU&Hm+x7AzWU7a^W}GzpBhXI=Abn6;=Rkym#&n!P*d}o35??Co`cKP}0yUS1Q zw+@ru9JZg>U8(WI^W(|MUZAre-35QXbQT2lF(!iIYTEz*;@~k(V^{F~A+H{@fa8XP zk)s>7hw8<1h}qyceeUw}#eI+(&ew~e>!x4acY&7++#hQ%zdUR|Q8P39hvr*{NuHVD zv)3nr%=iGx*NIK=2vX1;V3uGPnV~Clc_2-~|>5JPCH@vv*^7F-Y7LXYq zxp^V^32X*z9r!;rE=%T%*IwW!czrQwExfhB&zIH#KVR8H-F}c~;_JgKKVQuk{P}XW;LjHf&^6^C`*uUz z4tM8nm!D6syZn4{7}cGyHRTsz?%eMJ9&>ovEco+9yWr0U&4E83wg>)vxLok(gT;cN za}=k%SRM#oQ~ogr(g%O24XGo&LF-%9A^GuvI;g+S^79I4TmsuzwY}iaSJr~iv1$&; zSoLxi#8`EAhwX#*4$QIY*&VizrgzvroZMmipufZR!Tb|ob)dc6FPJ%3y;#ix8UJO5 zj@Q?B*gmN4uzgV8VGCL-0V<6+RpAQzZ{G1K)*Ls(qFJ22k?3)isw=Y+_{CqLr<>!mpkhI7JEe~JLb^(_& z;Pugt>=QW{Yd5`UXZiW&eZWr*M$T^DkF}S(GIM`q^g8@_-OcioyE5}f1~mVBF>!lPm!B{4 zS$@7OX8GB{!~nj7_hqrm&sX^nx4mwMxC?au8z^ibZs1xCss}h2Id*xYhXd67m!Ptz z9~1{HKj;4cFaB`33p`FAq_g~76vQy){cpFQ??CI*(p`Q&0?B8y{CxE~;O9w3ho7fF zXS=)>`1$IfgXPJC4wk1tXR;k+usq4?@beU>!_U*a4nNNbI{Z8<>hSYH;{lt8jR$Ss z{}1?iUXPLE z^92Ymwwn0ju>iR3@Z!0^&xg+gem-~{@UzMt)JKD)Gf+M8V6n^32iqZG_h7pVxZMF3 zw|5246M@<6Za*I+v-}j0fV4+meFn{WalO{q2&!{AR=o~p`Kf)dYu4*0@eq3(akXBfj`U7r{WAEFM?e_W!ePITF9JM_Z{e7 z3XJxV^3Rvm%0Hh7J4|eGkb>-)FlIq&A5FAE{FeiM9{4C)z$xpJ@BSS?T8k z`H8j`9fR?bf?@z4$zuAI9p;OSPr~5M|>h! zEr`8PU?NB_=eDNE`7Mb|sKa4Fr@dY!?e?k*qu*2Ab6G8Sv?BbsYa*qaML(mIhrJoOl zlYTznPx`sZjbX|IZxDQ_n$Ah-G74HnDU@>?(h@b##Ckj z*SX*}=*F&DSoe#lv%vdz4}={iGB}8V>wqiX&^EC)mhgJ6`18eM#h)*3D?-BS^#t1o z&nMVEcs#-O!F{Cg+70uw#Kaf-VQlex})_~J5* zEj01Pbr@T4BFKJlcpc=O2yzcNyq+umeE2-^=Yz+IKhr?rr40!$HfVS~RCoFL!rcYU z&!S*IPlx$g8jGK|EB<`3S@GwK)lffQo?!dn`~=$vrzhAxIF97!ZkYQdCcfy0vBf98 zm<(f!O?)vO#ulCUVm6E|GV#TH7+ZMai^VXu(8L$ZVQj&PAp607cI24|au3+g+ZBI4 z+@ARJ!RExDnjk+*L;QS_7b%UXyZn494{77T_pb=EpzdD*$G-?TEJ9#mA&w<1+7*Ak zXjc6Bq8b_&yC>K_*gnDb!R86J57r}vMKsLa5))sckr&_He!dchgu`ofm!EHh9VYfTicWmP&hqp1X{Dd9S1bK|E$lEc+fiiVYi>wB z0`kh_}v*iALW(>X$ynvnBUBhKH6{RpD%7R|MWmFXTueLz6e(Q`NA8T zZWd3leK3E5?St79Y#&TVN;lfDIF^|BLLbH!pZLNU#ul6S!W_mHo%q5U#ul0Q!XCyJ zp7_EU#ul3R!X3s2t&4-PIVXbL15P*Lia#HQC;og8ocJ>Wlx}W2gUi_;Jdkwrk{yzF zUS4PZ$#K*LH4R*5Mx=qu&@i~{{PV?mq%?5e`R9w%%s;JB(ts#R8Zd;(U3W%J1Dlc3 zz+vW}FV-jhd~qC_2FlrYzSxYG2DW2K1I36mPzsCx&CWkxYad@BoiqeoQ8(MY3H9W)?-Nr>WV*KC@cPa zAq`Cj-4kpdv`?^o&^*ERK|NAB_^p7bZ~w#C;uBvm!{SeD;tO^dTXfLy)>7Wdj4!EJ| zU^OTmIHRV6$JT!Ls32Q6)_%lpF z@I@zjpzuW|y7)6p0ktRmL6JM-{v4tnT z*bHL}O?BMG@-xWq zsD2g#``HHO=V~l|p04oo#bkw_FS?)pWZD?zaT|9C*-yc~=F(-nTcNLKjy zA{y#{?FqII)F;?JP@Z7>Kpx5e)-bn9OnhMvV~bCG;S6JoO?=@FV~b9F;SFPpOnl)F zV+&7w5e#DsO?(j!V+&3M*$?*rLB@$7_kjJMuJH3=dcw~K$q7IEK>ja>_+O73QcuGC zj%Z&AO?;Eh{PT6T($Cl4u=bVU#Mk-E;PEza`$}8s=gaJ*pD&9+WvUZunVODNrlv#7 zlXT~wFOreU)MV$MFXEx?D|UBiogs`;rh?b|faHqN%G6?{GBud_=ZpNLpD)6pW$JXc zoiCi>W$Fd+dLMTzW$I)$MElC0`R828|I@*JGH2(XFWjAfKAP;d^YL`IolpFs?W<_) z8q&UcmyT4g#zXxd@BH(HJ(lv+T;b;nV}+kDw4v!nc!KQ% z{t31ZxF^^?U`I+f+^{&7nD~Mp#ulIWLKwytoA^Q;#ulCULK?;vnfO8;#ulFVLK(&u zn)pH;#ul6ivLBpo92q8p+yhQG<_bR_nkW2xV4U!i0hDg+A?aoT7bM-h%ytH+hnLo% zG~kGu2F#JtfH^b_%$$bil6g^98fQ&lkVtA@%C- ze%lA%`)wb5?zesLz8^83aa$gmS0pCBxDR8CPkiwh#ul6S;yH{hI`PG87+YlGi}x_L z@WdCNVQis^FTTUrf)hdZzua{DYzb&N@Y?C;i}y}HA3b*6`S`gjqJ8z9 z32Q&A7o-o=zWVO;^TltcpAY^!!Q0ud(vZpnW@s2NJO6y~oC&kPbzT1Fi_7vqUz~=f zgU9{05AOHdKDga)``|iKI#>;hGl_{W*2CE16JKnGvBf67*bZZhPJFQ&#ul0QVn2*6 zJn_Y07+YxKi{mi1;6#x9;B)|5bADO=CpaBkm;d?jdi>7^m*ao_ab%eC;JFjHzcq&w zxqT%(@rw^~`$}ly2Nb^G#5X>W_7!H^N_^r&VTXx|4k8mD2|G-5auA*P>j8A_#bYMS zcGhzFpDz~6|9mkU8dj(KZ66%(w|#K9-}b?Nq_C=n`AcHri+UJaeBz5{7+Y-Oi*^`W zbmEI{7+YlGi+&hec;bu6Ft*Ud7t>*E!HFRI!C`gKdLqa@;ILXQ|MTJU_@56J$N$_2 z3aiJEunOdaw6j2M4%9Z51k~^1P``^!+zs>leJp-2m;d>qSpMgWY^dKi_uD>L-*5Y1 zb-(R{;tPKmTYTb+U>I9$;)`$?TXf=!Xc${$;){3~TX^D&WEfj$;)`?` zTW})Cez4yittNup1NM8l{LhEw@jo9F$Nww>`Tah`??O<&gU?++8qb5oxggZvLKACY z{=SXH-|q51UpUMEd|?gs_w0V#2h;m)A58AIebA5OZ)untB__U*hq1*czEFm-#U{Q` zhp|N`zR-rTMJB$`hp~kxzA%Qdg(ki*hp`1Gg6s$T`=G@{kbA)Xc9;M8&^`X=1Lydk zCLn*`hWPsm2PDqHd&`jg4e3uvLj5f~(H`dS>sb6P4zgSR=L>GAznlAQAJq5TKB(@u zeNc|%@7HpO`r$o{4I1x;u|ebAFg9qs8^#8Wcf;7A@otcPpfj~VA#_d(N%Aoqad`?=iDhtK1FK6o7Wa|g)Zmm&U+!0B&T-WCD- z`|y2e*>)a_zqiZ%e6d;X=Zn=)e+T#5KJf3iec;`1`@kK^-`y}bg2t|4Y|z*>j13yQ zhOt3o*Dy9{>>9=fja|dops{Nh8#Hze^|zzRM38&H{@yP4^WpZmpAR<2{j37{`#i+o zQXC8-PoVP~@O87`@?0G3UoO}>)6-b|+b;L>MYG(`7u8VzTKC&NFz>g0VBBx}Kp)A! z(J;4x#;0Ly(D*crEjIB*I*bh(pN6qPyT#j_aL-=45|K90rT;c`D;1k3$=;SKe-a=+~Z z`F`66(*3p%#F6~14Ra%Cd=7h`$#={f%CpLF#Nlu%CHgem;!F&+2kNUntA{ zd?5|>Gk3r31NMH~2h9Dp5B~Qd+Pc4G5oOtb7#lQ}2y-`RED^>AjU~d^ps_?48#I;( zV}r&LVQkP?BGk_Z^(TVd1NO7J+|P&VaX%j@$NfBP&oJe|VThlT*&%5g=4V*?2JKY} zfvu_BkHxRwWq-c-Ec^4tYgtJ7^|{aX!TUbj2e12VA3R6$>uH$(K;vaFHfX#I#s-a- z!PubjG8h{)UIt@>#>-%A(0Cb)4H_?#g_K{8dJ{qJ0sHm4?9YeaV}CyQ9Q(5aZ)=zvL1SMqHfZb%#s-aj!Pua&FBls%_61{u#=c-|(AXD@ z4I2A``um{fM38&H{!W+u`7k~9=Y!e~UufW011@)?KK-*JJUw zx$Msu#^C5fe&j-x0KZ8O3UJdd0 zXV4jz(6$Mz-vw!l3PIx=Qm)0p;(Iw3e_xmR`Qoz7&ljhm{!Z?*eGuPg`yjf{_CYw3 zzgNTD2YKyZpuRcO-;SyiLGA(j`?}1} zhu33%KDZq7QxxRySx2)pnf)t4eDpZ*r0wkj1B5%!`PsHHjEAGXT#W_em2zK2SMlj z$Uw#G7tS(2Usyx^E!}7PK)lcPfpDMg1AZibOT*j<>Sx2)pnf)t4eDpZ*r0wk zj1B5%!`PsHHjEAGXT#W_em2zK2NfoQ+ynNvyUfpr?lC_fILG{q0{MG3#NWSIAZ;{I zT?T8P!Tb$sr=9I#nDS6u=H~-pnV&DjV}3pWodZ7|%NQKL%+D9xGCyB1L;e20*Y?5h zUfT!Xdu<8CP9@3az{PvG{Sl^v@TorGLIy4E5vrUfTz! zdu<;a@3nn!7|D;#F!xAIe9;bLi%)#f4P%Qk1a@kKn0 zEjsZHjFJa@kKt2EjSTmKiJ=mQWHV$0sFgN`sc&?=${X&qkpD> z{M`-lHyciW!_qXQjkW>S*KEh)Z-42ZFTACHzHo;6dw#F&gW0{d52p9pKA4Q;Z)KPp zB__U5hq1*czR-rT#U{Schp|N`zA%QdMJB#5hp~kxzOaU|g(kkRhp`1Gg6s$Tn^AHi z$UR_x`%C|P=pX&_fp_#z4UoUvA^tuAIzIwyUWS$5lHl^Y20WIxp3 z?Y*`SntN>@)c4vxs7CVlXDLJ(_8rC+pZMZ8j4d|t#eW!Ebm9wUkeQ%yL6M0s*kNqp zi7&WeY@vxS_+f0pi7$kuA#Joq@rfY!fc-5m{qv!G^v?&<(LY~VGfa8V4DojtGjd*r zj14|{0!`EPSp4{2>gS8sQa@ijmV%U5`MtIevU_bGr1#oBNJjGGVVL_RCcZchV~bCG zaT>-JoA}~9j4e9x#bp>O#ul6SVm^#5I`PF~7+YlGi{&u3@WdCZ zVQis^FV@4@f)hdZgZgR*qQ9p}8{;r1jTNr1WhWQ)P4&4j$ zcR3b+_e=eJ(Jl4!MKjdj_Pw?btb1)AnD^Q~Fh=rsGR%z<6JMmm*y0mkWW(5E6JO-R z*rF3(6vNme6JM0W*uoQERKwUp6JONB*n$&5_JjQmTD#dT1!;%&OZ|MNYNBw*d9rg2v6~mMV#SlNw0G(3`^)qT3hm~KD@n9!dT<2r) zx4zWR7ur%kUnoQU&EISLfVakn zhq1*czPJrzi%ooSAI27)_~J2)Ei&=Na~NBA;)~ZXw$Q{E?_q4gi6HyI{%+)(2yzeD z-~T0lKKvi~^TF@PpEV$VXG8oggOtW!s=NF|Igb>)eoAQKpTp3#Q|Vazd|vYBi_?-n zUmS+|`F@Y>gWEl}53cvvKDdnJ=fyDhNlbjP9L5%(_+mATEjIDRdKg=D;)~5Nw#dX6 z+hJ_si7$4;*g_Lu?1!-hCxYw;`MAGb_@$reHryOxzFib21h`&zJo9Vz%VZ7n7lWKHg*d;Bb%agZ(|W4|XH@xftd? ziHR@DVQleioFDn~!R*MNOdvleL;So5bOs01ttHiiO8-@G@Wb#^=!f9Fg7e332r z^F=b$-|Ks9AFS@NeXzX8_Q7H#e>=n6C^7McJB%$p@r5^xEjICmKa4Fp@kKClY49*^!M04=tlCdFwAWd6JLnK z*q}BOj4d|tg*=QcI`M@vj4d+pg*uEaJn@A#j4d?rg+7c8IGhpD&o9{;uz_eNf$F`=GqX z_CYa{zaL8=%CYA#HmDB`V}tt8FgB;bf$^1%TL%ESk!nHop|~XvN~^OpuRJV4eC3?*r2{Mj1B5L z!`Ps{vjjArSto+r1NQHIiJuSeNBn$nJK`rF$iKl5|E^ALVQf%;8pa0o zr(tYRe;URH^`~KMP=6ZgZ$_4hAoqa%ySuS0?P zU2Nj*>(KP=jm6*f5Knt@puRDT4eA@i*r2{K)DMh|6G83)`@vu0=R^O9pAWnvekOwa;12Nv zc>l1z%g+bSOh12dK=$WyLiYuO&SW?Zz0(YI9~$UPkyo$Xe!h9{_OqMO;b#x4!_PPU z>OWt1tN(l|>@acZ0nqtAtg9Z#Ga>GG+dSF!!TQOV_q!dQZ2M^cWZQ?kC)+;QKH2uc z@ylR!uRwRm2CGBzyl|uKgXNQLA1t11`(XZL+gHZwKOan=Z2MsHWZMV*lWkuKtN(n^ zKH2s`^JLox^^wtcl(?dOB= z$+i!IC)+;opKSYTvf9rF?vrgFI8U~HU_aRwbiT+deJ1eP7~nG{jG4geabf$=;AhjC zGeOR#wPyPHBtHG; zw(&%e9pE*{jYbo}c7o2TEm!;busrSOgW|NG_stomJg|5A`9PZKrzB{M8{|f7r=PFP zoqoR5cLMtzW9|L{3-H=~UYH-nvG~zn?dJ<`wVyAXp?;K~Z2LfZvh4$LBtL4y+-WiK zg+7dJKJkSyjBPgYg*l9EI`M@yjBPUUg*}XIJP~9E*pHxf79cx8e)L!S`OrV@=L7Gw zpUXgg6o>fn0ciY7-s$HdsX6JI=su}vqwcnxElOnmVk z#x|Y^vIFeLgL)Iec7pu)U-jq1|EWJ8{7(I84)P;E#E*qYetc=}ggDohoe3=-O~HOl zh53;iiyyD6{(Ny+_2-MzP(MDNWc%R$B-;nKk^HzB=1z-=FSf(j<`ZA+hOx~izSs|A zgU;oJu}vnvI1XbQPXyTk_G6>&M6jJ8KVDb;`S5z`&j*)NfBrKAo&OE-qXpED581J$ zPZO}e^kM#D#^SH_sy|<>R{i;6G1On@C)qwYJ<0aLaU_3r!`x;u@kKw3Z9ehEWEk6Q z;*04pw&}zdvtewLi7)2E*v1neQbnK>lKe_=^dz zzl_2D`e_Z#cmEkN%glDwpD&tKf4-=O`fK+j+Xvex**@5e5D-kmBW-?gj$eAu4)^Fed!&q*ME{dWYH znP-?G`!-;C?zO%XWIy#m^NDZXGyZ&Kt^V`XZ#Afx#l$zC8GmLoI{eILjw*WVezWi5Cg&~3G!FRjymzWmMjlfyL=b?yIaM#LW5*Ni_wb@z+cj+kftg7$qJ zv_x6&58nF&ItTc-BkI0d=XAv0>idj8U)ZPreDRp^=Lyh#_3N2;zBtbaUhm%l+gp8^ z5p%u&YG(L)|0lN@f6n89?x{TQ`18eO$DfZ@JMVnF-g)Pf+m4XEwa*!`uKAz9^MCq_ z`;I>!Ja+u~@VO&+Z}s~q$Xb7}U%$KkeEHrH99Az+gTf~rHGGaEh0k$l_#8(IAJE@^ziu%4WH$p@X0_8 zpT$VwvltpaixJ^t3EO)O4j&7Y@B!}|0;QkjXyK!b6h5;Vf4-1U|M_A*G0;iHTQAAV5SfX)NYyX`18eV z$Da@8JHq#i#G!}LcW4;3gTg2cHH?~(!l)SS{OY}L*%h) z#-A_lr~Q0U4-KQ|Ogmp>qlHmEmN0tE1kYo~xS@M$vK@cE$annt=&{qz$IqP*VN{Mi zjCO$Zfx@WV@#l+b$Da@C5n&{X6h@Ds?La10ho6j$4)C_^gLuZD&oBR<4r*tB)S$|n zPkfNf`13wg{$af1&qv9QKcC8@x3f$proz@jrDG}U<5hpYh*tgiA{biMFP~)lVDTi| z2lJ82dTUsDZ87nMJ&bKW@r5&tZ8q_RJB)2Q@r5^xZ8GtNKa6cW5o8CrtOu=c1KA0x z!{SwcK8#QO`5-#=r?@G@ln3dMvOW+r77Yy-*jOES-r;~TWc>@MT@2b|bHHq(F3f+? zSo~+M`tyac>dzP2Q2$MyWc#3hlI??TB>xG++-NcJg*c3DKJkS#jBPgYg*=RHI`M@v zjBPUUg*uFFJP~9E*nf?nb!^bO%v|;7L-W+14~$cP-Zx>G@*o=GKS`YaGez^C<;0hl zq5b%9EdJwH{rQ4h_2&y_sQ>CG**>VAWc#2T$$zg^5bekJFt+)`7oTBlvxzUh!`P-1 zU;Ku#O(wqh4`Ulo1la-hpQHLju$`dz<5&IpkU#b31MbwH%R&ANhxqRyXbcW({8>W% zX9k)3KVUv_Bg}unSp4@~<>!mXDnDP`R)MsSvnSa;NS|c;AQ{Pjhhc8CnE2v2jBP&g z#c3GZY~qXaFt+K$7nfmdlZh{`!`Q|XL3V)s$EY?DY$wQn&sBate4g_2!Q+&l`5^xV zL;SZAi~qoDI1ZRX{bdQB<8FhkSMkTEFZ{d?{9|TXbec+Gex7jfF zSxkH}AI3JH_+l}PZ8q`6av0lm;)~TVw#md7>tSr;i6A?`emkf#5o{;OZ~Ik#KHQ)3 z^TFv@r6H(Z9efuFpOmOB@kKn0Z9EZV2iR|*wR0dlL2;L_ z^7CPS%FhScDL+pdgYGPZ_>CDf){oTZMi~P>U^>xjFSOn7jKxpxDnDO1tNeUn4fT`s zB-;n#lWZRdBl$@g<}QngFVtad^NBCCVQjOBFZ5w-(}^#PVQiC$FU(^keOLbZ@O$#l2cMIFYJmJ^4e?tN)NkPNX{2!a zqwz#znBUB?`0c#%&ljhaf4(>j_1pc4whwMkw0&?L$#1J+?z5QqVm*v)KJmq77~5>( zi|sJB>BJYiVQiC$FZRRO#uGtyfc@qOx_et0Qg)nI{`v5H^3MmSlYf3RVwm#49O5@^ z&=@o*-azLw8#DfVv0VA*i^a-6U(ANO^Yld92gfJcJ~)iz&Ssch7875z!`S8%Uv$IR zW)olZ!`P-1UrdIvO(wpW4r3cn1la+0Cuq$b$WBlkELZ;daC!322aA(`9tXM87~)P) z|LuV^Xv~@MXDq1S9PRQGbY3=(Cggly(7BKtj4X)rv(e9k+%E9*JY9rAhE3-}qQfYQdpXqTT) z)g6C6X%G1MxH;hGBW8K6%jVGXNt+RI4y?B0&j<31KgB@jVn?H$J;)E~%Y)Az6lMgU zJqS8;6E=qYLYxsY4qPwr^F_75&ll2=KE_LN$Dc2x9e=*yX8Z{ncR$4m4HtgLpRc$b zf4&rk^jS1n89u_!G6bJ>_?rQ7p7wtR@Ypp6BiCy!R)&dOj9jldx5CcPX8ier9cmY| z~2dU?L%>_I2^Si^(*S{TpzG8R(`R2a^_&h~TR)?QGj2zvXl{r7aXH+wC zy!NWh{-IraYPL=-*X)<|0Y6_=2O!S7t`_+DvR(jmcJoA#eNX@Y7k|R-__KqF0diiz zYv{c^NO$sZI5Y%3W#-U&WY`e2n4ux4kK_OJ7a%`Z2mAz`Fa7GU{Y1}7jUO+o1Ae}$ z5BLc`=el0t=gVrSUDAv{*MrWv28AQP`%f;=S<#;ve!jZT@RO5~;U^oX!_Q}r86e{t z&l!Hcc+QUGCWfCc9<%>^_}u;HgU9YanM@jj9^Gf$`IxC82y{o#Q)aeRHk|*bzvg%U z`RcL5&zH{~e!h6^@bl4q$DL2a9l_^^zb+Q|`Knyt=gaHtKVMvC|M~E``_BiL-G9RT zc9^*#h==q4^cUieKS5__zswf+`66H7=fm=VpAU)yem>3*`1vS1;OFcQ3{zfwb^wLn zM%?FTGeFMIzV84&lN)hpBSP*!w<1!>IbivQh zcKF%J#Bc%c`Pq(a6JH-^`1$I*z|WVb1(43qcKG@7vI96Bzk%L0_2M)_41O;4Wrv?n zPCNX3aohpx`Po{abZ{M_@AYYipRdk4fb)|VFY@`>43P7)8QCVj-p}y!)nS33FONgd z`?eQA_yPU=>_)bUuMac)e05#m=gZ3iNatre{Cv3^;&!+@cRT!idfnmYi^Hhygq@$w z0CVSl2gumeZh@aK_6z)cush)A!~Fq2AKn-E`QWy|Pr;uIQ(oK;0H2?&7zP>FdZ_FO zKBvDLv|d#nl0P5FJN|sIo#Ced6NAVLQ27GA>oF5FcF5}R^YwA|pDz!y|9shOGZ9<{ ztY<*Xx1DdceQ>%NbH43@g394F&~g|y&j-54 z3Y4y3|3L1&q>I{bX4FYxoFw!qH^><$wd4%kn8u$n*v#~0HXAZ7D+_Mb04v;TZC z8nGRPc;sq0-400QAmOrEo&Epx7a%`>c1JCnKfC{Y_1zs&Hh*XT`SLT=uGtKbvKbVPu(G+B z;peM(q_Q~~S~jPnmCf1M%4Pv+b39tv z91V%z7tszsUxec+o4uiBvp-VV91KYdU9hs*8(cPTz*{yqGEIE#&hYb9xWLbs!ANDZ zx5Lku!Ju@=`5Im}BZXdFD+<>$*{ z_MebD4&+z8)MohkLLcImm)Z_LU+6phe4!3aA6$?&BiKFa4nJS8yMx<mzQ|_(`9c|Lmb}By7s?JlUr0mD;$nfA^+Fm_=DbsP0N-KorriDKNk)!t-H)}G zJ2P{CfbJg7uFM0s4gD%Jeq`02o1I zd?^kpE8Kr-RBHVI^-n1cmR)|Nq4wt#|nOmf!v7yZ>%KUlzOnT*2t@b0s6g z&lkn)KVLf6SgtteV7c-jgXIfn8_N}}4nJ3NI{aM4>+o~6pu^8Kq7FX~G#;=y*m%(9 zUAz0wb)pPE7dAH9ENE=7dDG7R^K~=(&sX*AKVMd}|9nx-4ykwI*?+!>hTad*Y&{Wv zPe3#~q-G4racK=zR&j9JOtatdC16osR4vEJH<__St1IRxQwmbZMpbu?R z=sSYf_<+TooqmGO;|H_-UBGt-fY_irRvsjS?o43#sln>}<0U_|oPwV5|Khms&J_#{ z;JZgb_i4P~XV?k7dsGX=2AT1I8&vK&fY!|I)L>+={4eY<@qe?;#J|;!EC1vlT5*6m z{@S1XeJlS~Gp_v4?Qrowv*^Va?4U6XiHR>3GyQzBoayJo)l5GhtY`Z9cr(+_N86bo zZQ9jNKVL0(`uTFZ)6dtNoqoRD&Ghs2ex{$Ve>44j`JL(KOJ*@hTL`rGlJS78BkKX% zhv|*B50V=(+d}1ywvUP%Z6D@0+CIo`w0$|B>F3Mk!V?ufp0@$12eo}T7$NI+UaWQk z=OOUDA=8|RH<{_D4d|@g=}w@#AGBV| zv+m3UwWS-OcOF33RK1w(^z+qxCqz3cp8w~|X#Ss1*gLq$9e7=uGC!nDvTw9~(BE$Rpu64nL3_LH3ugYG z59-@(A5^#7J}7Uueesy@=Y#xq+Xvb0whz+VZC@Pb`}rWg-S$CryX}K;kb0I?FWQ-Y zKGygD`AFLz($;gZmt_1N0K1F39J=0VIp5D0i}@gK@Nc($;N5Nuj&Dbc zi7zJe{e-a1C%%{tW1CHUF&oAidJIz@ zbUXcgP|Wnxnw3H1DahV-r=KrD>4lkd)vI*K8ZNBo{%0et9Ramn9UyCft{Fr9laIwe z{d_-PbVL2)+;0289?3t|P`854a;k^1%_hERhOtd2zG#QC4}!*sq5kRT`}wfn@8^SV zzn@hg|A6*C6f^x~hx+GXw$slS?MU-zV7Hoq*G;U3xiuM!Tg&-=z9@#e)x6#IfiaR> zlcDYaxiuZeHk_;=9p0f}317xjE70eIuSo{#r_wz+G)DPP2whz>i{NN3BAIJ~> zFt*vm7r`*L>BJY|Ft*V|kU3yK#Pj`p81MJBa!0Vs&d1>{ zJD+4b{d|S)7JaB&^!a|i(B}L3P~Y$818u*bsx1GfzXYXAeW#xfjGcZm@^W^+I1O>j zZES8?@AvbSKhw{roBe*iROkEoLYeR9Lv_EO50w3WGUYb}J?dxKDZui7ISd_P}E^Zk4%@Avb8wBJwAUCc}%w?sSrd;waQ>koCyYKU8Qa4}AK2--Ua zPH*ND9|SY~TwuX~BxW{o4hr9N;tUIhDWLrJFxctmlX67)4({JNSWFD~_kTM0Zm4i9 z=~bNX=L=zIdS!37eZY*AUYTKO(R|_yb{N}i;tOsV+jQa!ekdEX?oSw6K8W-Ed?@bs z^MSD6&mvvWy^fId`kxt5-oe_I57|NIJ(^E^#11;|5j1AcxT^LH)Veg#x|Y!;yaA3KM`aOIDh@;{rT{}@6QLneSf-v z+zT4_EoS<88S35#pn4OjJVSM}*~AGKpzamN;@;=HKVLkCy7zsX?St1y?!63ii}}PC z*I{h4i7#%$*rpR-+=sFoL3iZxLh6&}ygwg4_x<_cvF}eQkb6PvMT?n!E{D1oloqgu zuNinwRTUP#!dTpUp7-aA(@^(5ZnJ%GAIZJDp>6?{U;ANfvxzSb!`P-1UmSC)iAc{#24$KY)0LQAalU(+|K*+;dbAj z4>tS$JOXkjXf0#f|fMf4-Ovb>rza+Xu&y+}I7Z zALPb<7~5>(i^(vy>BJY)VQig=AalTOoX`97;e6kp4`%!RoDFg#HzaRq;Ea1Sl)SYG zwwHq)i+kI7f4*pjx_5t@?StJ&?k$G7#eCw6av0le;)`k++jQcKdMLXQv=$MXR@-@h zK5X~>`JmbNXFkZi>=5_<0j=MF*1xc{3TmT2V&>3-qyb1;)q}Own6bDwpZDjBY^ZxT zx7j{ekL2EHs9Qkc8xLcfO?;6IW1CKVkq%`a)S3t~2OPfnygwi2`~G~8?fcUia7eIR)q3(snKg6AoGVA*vXj=Wxh}otL=l%I280yaDZMF{IRTI-C=CA zi7&iiY}1J^{Gn_{t%)FW!0rs^{rNE5_veFP-=C5ocY@Y<7Bl@^1`XFo(6kB*TZmiD z!E>Ujr=f2Bjm53@ygy%9L)|*N&Gx}`B)4iq-2rl|K8$TP@r5yrZ94IVIgG725o8Y7 zt@gY>AKLr=d|>VS^PM)sln1{Z!R_B_s9RzA3g%W=IsoM_b68vJI~KR9^ZtCH40UUN zo9%;cB)1B~++jZPg*c3DHt~ftjBPscg*=oET5qHbO|R;_KOd_5{(PY9`|~i!t=}PT z4S>28cepaH;yVuw*Uwno%Fp}r1vk{K&26?1>XF>~n+H*E{fDv5Cca>Xy3f&c;tO^t z`ygoT5Y(;wygwiE`~G~u?fY{E$gQ6tZdHZ46;!Um!W0(&ka`x9w;r8?y7xU6_kQR3 z`QkGVq@FErvwcvEq*L;exj!Xh+84~Ydg%Xud%rGKF`k=x1ny$ZnJ%mj^x(UP^H%)dF0<_Q2fw z9E)3z^Za~q80yyeHrof$NN(K>bBFoF7u#WMvxzTu!`P-1U+jmn8&xNQ%mKUgIM2_A z$9;Z2IPCLN4CL155VtM{t!06hS)jHr%D!xH`_gpcv@OuS<6|stUC;CL#cHTqgWGH$ z_#?S>Hq;%UaGeihn@xPN7{)f8_+mMf4O%m`ng`N$S{hdh*)X@>$KuxMJU?GdhPu_g&Gvyal3Sah?f|*99mY1B_@W!eHl6sQ zAIfG_nFulm9In%Oem3oM3Lejm3@i zJU?GlL)~cIX8XV#$&J}i`$2BZhq28jz9@#VO((u6hq09>g3JNCv7YDW!+M{e52}5B zP6xU1HY7Y%U~UBUdD_wY1m+VZVD7w*#hvLqKVKw6-KpPZ`#>AXoxw0Sm`{8W4r7~5 zd=U*}n@)TY4`nwhO$3<(c4s=z&xh$gKOZFf{LBTp^E$+xzd+;C&@_r#R+&QEEs(OR z;v}@Jx{SrW{yaZlcthQ*+-Cbg9?8AdP`7}>)gHz+oA|;R#x|Y!!X3&!s5lX14%of^ zJU<`$`}}<1?eo(SqbBAdKWzWvDwq zZdHe|%_hFkhOtd2zR-uV85Jjj%mKUAoag65bDy6NjD3EJf!ul?;?~8`u*L3HP+Nd; zl@iRYr?I$Ip6BNaX{cMd+iV}OBe|6u>JE@w`C)9ci7$jpZk6Zx z`B2{H=L2b`EZ8q`6Zy4Kj;*0-KcBA}6kU3ztvh)0W$nNv=0khA~10c5^hq%?3fk6Z`rut$% zXuOnT)yw^$H82j4d+QG~g61nfu7<5qIqdlJ<$9-|TA+F7-Hbm~IURnourhpnvYqkg z3(%gGbbioS%mfZc?ujpw`F}o4_y74I+5e|fUSkkw4aWEX|E9m(?)dY?ZpWV-m6<7_5+-m#aJyLkxhK2W@8X}G2Q8BCKJO3%}U7l^6DPw+zn_fXSUPN z*YllzX2I4D^b7rb)h+b%DK}`pF6fLP)>RMs84-7H8+Y11(C@^&d)v9w_K|(3?L+HM z+Xv>Iwh!D-g4KcVHVzho`1^E&?F02r+Xu>>wh!bxZC@G-{d^$aY5PF9)Aj*>r|nB& zp`Q=fJ8d5@ciKMq-(mamv*6DM-#cs{eD1J)@V>+LO251x0}K6u<=``~_u?aR%A zKObE0uzhg3!}h`X4qNaT{Cr5-fbYd!3|ddcy6VMp#-C5(gML1a4uY%^I{>+3Dp?O& zAFpQo`2aRH-R}sQZ<#Lm^TlN7UE#+&Y#$u%uzj$S1jD zi7!C+qjQ7iEchmZ?n#HJ;hp%R8>WV5;){M5n|mV2juW7@anl8VKAax-^TFi6pA4Y* zT(;wG{&3F<(8HpW3nbsa){qi(;ss zws+V**xX_JU_FwbqG9e5nD`1Vu%L9KtC=UF2T7zNAgLa6Y4kGyp?w_Camtl3%1F(Pi!T$NB3yq^@EdB`>{P`jn z>YwEuwhtDA?tMq{k2TCq0ux`@!`S>2UpT|qd=p=|!`QqNUwFgVJQH8|!`PrZFa>{t z{Sz+u^I>@4&j-PQKc|EI(+u%XFH!#C1N-L~%s=&5{9`Wo^Mx_gKhryGA3*Q2hom9U z8R{@M2~2z;4`cIBe4z|u^G$rA4rB99e4!0v^Gtl94`Xvo1la-hkGbH_hvtDl9~cMz zOa}R<9^#)!WdAI7MC_+6XGH9$1;-ID*iRE-eyYaeCvm}_FNC3fYVWXp(A;7BpdKlX zehVP-(SI15f8q;fn0xsqzF>#3c_+T$hOv1jzTk(k*(ZYR0Q*T?@aIGEz@HC<1App) z`~=#|)Xn%)1<6my`3N-st%#BKc))d~qMf<_F*F4v9~`iJ-gPA#C1>FJ8mc@JxL19>xaUwK$ku*kUJm+3?C*2(sqwpuoh}*^u?7AV0p87W(}#_C?fqNr1dS)uyQ08*M?rG=X#3ingAn`LqCtB{gMPkA0ZraL?Se39+=^MN~L&mE{;!Su2A@&p#fDPZ@3>l49=FZ3CIz5vA`Gsmiz z#*ns8H>~Yr?D+GgebCRB+KfM+ItM}8J?e}Q|A5*%vxOjSp!rB)3~l%9{QGbEOLfPe zFSOCxJ^HBao_qiQi-YWkw|N$W=W(?(4qAfSJWrtY6s&&+DaUyyKIC?osCYndBIgfi zn^GA|emXAj^TlCkev0p~eGuJY`yd=CKdpx434w_(*2CER6JKnGvH2#x*bZa!PJ97c zX9*5Bo{6CKmf(Em$T|^Z2e_O#F7Wf=@qnKX4hQ^H0p%yqTFY+6pHiT)N38zff%-#W z;`Q%Pf5>C;$8v$6FBU`n0b5t@j^vMSm>UHqzUYUs`6s@Z3}f?6d@&uy=AHOrHjK?P z@x^>7+mU4=$PTbSmJ9rRxIEzJgT(oDcF(d{GQ_>p{MW zFUnzT-ihFK?O^ph6JLPVxr5lC`$L+KOZy){M-lfk2Iv5+XCuiL;V9w zUl4!rgU5l2U~wXj#SiHMKVKw6{h;4r`#`(H_JKN*AG~4i6PWnIAI9dN_#zm_=9~B; z9LDCI_yV-<4CL;EJQH8UL&Y7LCW7n$$4R=t&xh#&KOZCq{Okq!K^)?TW}I=t2TfbN z6CrWJGjTdBPK2@e$6es(3umZ*ZXGN6JO}V*!&Y;fY!Hx-OV=< zw9X9@SG*HnSi{utOnhMvWjiuX1la-hkGsInhwcGCA2-X|w@r$~^&lk#2zwme1K7g+Gg}4oL2Nu*lAiwa#*!&Y;2*cQX6JLnK*t`>8 zNW<7X6JN+f*^UeoL3V)sqAu|Bp?bj22g(6I)j)pXhxkPXn!X+`cKrEbxg&ht4x|j@ zpSXNIv>nQg#SiQPKVL9I{qVot_QCIV+Xvs<5q*W%{Ls2nVB(ASFgE|h7oTBlzKJis z!`QqNU;Ku#c_zO2&kyZS+fM}90rmsCz|V*50Y4uw2mJi13OXYM;)mCuGu8SXe?A25 z;l}U-&%`pAAK0<@;W_`$7muOqf!?>$+$}QA1 z#S2bT=Z`?kEM_czInMv{#bKyl?zh`MxZQ61;5w3DR>Rx|s!L#OP+bCJgX$6(8&sFT z*r2)u<`>(EAUnW*InMv{;c@?;4-WhPoCxv@GsG|LP``lZw3j==+s>%|;h8uG=9m8r znElY@{6AkThWh1vyX}M1?Y0k&Bl)Ep<~C4$0%L>f6Brv*pTO9l`UJ)X)h95&*h~c3 z0rtys{+|z*`~Q5f*#Bo7$S?mL!2Qq=^l=#Q{vhZ$%x}nAK=?S!ZwJIU%x4C~ILvzn zcpC)V?t`{V;B7u=dt~bGf74&SclZh3>w-KE^WA~;aTriq0*%AG2Cbv#|M{XB8kYOp zZ6EAzw|%f3DJ-*LVFRkmU~Eub24jQjG8h|Fm%-Sex(pVU))PT?fWxw#|L4PY|DO+< z{eNY~hR@(>rTQT=mTyC{}biUR0;ptY}2gh4& zA6!2QRtMi(!7MTH5hLRi(E3JD+6C=z0gtcT2Ce@Eo%_Ji{eqcs)rFXuLUh5A0w?I(?PmD-azDe*7l)zl*zWN2)ozEMulGat z^1N8g@bmR@hM%uigUsiAeTWI-t{00Pe!g7p@blGbho5iPJN$gJ+2QBw)lT5O1face zIh8p-)-rOu&aKS-(Or9Xc26zuY%fNh)tZdlyFlxQk?nm9YEK_WnCHdFwOW&rbJy!~ z@1Jjqy%BpeCNuneIi2C>tJw@cU(RRvslmix4oX8WKzkA*Z{QpD*S^{0rJw^>Vhu&sXyueuCCqzhRb`*j=gd z1HSIMocrg?Vs6m*>O@dnO#|(p1C4RscKE3U+CSF~3KvlPaCC#lM8R>}4>21Yr~RP4 zDj+qSuNT4A2)8531@4cvmtQhVOw`QG{sG#@=b5Sf0~9_l`Wb$H0EJ68+FpwFPCqp` zA?x(P>+PDMdnrKsP1Zx!6T-y7VFTJL1KL-^%7EDC1~LQWc4m%MuZp32Daw)dQdC3S z3*Spo>;M`&h3s?V=KlGTts&?oKljg<+}=N5@q7P#&F(NUn^A7!>wJcvua0y7e0i7~ zvCpm8;pfY0Q1~G2r9cvc?@_3B`1z#R;pdBd)IAEYy%Yt%{!M=Y+S60*@bh&sXk9y& zy%fm|5VstZo%lK(l(xBlzT6LWFFQBF56s*@Uow0De8moRyQAF1*V&*wdfY!>p5{jE za|79z3~@W$oyiVApVouc#G|?swwJ;U=FW6T9KGDk{qx0k?w=1fd;fg6-TUXm>)byd zT;~26{+eORi|gLteQxOVNN+Xs_dZ6EZv+Je?ffXZlaSs2dnle3ZGBPUBk5aYqlSx@Y} ze?GSMhL*(=;PE5Sm?wBGU^G&B813-$fj7g?*&u&`_NGX4L&lrkA^ryKzX9#5dEpF6 zi(Jt1@TD`PoB^+iJ}5DfgRyoKXfMJWdGDVZjGW!PA8RjnW#<0K=ymw<+L+-dcV*^} z3~2uMV&q;8+Hb+Z$i2(^t-~bH{tAwdrzV5S$d~2}KVMoi{Cr`LWWTk;&sX*iKVPXc z{CuGeamOj>IKxYAho7MR9-uunuk;;$zBYFFnZxMtv%50mM^9zukNny*vkPi@X8VBV zOQ7!R$jtr0#V7!F!wW|4U0#d=t2r3?cX=`Lt;XsmsC&TkETH`y+Mqoh44C^-#2J3R zlm_qX*aFJ)FG2fJK>Id8VWkgo7YB+PxK@M8DGo*s%y0nheNkrk`4Uw2n1l8r$bohCS5#%QBpRW!& zSe`uSV0r2wgXPPE43;NZ9e$qTbohCi*Wu?GL5H7bMIC-VXgpx^u<@YHdwuVp=S3NQ z9&Bv1IndZ(^H!hx=NoPApRd)qf4)-Y{`pcKlyBu%y%gvE`BIqs=ga?0;Ct6!JO^fyb$O9`B2>Z=L2EypC6P!>;53=3=}R8ydilB%#L>ew>!Y>=b(HC8Sewln>|?X z`11ifbbkjoq)o>SE4$@gQTKPSBkk{CXV?igj~%r45VW_*0ldHC!DPt(4AA{S|G6C| z{%01&zSo1@;o|?pOc!4?%S?PB&;0X&GV{-e>dZeMX*2(Ptk3-Oi81rfr{>H*pII}5 z{rZ5JL+gP(^G^<$zEA7(;v-z$CRpRcu@!S?*$ z&iwQLZswmalVvCVU(fvW|7PZ&uh%pGe6^YR=gaNPKRp>5f?n=s{`qRV^Us&NoquLC zFH}lVzhn;`EOAw$mzSA;g2wM2@;m>0!0r6= z(P5d1kC~+>YW!oE@&aU@H1p3Vpt@e)`R5Ce-x(c#zF=ks?~Q%Q4zW9dks;&-v-8iF z?9O1f^fEAnys&o$r%6>%x#kRED}mU|V0V9f@tf)Ai{DN^Uwmi!>B0PC`>XFxKVQP^ zV0HM(QJMAQ#e1fopfd$DE3>>&1c zCr}uH?RpBz$DnpUIIn=kH@*;`FXh3)VD>`Y8PtZ_@=)9P=L2=;pHG>kCq7Pg{`n-` z8B`W)F)=a-O$Ftl*GxYjFfeR+@Y?Aow)F8r8RUP4Ef18Pe?DQBp7u2>(|;yKgLmrM*Bw4OSE(~xE@*KANb#+RKT1P&0Ly#u#saYJXoUeV@7(!k?cLJr&Ak9Xmk1zJK?mP_&o5xN+ISw*^e6fAL6bB=N z5J>#Re%GBGvJ6Ep*yl@u)5$@ei7%s>f39S02znXM{PSV7^Up`|&OaY3OHBmJJ91Ba z>COyk?|3u+JQ>>%^l~=a&P-6cn$HH^uf#j?Wia#4Os0mQm*LDm85kLaKwy8=bw+Xoqs;ocmDb8y3@}m$<9BYraS-4YG9c1;5O4w4h{y9hs@FwUnV>M ze39<_^W}cFpDzxx{e0kTGV#HArk}95$k@?B`6BqwunDSshBtBoXyY2+-pI78$nE2G$ zWa8s)x1Ue?-F|}79eB+1IMdGq%nV!pKWF{<|26B+2hDmDA8d!Xi-Q&7rhZVEYrZ_7nDyt2=d3?hfWiS} z-gDQV4_~|feB^90F;$Ua$^+0{)2Eq!E@Ed80p)p6TL=_pnw$(1U&gcj{C}GD=l}B{ zJMO$Skh~3vXkP+dz8^L2m1Yx~(7Tw#iVpO^3Q|HtWw9 z^Pz47nK$3{=flMiw{e2)gSgEN19IDZXj;gJx~&-MwsNT3s-bSHXZ`u28R|BWdCjh%G!0G*j})MHdY)$bDbLOz z0xzErI#_BRbg+D>&ARi2KI_i^hm9;BC>u`v|Jcy-p|i=vKuv}z9qbK3FPS;CICxIZ z;;7}E&B4I&`o(OfpB!%)K4x(-guI;X^fQCKA&7~Q^Yx>CCKNwEWHthi>Ggr;YbQhf zo6h?4e>N!XYfXI6jq2YEe;KB{=!W_?80z0}sDGoO{*8zFH<|V4i*%@eLFT2q{(P7X ziHl_*|AOu|1m%A=29ZboPN?ouHUzsX1LUrDsJpybfByGp{rO=U&hno_?pFFY1|o zGK1oUaGtOe3=ibM;Si8EN1%2$jJHnVL1~@ ze*ChMVakJQsDJcXfBrXS{rTXq#>5B7sQxJf`6n6bA8Dw6K|>^pD*;G z{sEb%@A~thF~mPUApd~wCOggavy+WM1k`T(|CsIP|L1H!UmiA_`2RNB&;R$?e!gNh zn)vEA+s{|Zh7(`iXZ!i`F&nr}eEFR1=c~tVKVLp~1GTF*fZJ8a*&ywz(`-MrdmDmY z&*p`+tLF29+Ep8}8Tlr@zRdQso2en_^>wzNuU@nLeEA-P-G07|X8QRep6MrOKi`XZ zaNA(wi*QJL1Kh3(2ko76gSD$RXku$u`7=Sv}XGG!k+2pOKYc}FYKXVX^s?@<{&q_;}1)HXjmFE{e0!k{_~|jJ0vWPL1%)2 z!qO5Pmi3^p1es?K4NG;mpD)yze!g^e`}tBEVkbBZ)j{WNyU-u5O(_c zQXFCjyiKai^b_7DRc3;m!z7Kc<2kHNs?7BBg)%5yn0^*AK=T7X`_KQvXmJRNJ5U^g z@&hOi`Jr(r%>MHgzx&UZ!boxW8=4>fvq9pJ85)P|NO8yxjYDqspRdH(f4-CkVfUXe zxtV^x;Ai^zlH2L$3x2SBC%#~Z_!XQVKxY|>6NtnAjF9}m%=Gh>Jp0d=%Fs9j?dkdN z`18?Wb8sB;f#MKk9zQe=o!x%E_|EtfTyFgat>1&T`M*2}05LfVhtSs?Al-z<>!<9`-N`;i%1wzISTe8CMZ+d<}WyZ(I04=LNP%7NPQj^MVI z5Gyn-r?db3pA9;P3QyUd4o%D1>_1+j1bVd8^!KFL1({%&ZU2O+VSU$^Wb=!_~JMu&cSK_aG%X)y z{Q0UJat;T$&wLnizWSqPD{xwl{>3om1<1VfjF@G6IWuP2Uha%2+qW}<>vM3~4qBfK zT6ese5mL67J0r^W{p>&ggU<6p8h5}b+xJ7m@-X|)SNq+6zC4T+maCy*xgJ`!C-Xzf z_H=$k*}ffGF6?Ii`3iJ?*lG5kFHgJwdE_UVj}vVArr{=jAX zbjP1BXG8KVyj+-!R4z=0mJ8FtasTlJ=uCOg9AG!JTmYRN4=dZ784+bW=)8AEXxY>3 z`155u#1445Fd3;_m<%l!x)FB3%Z15|KVM9C{0Un34KLd#v;X`*oj}<>85)Pv*?+#8 z?EdrRbfh?}hsI$uG!D6;ambGphuzRP>}UV^YBu}Nm-9i`{pU;2nez3FKVMcm{(Mmn zcJIU&<&f|M=LgVQf!PG&FdrI+#f(2+EoT4uayc{(iyePH0G}~$4UWU5b87U5vp>dcFcJD{fy1^Imjz3>SL*pW5J8i&ycJK%Ac%=q&~G9(UPYzCQuTDEuo`!5bUHvqYh z3u=2eE@znX0<;InpYi9*d?)Z4MbJ7&(0I=2B!-X|-j3k(4C4DTFof_jGl;w@cKZ3! z8{(fA){NkG(hGaWpWwCg&PaZ9hxknqH1_80_!F!z+3hFjJWnoGhL0Q!4=;hvD$-+M z5P9tE`16swo=GpE*iM#hgE9~nM^>^Q~ia`}Yn ziCG*UnOB`tJU9`+O-5hJTa5{k``2Qd$fQA2}F1r5>0wg6On6??$=%*cfWO*1adcAo>_hsvivK3#-CceT-~7a1VQr^;JHH3IZMWjKVRxQ{(NEV z`16G_D8Af~>&TBBAafZRQ2IR&oDINzYtY!-10~RTZB9R5^1J+1W^y81D+u71t}8S8n?^7F-e7RXo+$h`M1KOcT}0r&4;$uLZL z09sFXn(3!H=$u_pdi?DA^CdsyPYzCok1vGL{Lc;bzc3_yg7?I5GyZ%HN`L&0KVNb? zg2o>wd4l{8GRNKRXAUdFN6>k&o~#T%UqQt*E3_7j%M{Og# zb~c#!8r1&-_5EH$%ft8VKVQ9e|M~JgQh9hCS{~kpwhwkg%ftP!@{n)h>&MXc!E^SX zub^iezWna~^CdIntlO8+b8f+P8u)BnXr1;SwC;pJdH9_H($@XW@blGg_Mb2RL(9Y8 z4nH4!clh~eu^qTP4F16|(fS;azMnA%q~DM&0BIlO3xL`O6S6_`6V@D%zMnnE&sW|YKVSNTu*c7r zk3r`#GW>k`7&MLzp0A$>S`z{)-?W$+Lcr?)ygk5WS|$_21g!n&>(H>g&G7S8FvriA z;T%6f`>r0|cKG?=y2DTKzT^Z(aCrU)ox=xOFY=t>CwT3|d)J>Y&NKXc$?f*@h` zCAfY$4>=bWJhDUMQ5YJJ;z;qx4~<7*j-RjOIexxW24Rn% zpz~f|Y-jlSa?jc92$?S8GgP}=lJZ-&H!mMbGw1pq`Z9Z`t#*th@Id#obT}SaKgh11Y_;XKRF7nh;+0?53}E=<1|GQa!K44az_@Ers{ydQV6`1H{0ds!}$<5$%EWf3~^HoXq_|CJPo|R z?QAeHXW#$n53-@|s%QE6znSId183!l57JTHr3`XcI@Dd+PAS2@&O)hs_> z)I;3`GOym{=fh@*yM9VBOnHzEahDk=t`0-S6CL>(LQvWl(DVkIOGpIyCmHI_WR{=* z(^-B#NLHE%T4Mv6?}CjB`~>As(D}5WwuV2{oxxCdhC|&M4RvQc%g-0dPNnKyexkb(1^G&;Q;mKOZzJPJ9rK8g^GeZUUX}3UZS%)J^74 zH(5j7WDj+dGt18x?oc;@%yW17`Oq8Urd1#}f!5!gX8QRYv^Ez-+hx!nA zwSe3e3<;})p!O!HU7L)(JqzkXaIi9beBsad^ZB3u;-E71VYl1QNBwR;LGxPin?YxP zviy7~42qisOXyf~(2MEN^%|f#{eupcAUVF5d0u>v*=GT#O7qxeq#6zFJ&t`FgRjCD%a)O9e%SiHwR26CXM= zfZMt+j2V7%usHmDVb1WAgTvwH3u}g-96S!-HAWl)khL|i^cMA(A^H>>v=5jLp%;9DDnI*{Z6EtSt zz`zg!9zzLd*a?~+;Q-BXhBNGZsqFmoMYzLG(0**teE$kghAofM(dKuc^G=nZc{X)u ze6zFs{Lc+ahw>92D5IuBBT#%RL*x51Gi1!{J2Pa=>^C!H%P8GdSWGW^uyW%#Kf2wexq&hYd9Yv!N--!uPwuvl*517_4P zdHaoF$_r*_m|Ta3$!%zu+=qtAV`!K>Xa4!(H8Z4d0y6Kl^UsIxoxy#R!;%bBUa*7K z0yF)5aoXwUi`z^;AKb>i?gD;B>|ySUFPzyXzNlvS`Lv$l=c8tZpAXv^em>}C`1z!t z;pgMYkTq>DnjL6`nQPU9Vuqgyj0bEJ zSr6DMIyTrU*f!WEa2~Kt){0S|dla{LF@~ z2?U)<&&lfW^JOx_PgYI`$Qpmh-opvtvlf&Ye?C-q{P{rH@#mwYhM;Cv$lV!F;u(I< zdjD_w%Xo*MFTm?f9V}m_GyFt3M>riChoH6^sQ!#*_z4ed(0S?7pgsQbt3ds7P~Y~U zJf>f9g%_yY0Id(JRA86_K6@Rs*9x?MOxW?~Lvc)VKymhxSzhbqdWN0wGk}{R>(eX8_NO^T5`WH$%=y*95KaQ9L!vi;?l; zD`xpsnucAoKz*14uzNE6!R^qApf#%RKyyj$AiEuYzH~+kcYa3D+yW%rxfy>x1nqC) zcKrD$r6K4sGc?@Y8GhP;!rj^7=No^ApRe6P_ZL9c?P@VJ1bHc*nbpI{_|eO-dlqPn zMw5}N>!mkRxP#7q2lb;tX^5Ti=L2TPpAXqF!wVGdkNmNxRT)s2gUtEO@bdv^-^*`@ zpAY{#V9zJK3?COl!wR%k8aeI5_5vDaFid&)o#E$$&kR3bes=iz;=9Aom!P)!dxoD6 zUOW7J_#V@2ko#VM+OOFTKVMZl`~jN$;5;dgls2|A{PbXA_yEq6n;CvS1f2oC+2LnXMne!YdqdFncmJlp0huQb zsTW>@(xp6TZC=g~j*pzHUNUp7dI?%13o5778GgQkx)n5z_=cHt)f;VwpKqACSG~~( zm0{ekU#QQQ@?vBFrDZJ+#xALs#tc7SK=&>@RCf6JK;7ZzBYlUTkF_0sGJXCx{gt-E z&o}xGKVO2*r&k8W2g9ld%-pMTYq@4;)t;H{#mL*8UCRU7&+wXqk?YsX-3&ip>}UA- zz!(x<;IJ@u`1wMZ;pdC=2h2-uhMyYHGeaJN`U%c#69ttSro037$GRbV zBtZLGUY%z637W6d0>`ntSc!2B0`JnqTKzoH5!0To~@(-6g{Cu$3;pcO4hAA((!E1HFdrLs~nLL>8@blqp z%=8McZ^7$y885zQmYxV&&-vg#XuSyY&qwUcKOb{5|9ryF{PU?W(i&ZH=o(#V=AREi zYfJf^f4<~){`pd#`R5B|=ASQ%nSZ`02d&kWg0I!R{Doo4OVBz|cIaB&#gMhS9So4Q zx-Y&n{jA_%5P8M!{PQ(vZ7D;;r2o^IfBv5hYGcSu{NK;~^Z#V#pRfCwf4-W`{PX2> z=-S-b%s*dEcmDZuw)0PKCWa5-v9D_A+T42R+FWMn+FW+_onSSfv9EUM+T3pDpRblP z|9rU`gq?rBe9!dr#b>6UFW)=;d;waU3c4HMHPW247!eCMC99y9%Xx!C#V%jZl#U#(~U`EoOKZSHfYpAQ~8{d{y-dg5bdsfmuC8K%4d znfDnoXa15Mv`!Vee)Klv4D*-wA$EhuPHsE>e0d)r6jiTnCG9TnL)i_zyCNVatR6PCuV8OHF*_ z?ELewJIJr{TA(re&oZDgSAG>J4SWZ!RRpg;2JP2k`gxLx;R4n*w1+|GMnTum?#Hr* z_At^K+H&X`+Wly2Xvhmp#{e$Xbr73bPcUNWDWWwd(awM$%$Zj&>C8G=o(sW z=o;E+=o;F1ww+)#jl2_I8bjC6n#0!6N=9K^UufZ&Oe`RcKZ3m z+4<*FcW2NT(5jiG3{yaBLN|lf5Hd?mdByCuo|(3_Ae+6 z{dW5K^1sv1N1*fXpBqecfUTcRX8ZX+9khPdXyX59wx9pw*?zu+(l3&s>u1y1em+Qc z`}r{4?Wf1q|IpA2jPu1nosY?z`^?g~w#j+BU<9FF|WcnGGkt+|K&*rLw`qm%Bl0 z+w>>C+z(p+pf~a5Vb-57jziZ!oM!#`;JEA0ho?d7AB-nX6@#vsT+Z~<50oaEox%69 zfaZQQLF;Gj*?#_C&HD2{X#Fa)?nKb~(*Mgr>u2>RzFN%s^Hs9m#8=B%e}dMzzF5!t z^TBG@pAXlA*3TMGe3b3>^Kri0PiIj7v>&=&Z#L`C|MNlXXLT^vMRtMw1YQ?uIPqmW zXuY1{#FwD8svtjs)~Y(|PkaeltD3Ag@#S>ZpD$)Z{RA>^w(HM_^C5mp0QspO60efr z^yU2XsWT#+A21`;jpAVZMZnFg22XWgcHU^Q0>}YONhRpGS)>1D4sjY{G zTQcj<|LLIhvsx2DYafx*f(^)R)zGxy4|N-8T`9)I{p@3woiCoV?EHV&(DH$@!NmWM4J;oz8&7PM!?Aw0 z9I}2^3$%W=9BKV*Hfa4UB0e56L)NM8lVzClARp>qch;Z(y+P||H77nuhvZ4vm2ju@)@;zVREODq z{yz>{Cu=(K|8BOQ|M!E|$r?_4wHvff)?nhR{UAB$I@#lFKVKbo`}y*?8={S~9J(%W zHFTY9G<2P8JTJ73!#DBuW;V!Ls_kq)U!7+A`SLsnyZw9#y1&Ai34Z?sc&^kMQul-B zg+OaQPlM)IGJk;UGtfF&^frz$w2foV^z+qawx2JrL)XcgL+*xnq-;9zv9s|+j*kpe zUVzMVhO}{B97dWejR&ohEwp_37-_CF-UTsNs*SWxR-5VP3vDOxx=`>s*?6RNveN87 z|AW>hCL`L3uapfYz5=xsnGGj`+l$iBd1ra{pRc6df4-D=M}#Fibl#a8x(-Jgx-Lzg z4;q&I6JHBM*Wrk>|9qv){_~|e2!qT4t@&j7`4Y6wR2kgnnfL;<-W0Z$3bf`_88YvT zGb}-CQ90Lhvf(UiLaltLFT(( zv;BPao$cq#-yrPv^Cf7F>1W2DFW)kiC%S;*5MjAqP_%jP+o$Pm(pASB}{CxP`1-?$U^VPrUFG2cu zJ0h#IUdmdD$pDcXnz%Gjz@3e%jYaVU%ZBn`Gd@R?eg>Cd(fD_@kDMB(Ecw+ za9jBZ3$$!^XaD&hwBG$Np0eE?S{`|`|9s`{{_~|bxIBXFEj5OgN9NFVFvZaFs2p4# zUC0LQfv|_JgK=j6`O2UD=gVLacK`WuJtKIH;>-1*b#CCaG4aJ}NSuSqcF>wne|ULx z0c-ztF(ah^x}5Rnt8n(8FQcJpdAZ}y2a6qlK5DiEmq!ypcVmLg1FdfbjiDfy?e?H` zvS?+yJ<>Ya*+}bTXM@fNbo}{ZI&__^J<>Ya`RqUcgVrV@mkXfs08}o3$_G%nFdrJ0 zi`jp^n(zMe+4f=S$E!)5*}V1g$rPl?$LXr^^Y1C1@=ws9b1g{P}7<`_Gq~puoMH~ zXuUOZ9D?Ew6o;U=1jS)7G!Dzzf4%~(_bx|@!+2;MCPU-!G&Db)hvf(UiLbMvahT8k z^Hnwb&zGQk7VF)AzKjR0A!Pjd612`V8SLJP;Ps}kI0UUZttJqMptY!=I1Fd}`Kp=y z=gW3z9ELmod=TvT^U-6_x^d%)XWxP58ytVWNQTBCsBHI!mhJvXaR^$U=Z{vlyCcP+ zJ2Vcx!S4O|!kO{s3(#4T_Ru)A2bH_fvfZ5VC%kO8MzX`)@#jlxh#l}abVrIqcW4}f z){uhcot=@&c6Y{~FWe#d@daqTHCovYUMCw48n-~SsX_go?QKphv*>9qjb;g*0TX zFvdDrm^^5mth3usnEWeY9P4Do8GpVMcKivtTmA(*D1BgGSMbCcDUO`=;p=3@Bp9Z= z0EHoFeHJ%#oh)d*C?nE3S!U=uQGQsNk@@2VGsIqyUtV!L{(QjcL^vi4T6G&P98H%0|%HW1#-y zZfIS-A6i#~)P-Z%lRXa_zheLSAGB`*sg3a3S%2bdQ2!6q_d5+O56`pzdH8@|*H@}@{CuVC@$;p+2dM7{X>0LA*H;Qd*H>yo z*H`KbAle7g(Djw_96w)abNqa%55gWlUmgdo_hk6_5_G27Y4Ci~MDSWuM$XsZb+VxK zrrMD8m7buxV6pY1LF-UKb<2K+pRbHLe!et^u9MyG@bkfL$ofjB1O{*$!4wppATv)x z*U6rD{rO@u!_SwmU4OpZ4v9l>8v%4bHE6vjavNbibd4pbUB4c>#&R>*%^zQY=Fe6; zfajUO>tvTZ{Csg4x=waJ!%xr}PH-DxF_Ilf>p0={%X;V-zQb~a9q=~7dWN4b zKx;+MGa%Xs-`Riu2d%kAjz>`Zf#MMqpP)9vcW9pY%?`eI{^f6^JnMJ$fA*g*nK^#GWcGm1lf4A3Go1}~@5C3N^`@{k0%*WDb+Y9MJK%9x&+rp;ei>+;HfT4`8w9XM}oh&=JjWZFn?gV3}|52e~O2>ZWw4n?UPQL2d%AO9iSL{!k7xP$Kbhs{181d)ptI1B z-4zLPmp9a1-cWae)}eyj1zLv+au;YFD#%^YEI(hwL)`^3FW%+n!(@oN^g-?doz1nJ z3ACR;1U8-sStpBd;{#}VgRPUD4$|ii4L@g=pa0!K>tq!tK5#~jQ+<#-ouTg3hq@EA zHWlPf(ArdxJFTJP0`@FFUpPbE2{O;w<>y0ph&x%q_CdmL9|MEPLo9LH0g6+5sGHPT ze*V`6txr^#_`n*~Ow1^sGC6Msk{7q zs10$`1Ac}n59}dsnh9PfiwG~|IDNP7|MUmuP&0m6H$ms>f%Zm%)@g#)Z%RYg$%58vg4W3@L)UL=Bi3(Dc*8K| z!+)or@5LQ{zLR$N`BvWH=Nr%(8Fh!Bpmj4ZAG_>)@!W;*I$3$7b+YmdJ3;foFXW-? zWI^jlxEX%_Kh6B}|9Q}QPuYo}^Wc!YQr+JnspY#+>Sum!INV`th4Guu&-Ap~qEyAyal^TTG& zi7!F>9zlKg<%~Z;<8}|4x#4Cqy#b|3P+!dP=PPwi@I3#6-3_)}j1E7w8A0cVa=(80 zo8jk+{|rA@f%ZBIL-z8)#2$d$^Ba_=9e#rLbAk4GfzGP}^$9>{LxI-SaWH_|4GcfE zSQ#e10`-en8iKqU89p*z?VR?Kpz+V|43IOozJuET3_mY| z^6+PepOF5c{3_5sLh#v|pmzLqXy4Vwb zzJ2WQ^VNNapWLht;4^T&Dl>nqWp((uwlebvXw8@xBTsi$rRERNS{80z&h9Kmho2sQ zYc6}eb(oaJ$nX=iuN1U@?8S9xd-=4(&zGR}S`R?ho4WTgU+3H{Q2;* z<4>l-#vs^vx^tfVoBndX!_OD99e%!^4oQ2UbCbPzxw|#%+YV!0rI`bwGQ?7&%{q-7(qW=hOM1eTja)%FD-~vAKpI##+wV zvyJ{w2j$I&&D;~eNia-#aGL>qMmFfo%?Q~KdYc)tAM`#m zsGqw5JP!Vu5i&pao$==@(7Yn(>==G0aK8k+*RCD1o)|no2HMvK>mPykm4W6GE5Y+) zkaLxeGeXX*gvR-+Y6kFJ)605>pRYjko#IT8eT1O>Y1IxtA1U)seB8`AvF0Vi6wrEX zkbU6uDnV@lkl#UNbTI?u%*1j?Is^B0L1!<6`X`Lgev&e1teXL{CQco~2Cs<&^>aYu zoY@RNUt~M{1obz-=T(B%p2O^bt%-{Vl^xJEamh$_f%+QY_3Y6864Wm6nmDLk;686U zw7-`y*b0))m`3{Cw&RT9koF$dMxeq^9g898+xAJvlWoNQ{c5>!45wkm^1ub z2P)_NA$bk7#u;AD>ofd(Va)LJC1@SEzQfN~#;9iwgUfksX!)rQ*&FoA9%niK+KZ9r zHD)<~Jm*dh=2dy=LxC`tKe$d)_ zh`YeR*p6L~aDWJ2JI2a*itBWDDY&|S6alSai6i~Va_ci(%em>|2t%*i$*Zn`tc=2yF z+e&czn496}BYuXTkA)e2J`rd5`BdED=M!OvpN~Q3LvuU)e8>)3As0CW5`c)QnGW)7jgZA9WL-w;g0JVLM8Gk-D zXZ)#l_y6<<{LuC;zvIvU&LSx7-De=Z(vCkLf%>Dyjz6E8JN|rP&G_@FJ*2(-keO-K zgqNT&V+6P9Ky4h*{6Yh0yd2av29?90wlb*9ltyhUH-gGBP+xi+hAA(l9e;w_@voLc+sKFUw2?vcF(5ZU+s&Y`eEFM#HZn8M#K+B!KcBQC z+Q{~T3{xI_$I(Ux`Hh*3HnQ*#X(NN&xf!z^PjMR=lzs`fktcxLd7!hBK<&JG#-9(W z9e+Nocl`MX+D88HkU$$**b()93gkAjFj6^=t&I%Q3(7Ckk;-w*HZsJGpmrz7jkg(p zzPj%C^Tln)pRevS{(SKm(G~@l<4A2{aQTVE2bZ6)Hu8PPpAR2H+NQ8J^5utUZDe6b zNWTiXjSOv(QHu0di)_ zcW4{=H?)oX8`?(x4{jqv&P-uug0zuAZER`Kx<3#mvW*NnGZNB9hMbvl9oj~Q#yPl+ z3|jXEY9lK%{d}p8)<#~;Kk+d$*Tl`w(Avn*@(y(N{R?8+$e?kHd}tdPv?o2E0kUrd zUmF=_2dQmjs9oSTGSn`-ZDeS9jJ1snDyKp6ur@NN?8MbZMy@BIZIcJif+%g|b@qxUWRP2t%Xw&fm0%kgRDKSIHZsT^ z)NUh#%17k8e~{bA$Ym?GHZn*rsBFdGMuwDO*vi&ork^j$5p7X$*^1OA2A63_d~n$c zYag`hLf+(C7P!_O5=3|n7-)=h!N0zqtN$Db=08MZudcKrFI zS$yK7&rUxde~08*(B88U(42@hq^%3u)BnJp@h9lsZt5&Ff%f*z(ZZ@h7^O zpSVE%3#eJi%cwi#xUi9y5rA>?v6iSggfng z+AKct@n@%>Prf^W?<+XX$uQ-CKI2aZ7KSbVr!)QhKbz_2i)4|B|NEJK{+|pQe-fSe zvY+Ya%f})UUruKF`C>W~F0}fCh++Fi*BZ$589o6KJ0e-X$rO<;%`l61`$wrBfIgzV-fIL zCeVJM1t7K3P`6ey{rq3g^z%it@WlVcOh5mZL)}^obt@>(S3})e&-C*FG!KE@D$e** z9OPEe83EZ$KmUXJs>;F>|EELU3ObiP8|v14CU_r}3v55ct^b%9L_lHwzgf)k1;~y6 z8Gim>ENc0%S$yI{X2zc@1R18hWM)_eT89L>YwsbmW>{0X}A?$z@7Qm^Ehc6u=~6mbZ4&Vrro2O2j3_34nq=piWX znHg7^gXSWCGeF|fpXulSV9=fgp^5+9nSTEFhK7$jG<=}rNuYghFM^qVKJa(?`7jt7 zm){wFp66hg^60z6&;RyJKmUWyNIon$@xL`Re4uBBgYr7){NxArPCp+yJN-Pw!7$|k z=nOr3#-H1m7(_7K`B((JpNJRa&d*SH8Z-U;Zw@*KUvT1oZKj|9^`Y+6hPqRq>E{b$ zXgr!T{d{2T^z)%P)Sd4cel7*M6LdC!GSkoh>P$ahJQkSvUmogC(7E8s(0Ej5`uRZF z>E}arr=K%G?)>Zk&bK|F{w_OY{sz>>UBJo^0*VvRnmf>42iU^-E~qSd4Ryab)6f6X zpm-IS2x@=+2aS0i7M=JK)CL9R8DXZMFT|nlmuC9;K-}r)Lush{pELX{1-bvZ19+?# z)P{Y*EHLpuGt~W{{Tl30_j5D-e8BGX^C7p>&kT_JL3dHwGyaSLxnJIC=L%K^Gf*EM ztGl7$z8>W6$53}e$CO_*^H2Q$nepd;&>7w!cZ2pvfZY9^@#l-*jF7zkpYi8|-;O^Y zg3bX4<@NgvKixs@zVGn!|7*sd|3UjIl=&zAe-2ttE;jKcwBG;!|MzD8`QINjA1O8QzccgC|L)8`UmX^m_{y32 z=c~se6JLSuv+;)R1@~wE`O4e*=SzR*pW3j!;QG+L;Kt05GpDoJAmiToY&*efKx^r( znIZe6?3sVQie~-^x;y7(yz|eO*Fod(3_o99hu&EUS}O-Vj}SbD30jjD4cQB>3EK-E z4BZPJ&iwOLurqjm>t(p}&zI*x=VUVfe3=g23l6#m@3h0uN6C^CA2*9n-1nGa3V4m% zZRon7<}k!sxqil-FPg(FUoH+std;9WS}S)LX{{V+J`2<@-p>FzbGqLVapv@9=AWSZ zu3kQtp7_6>`RD&;Xc*Q*!?YQ)R~>xk)ppPwSk6CRZbu5s`OvUj4Bc1n4c%Ao&khYs z{)wQwu1x^0Kdse$JZz;}E?*Bye+DBMjTELSu9 z1c&8%hM%uMbJ544VF^9+;n8Cma9C!8!V+vAG%V*kfzMBPx!dXI%jKZ)Zs;Bx=$)US z{0-hu4_YHWAG*d0bWZSm=o%}~d4-_4gV_w=`6bYt7kHfjcf#)as9e%!q_KU&mBJ%Q2V$q zc02t9^=)5*?!&=1{{sr&e55$chsGh6zAZQoL2JE0=K_H4DT@cK;e*B@zIh+09q>5J zXMmguiZt&7k3-PB59oX)(3vWrb46JhJ{|W{Z2n$xI@oi1I^oj&ISXWIRsi;5)55i5{+0}^7Apn zl(+5=}OUXJeT1$ll@S z|MQGL|AY3dIrB~Ye;QgpoM!w9I^!Q)KU`+~`QSWco_7-)!;}Z0`73+IpUW5+L_lr7 z2j&bv!EGvIhM&Rw3{##OgU+yGT=mf0;pc>;?Hl-{I%~)r>#?gZ5l0^G^J~9O{qdkhL3Nf2?Qx`Czr<&xh+Be>Q;pVGU_tlrS)e zxc&Ptj@}k}0BX}87MLHFH*!(5%=XA;P*>JC5u_cQ+d4?4%*nP=kvZm3(k8GpX$hs-m) zn9TU|LBHeAhm#$DhO#kCc>$WEvuFJ230e~X>VGX3oA^?m;phKkaZB);sOwHYUtecJ zoE?}PZuvS{+!E#NK+t^KZBV-wnr=b!SfF$Zn(qRoThQ5dptA!(b8^r-(7YcrOnK+* z`138h!_POMIVXOHpRa@+e!c|V0V?f)^-R0}&5S?)w}a;QxhMXwX8iddbT&RHU4r&d zfx@Vs@#l+XXc)DF*6KL^eAo_+Pi2Oml5C*6Bti4g4nO}FGyeP!+Q*d4J@G&2jQo7i z9x7-Uf#xuZ9e+M7cl^l%3M0_|A<*0j=qxyAIh47U|IEx6|5kIagv|*((q{PiSfAnN z6Jv&-PeFZb(EX>Nxlzy@X)vg6WB8fD$gmZ3-q8bPho4Oh4nLbg>&TcP=cKIUW|;D~ z+I!`HW@hmG(NlAWpAXd?euC64W^nkq1gaL)CyEB8HF?PWv=6}ZP6&OVcm=dj&Fs+W~T~BrjJt=)8Q;d1;{X5mZ(@ba(iv zagbpONbM7G2gLdrcF6h}4VZn_Q2Xo|em<~v`1#P@;b&8ALy$A*{=?h_>I=)8XLT`r7VU7)j}ngvkf3qD@LEOzn1 zeTJV8A2a-X1UmEjHRK#8@c77k2FUuh&kR2wg4Q2B2d%Gk`1umtr)B#2z*z`BE>Z`o zBkw!>eEFOoGA^Rt2wr0byN61Hk-_XgvydgIpZCDo>E}atr=S0s#Zc1di~FGX0bz!Z zpmXlPdJYR({S#cCWa4Qjyw}zf%cq$ z&H&J7`uRZH>E}azr=QNu4M7|Npmf2ZRR@YISUbHk6LjbJN6=oe|IC7xp#C4MkB9F6 z2lpL*K5-VB_{iJo=VO1TpBlUkK@XWZv>t9}_*who|MaJzv(%)Sem<0E`uRlK>E{zr zJq}tIv76y12RIGMfcJdB(-Wv)2b#wbXZra-*y-m(ai^b28ybQ@ZVd&w5qb|jXrCMC zoJdE|x~JU^KmR)mSiazA`uTv{>E}a!%rJkD%s=tLYRJ0ahw+T?@gC+!3{ybooxO;6 z-1*d5XyRjUr=L&!oqlTmnG@70yS(TjGbi{y#4URnraaip@H2s#Vaton4nO}Z^IL-M zRC@8;5!^O@0os$koZ;txSp9yOZz8yEPv)Qa5?ZH&^EGmv?kqG>f6o8upmWDS=Z~R> z?Zf+^F?EES9)bM8%(SZI>;LHw=0n{w-{I%~WRV@;**C0Q0D4v|vxuYS7 zgORf<0~CIf9e(~_%xn2#H{;J2pmk&IpuUacPtckrP+I`ho_OKRI}y}20J|A_-wwzu z(ETy6^G1vAe?P~8o7Q#0ew7wu3tbu<2a(C+y2VK>B0 zQ$cPjcli0R8oQf7_toNzyM^%QqwWW#IUMyr zDE{(6?#g%g2|6nfJ^h2m&R^mSt0^;sJo(YwrOa&!8V7%o?g(C^_9ENy=ZkEHpa0_- zfBpxpGd|2U@qaWlFGMr`1l^$nPFKl{KOe+9{(P7W2`^8OyV4zgKFr1*UMrb#$6@Ef z*+C~;7ovt&GneHH(0G2Z7-MG^mdRS{oA0 z@bkYp(&J zP&tNNM}W$b9?;&6U}zZ@3@X1lEnny}{(J$N?*z4B^c}(H!Twif{P|xUG>^|Q@jvK} z8IU{VLE!}rA9co`p!0J^blNrGOhxtW0=S=<$*iYes@rL z#9{dYbY`x&<4@4prJ#MrFPs^E{^w`>`Ck~cKbT|Ue{N{}a5MgV!4I_`bT%$%-8^Uw zk+aam-5~qz9ezG^#taA0I%n{h++wDm|CfWtV?`!{<^}$P`mM?Q6JO6}0{3BGE{4vr zFK7DsYB6Zc#R)VX2ib4g&IDP9+RX%6hbqkq8IO}^1&tv=&SRJionxQQ^z+qbrk^jj zgRs-jm!LMYHN(%BpuHm2;PH})pmm0z@f+}X9HgVsBM#v%BT)}Mm*$a}J<=+%MP}euBohLFbSE z|IP68|9{ZBZ}y4*LHFW-((QMKpD%tx+Nz*E2B0y0(AmDA^r#C;H|!2SA97=+oBz$A zeh}}<2mA~_9||-4d<5zfg8aeB@NqF{&6u#mPfmt^lR)w4$;c1_N@FjQ8GdGf&U{a2 z_zBvZ_b?r_cFuR@|7J+v=LNq5c%KHWt?R)Exib~Cp7sTELlCHpdJygK^I<#|eT<;E zg0y$x`hr1cayJCM2xs{DAlTvO!*DcxU^g}dy%cBI`GSFA%L@>nmEj}od}t2Po$Mev zafh88Oblj^#2tP<6n6OefZyTgn{I|F;Qes^&^583y9GdJ>bo=ig!NVaR-^e1`hAFUqEvSzLI`{r1C|#qh zbwv2-PyYUu|D8E5g4VV_ybl^zhopH>oHH>pg#2e_{P`a=&kQ?r+L>eGpZtR>Kdj%$S;m~J-W+H6 z`T8`&&sXO`dt*UuPKKYaLG~PW`1$5I=)8J|pRdk4{Cs=a;pe;S4nN;5XZZORbO#P- z@A77bpKn0->g;Ct>B-3O@um5EDexWxbI7^KpnK9hm>A4otakw4z4Lav!_PH8>o059 za?a+e<(#cw%Q0K8_T+3YM*eOuM!xR1AU9!g&mB=bP;g zKi}?l`1!V<;pdyl3_o8_XZZPQHp9=Cpt0h`3_o9j=IbXr{CqXt;pgkw4nN<_2aWYP z{Cr!^@bgVI!_U{Cao1*spD)@Oe!lF6lwqKL2(JV~$cz1uaDLtG@bgu>!_PO&@~g5K zxw>^38iKt3I!=BS&G6Hkk^6Pl-}=dK;~9RwNoM%@I-TL?t89j!FG1s+#SA}R#XJ0b zo$T=Q1!!G;w!_ai`3^td7CZcW>&)=;jXNm)Gl1*G*TD=wUxhRL1jP*pBiAWSMy^vF zjGU`hurq9V8SL=$Rk*{?*P!*|{-C_-FbU+AY(}0g4n~Jd*^E4=I2gHCf!4*pv}gFa zf{|e>Nc|gk$of*pQ(*7D5esO6dMUCTY&tM<%n4o1*E5U%c*p!{Ob@bjI!!_W85 zka5wE-jFrup!+F6_vwMoYX`L@9T*uu3a~PO@6*%x=Xlvb>B1}lHt$u2Y6oV4<%}lI z3S?yXn9Vo=e6~B6Vdt!qwS2Q*)bh~X+2z1^!XkQi7p4T9Ip!*-+DLedp z$IS5aEjz={H=yxCMs9fe&|qZP3O>{SGs90%z4YL-!_SAH`Dmp455Bj8-Qg!_jOewn z!_PP34&eJSaOD|eSR8=D9uyC^L1_-nPSD<$*9<@ZBcD5uY$xc>hQ|y)|37E=`QWj` z&xfG7TO|4a&1@I{Hf(`x$VV zE6)xZ>%!Cna!)TKZugY1;nvrMM_(FleOticz{>Ekfr%jm%;seHxPX}jo295DP0@dTn3_rnpTa_{666987 zyFqRRt$Er4N(16hed3tw}9GttPCG>LF2|q=^11nXin$V1eDeZP5kc+^$WE91~%85;pYQ) zho29j--Di1*S zHG#_v=v>OzI}B4mcN>86;aLubkQdSp;B%}&?McwSS@53HY=)mN@)>@D?jL)Y@9;Bf zH^UTUbzn81`zBZ&ermw>opOWjgo2Kp^D}_QDq!t&rI!sskJK4S$mDb*2nDUa@;pZz*KTX~N z)Xw_}ii^4b|BL^v4qN#rKXm2)!>r&k^FK5D#XtE{EB{tYuY|SpA1!Ct`8b^6=aXoL zpHJf%!2J+Vz4a1w-`Qk_pP)4a515(ZWqUWsKF~fjZ-<``ybstuFb0+HoUdW~&;M3O zul$oAwemkRJJ?R}+z2!CL?zHVLD0Dtpz_=ul$KG|y;$zB6Ljy+3rIWaCumFn+((4+ zVSD~K4tCB0$$`{^&2|RmapsASlO29ONp}FR3G8J7ogV=$H|(+41v=luAJo5e_z7xf zX)rQudExEwljEp^B?qIN5Qi*-PzM8pi3ejt5aFu$_h$TtgkgUw$6G9 zK4ZZF+@}GjSw`WBpgaQF%X|VfJ`ZYxENA!$8@pEOZwz|m&am?_3-m4>b%vjrSN}~1 z&zp-o!0*#~c8or zeEmS*;panRPz?@?em>!boJaL=zXQtNKs%5>g+X_+IQ)Fg?eO!JH)wCG z!%z6WYj%d8u)Xu(cmVBL2Za~NUGqVG7tp?Pho7$wL+;jrxeM$L(3~$jDD0s7uGt-a zJ_Yruq4)2A)?dTsl4P#_n+~e4KzE&j_Q-?oIR(v&fbWAj&G7T#d4`{Q#~7x7_V>f~ z2HGnBpAI_P0X=X1Kg@LTZ#5UzJ%A5EbI>4nfyQD$bpmLf@-PEDAJ4pvxPRq=`T^Sq z{E&PM+HVi)hsz&iu!Pv@wetUACU9N`jhQ?E`Ry>n#K+POKcC2h)-piOS9tjk_kg9k2ah{4b4&#F@n32k*0jC?t+C{G1dR_u_Njx;*JEo4di|N< zr}l(~px3V%A>)JZ8KHFo-^ACy8Gd?$)|mZg`1uNS4x%*UPtcw}SRWL8pBboL1g+Nt z-@67~V+PvyE$#@uw^);j0kTh>AG!xenDOT;e#f7$k{Q5fc7X0Hdj%S=Rc3_jQ%?u& zjRmdOW1sl=Fw4YCH$iv8JAl_Df%d6`&cXui&jyW0f$sGJ^PyunYgiaUSU}|(XuViG z!_Qn$T~!a6lLoa-Ky@H!FF5#Kr)UO59Sb_E50p<{GyHr7J+BXRZ#wAg8(2Q^VgQYo zF^D_`-G8a?`17H$<4>kZ4MC3?A?4U{kUPUcc?dEl*vtZT3uv4mp5dn#$X%dyLG_Ti zbkKcZV0ZW2Jm?tpfmkmnKS+b-G_(a4$#?5=8$o9B_ww&1-S!M7eK?L z0p<>9m}sE8!x?(dl{=C{fPbVaI zG=tpXj0g`7Mre3|&SZ;+?$L&_!Sxd~oL{82Nx)uLFU;*#?Qg| z0U8E)^M^KC{*Z@^g}+pWrU!MT^nfjYK=&DAq)X5`8R)tl$?uMH3TU$LCV4wkl(=js6cty;S;E? zLK(N0WherPf%5kw(EN9`!%t8?e|nf@;$zUh+W8JYztmyoZ(M3iN-@>`X9l$`*jIx4 z`=B`YI0Ile1okGyFWk@MAluZv?u(6|_DJlsC0OIR3a&b*cwrVuZI5C9to0y0hJCZvGBSMhVC?8PwN(!44XeXApY9%xL*vodLW?4zyMdIn4eyGhKWHI{yze4+Cw> zf$m;>0XqK=v|g5(6FkPO>BukL%@2#u(~M9vK=&bAJAlW)vsf8^W-&tMyg+NmV0;k! ze={VGUxCU~P~QkN&i$BileXZ*PujKKvvU|ZySx9oPR{=8)7`_~5CpnQQJazbb2ynyCGjNbFPAkfz-W(`A6U3=Nn@Ouzzw`A?-_$ zKR|4dA3SeY#&V^RIfz&j8MQZ)!Pb`!Vvo)@0;+4ccSHxv_KBD^T2n#<@Xx z2E-O;_zAf~_2evF#;Q+Uf?cz88JRx5Ri7{Q)|_FdmtoH=Usi^XTzw8dKFBlt^s3DN z;iYI^?&;R4F*;IsqE572vuL1Fqz z-Qg$5PoQ%FLE#5d4=VFO;Rs@b#6WC#m}*1SgU%3CcKG?h++pWOamZXG=zKxWj|?9{ zWe&)ndJGLg=M+!Q(r2vt1j_U81p8(wGBSNUXV^dM94o`ewTuow*YYxSgU(%B$H>=p zR`KGjbAKH#KVTNrddRGx^?;dC>zwL=S%yqipVkTX&3Y@?J4=9xq3E1o|E#rw{jh0{-rQvECm!srx_SRK;=KEPW@Z$vhu$( z1HIhmX5@mdUxTbueZ>tbj~PF57VF)pfv)_;4{8|J_hYAw|4jm z8pBB0#xMmm*AALQu6P#+28Zg4x1^YsEIhLFdgHOrv-QQhGugCfJkM~@jN zg53ZbXR(L&mz)`XatJpDz367x2}(mR`jOn}4RxnK!_VAp3{$}Cok43^I6-YB&esnZ z7(zhpG)TG&S@|bFc;$a*$haqD90OGhWh@l5N28o!=OcTDpO2jxem-#r%{7AVwT7Iv z^$K(@bulEa9~y(k7?|Mk?S7qM3i$4DW`-@G`7qF&gbJg>&nNou^~MvxZ3oc04NzPl zjqN9iHU=p(Hw5W|(kiIV)Q7g+p>;fXeAD0I=Yp+}b7w(gGV+WJKS5_sfX>5y1)bXm zr@_apa5pJ|(jdsZa)+I-jywE(rOfbCi_zgHDE-0H9q8;QZBQO&FbAb6(Ao%ix&xK# zptVAvb^r1VKf&n^bPus2!$eTq?*(XY9H<=J4H{1a)tjsnL30rB_(U4d1E;%SMo78~ zXGEmC_0ag-3|d>l0-slcrMvIf7^Z;s1AxYy9`QT;d@Stn^9iUeBkl0>*j8wolm@ls zA?ftRHE6m6xf^t6G$Sp_o>tN+6JGeaEiR;X+7vc^(LHZv{ zGyHr4x<{LdVS-|;D|l?1{}*Up4pFZDKMY#4#JBQ+IK$6}(hNTz$usju;ZAc&D{uXGSXLtAss!PCXxY6<$DBXhM6RCav zNET8bEI9vfI>^1CxpvUK)7|V1L2sD3wYYiD%mTGTxf!|Pbr7h$fb5lMn59vv_2X|f z!ma_9RKc6}?{Cwul@DsGJ1JuR?)%P!} zL1)l|(m4}6>@7iI58h*S!1jSUXzZ2Y<13V~4qW*sKVaqmW){fUD`>x%K4_gf)5OQ# z4nLoO<{6-89(MiwKOHnz51wDu28AuEUQn6zf{|g%BTyL(GRGLz9EQ*Tr-SDC!1}>+ z?P&TzYZyN=eB=hr*Xuj{1kL?};+>KAC>)Q&1TWTE`CR18Rf&YhANI{TWcX)4>j2+x{9nKLWa^9XwV5 zDgzikg4)QSG6=K=4OBOQ(h}&7^bF=7+uulo&VGcnvtElk{Cvp{nr{K=L$nFF8M(V& zGc)|;P(3>f)Yn)Gw!3?lm*SaOJ&cSWy$ri&aX{M*p!qh?m^R2=Fnb^U|1bUkw9mjRZnPPG5?ogSowvo7c2-@5toa1by+YFt=p1EGoe8S{KyeucI?Elj z1_Lw)?u?mc{{DcR0SG=PQyDY{$pG0u2bu%=$nX)=_XEw#gVGKt&d}pJ4HVb%(6i#? zA^O2{V#bg*B1RlbGyGh^%CH5rt_QS73DmdKQan8i)IZAshi~UBFII++ptc{VeF(Z& z=oNUr2oz5YA76s^X@SPP9e#q^kf3(YOLoW|5}paorww>D}3n8 zG|`HgVG1Z*A7IHJC~Ze*KmCz6!_UY53_qU)GyHrS&H!Gg30m(3I^z?xhXZ|H)f5z` z-pF&R=;Z-w`vp|KfYxL_Wk$?>g4Rud)?2iJ;udsXKWMHMJpYNR7o-o=&j+2M4GL>b z(0(~%@EW^rP#OLZ)ZWEnuKC~p(?R=E!TH-7RL-E93z|a(wSitaL*}75py>!a=IZS5 z^9eKa#7D^vKOd(%{48z+o!bJPqXnl z6Zuu({wk=y09xM6wWD7NL)S`!&cg?tx5~^A0vfk@qwVk$w8jgxwhUaZfcpHb zh%$p$^*p$&c+bfAajjwZthJ1MU2j3_z@TLY2ei!Kc}hvKPX>;+%L}X^MSC# zPtY7?Q&eLRGkZhOjm)DTpA_TTgupz%Ra|EMza z2Ph4K^I>-#&1QL-4>YP<@8nz68~Aps?a#pHI=-D%}j=y=D&%Bibr_S0Me52kr-KALv8cDsNEQ zD#0uN+_{vgfr{}jm>p1 zFqnboH$Zctp!OSR>=?8rK^oMaWSaOm+TrJuctm?rHwWz zX7~xqM{qZQ`hcLk0-Cpn?z3@9g}CAE8PvQ2T9c{?+FPs$89#xvT`~9hg4_UFM-MIw z!0WzH!|cB^Xnm0M%D>ez7<<7%YXm`cH)w3*WioUfRWqV5(Rvv&KlQ-)fb9e623v5S z)R`IHC#?m^gXX$kH642Q* zpgycK>qJoggNHlljxkWUuZNDABt!eI>5QQL5+67~V<&L4aYN2w29+OAni(gGZvvg=2r2tuVx31S(%}8W1zgk z3_2ScRHw(R{F5KO^1m~5{T4W#po+oQZ8URS1l_6hFqq-zqi}|wkE0oWK0#YU_9_^% zb{(`X{*67uPacMbNpGwfe!iZ~@blGt2Jn7X^tR9^(3z^BF(%L*K+rX2ujV`ad<9z5 z2pXI5X88Hi+2Q94cgQ-PSD>~FsN4Y0WpKXs5?}}cr76%I3!w5FH17vaSImeplA9nq zKzmA7JN)E;rb$pabOMwvLF*io9e%z{clh}Vw5RAdWbEg`V|IADJPFbd8slSk#28z_ znl9ZLz-OU>)1^9eOa(L-2}+lscFA|>SjunE*czzK!VVs5fye!0=or~^Xu7-%O_$e^ z;{H7}?mvV2nrst6aae(4K7$ zlr;|jof$5I&P)gC^8l^;1FhRaTKBgCy6z9ukNWS-0PcH(+CDHgvEwbE^_Zac7&yK2 zGyHs=4H~y&_=&CTG`qww1=Qw(m7U=681V*MP=6L)pMb(aA2QaN1-jP-baxRbE-EvB zfXbCe#tuIpgTes1zT?C%$a>=ipgsV2?J!~t100sZ3_o9j!U&wd5pvktfuJ@Ws7(So z69c3dG=_p+k73kbpt2TJRw1?Zl=2#b4l_3d*`EG49o~no%=`gbmjS9nLG4LU{|i(< zJp|RA;Pwy5&ye*j8K5=-zr#<^I4CGiP}+mYb(b;2Pf#BQ*3JRfG1d-0UxUUl85$3xw0uw=HRySzP z*L;SbrN4oOH}LrF*2kcI zu%JG?yu;5&hgl|uUSOC48q)>Y2U_z5IxFOXGc&lJg5A3@^CD<(ox{(^p!v4=1GW#$ z8*D*)upi|+{QL*%=SegCbO7ZKY0y4NW=qgLB(QbUf2&dJ1Mqr0P<(^txD8He;-hSbpO5n$ezJqc5kU79g7#`hL-RDKoyX1a z6P!Om`!t)GEK&D6qS_D5%UePH!57Xa!1kC}w1l_v=-MjsOnFBu7XLk{F-?qcg2eS{@ zK4^xnL1cxjK}21H!i7>+f$mj-tFngfP4n7+iRIWcPN9@4>&0T0+WSH`> z++io^+^Pr8Y!gBIu2nBGOab-BUxM~tA7=RZA9NS&Vb+QNcQgF_54y`0nioL#!Gh0_ zIu4rOaQOM~IH+FWnD~g<@#kZ9$DfBlsenqvrT*n-FpZ&Z#%=!2b&#!KHLu4bHFk2C1|YC8?+A{)vu30dtie>Yq>clK4y0O z`2=*Xs51M+a?lwZpgaCR_AX}l`F}ZRuLjG+|Dba>=7aV)uulZ7YX;j3-CGE@7irD( zBW8|?r$P3bW7-SaKl_9k;ZIPwX@TrChWd3f!%xuK{1?tF6aRNJ{QM6(KM&+r&^@Xk zzk=4KP6n;*ZwLanVpVeo(9V!^jFH!Rah_+G0vf-Bj9=hh>y-hT zALe)Xd4iE)3uyiWUp%B?34eU*L3>{!vFL%9f6W>fA1r44`EWVo&qu2ne?DH%`18qT zh#x`s=YZl8)Lwe98+vB;en#*;VlUP^{(QL_bY=|;_)gge%*yaG@#lHaUh_k?4~&~^ zA1Et9&WAQPssdag^BM#VYl4z=Syb!iT@un zgV(*hdd~dw|7+%-+@N~?J@e21pP7HY{?7dK|8M4>uRwQw-e&&E$=DF|@;>v=2k#Hs zK45M_*`LV4&0zLoG31PHP+Mdn8$-y;#g2$`xu!FM@3jM`fkuIeFD^6x>;R>K>&!nN zTz3BX@VfKQCc%cF#mtbkd`u_*O@A>RVIF9oJSe48JbmpHgCOiLp0XmC*y7N!aIXs}V zR{!@i|9tTnac1uSc4*wyL*ou~<|-)Nv@`#F(G88ee&(MKx}ASM?1#i1BPj0D9e+N| zcKnGRcc8NxpE4^?e4Om^^GUkPPf)&v%{gR(^d&R?RA6D)@*>&s=l^o%pD(JJf4(Sp z{s}r)|3$Sk_za-``OH867c>8S!7M%Te=_sW|LM#>|7SzpnGAJjIy8-CGyi;%4|QiT z^UnwQ&OaX(L)>}&GF?5zqYd zMYQwJ7ohWj;+=oK0IhWoX8!p7#){Z~_OEdp`A{C@hE-9pD#i8@q*ThGbh3KTf7uz1l8|mFG2UA zF)LZVc#I^+&G-{E4+D||&0m1p7B4{OBXNW75Mu=2Bld!s@#hm}<%y4yU4A|W<(ik6SVpVe1;F`j2_UK*Jp;GFWg;zg2op>eVh(C$oV+`AG7@Y|D5IL%g1UH|KDf% z`N~;w;;Z{0J_}^b{5i|dSC3tOzI^WTlbeYFa%R(M7RZ@R=UE_oP8M@Q_M9x|1oh7^ zWH<6ne0`k-vghPB%gIALct&1Ql0&!KhFtNWnyOqc_IcMiEw4OZ9^7GYUm!B_=yZn5`%=+^MJ1b^AdEMdX17_Es57}K&_F|=g z+;nkIAq-P`g3*eS!KM3?iWM_?I9z9Ea|KI1P3KSptG<+ zbA#YBl%RXCKxZl5hVC(evcYq6(C`7B0|ZOY8lbr!(3w}4nSTDi&h+!eWzb#YpmThj zz~{{WKh5;>|9Q~8526$Q?`Qh?|1i_f|Hq;EZ9g=>9fsz&<4iwaoQCGN^GrV3Qw6VZwPp=YK2 zUk$Z;G1P9*`DviMzMARhi}g^uH#7Zwu-@tC!_5%8zr6oH{lR*NpASLjb)wk~Y9oN^ zxGA8zVm8yyhx3_!zL@Rw^986M4?6FDHN#I0P#w400eoKz=zf+LlbyhKIKP+!I!h-O~bcXFJnR(ETi+wJF0xdr=Jgt zA#PjmK{Co*IW9BpDUSf_~&e@=|OTqiEiWz<)*J&r% zKy$uI;4(y3Ozgi(SC=WPm)3Rr-Rl4F-!!V{{*T>K>PAv>$`x@gaYr22i*_j4mz_Ka`y0I zmWH4yAhSSc?q@sv1g*6N)$<&TTwS2OyDJzt%s^uBdKfe=0UD3+XZUFXDwmXz`~+PG z%mF%&0u&FRb&b|gKY`9VLOQ>Akwin#qjH9w%FumaPwW|f7J=LWn%4l$Rhc{dd{pkR z6SS@pcx*wJSwLP7zFcFkLU~T^_P@2_-<`K}?5%m1y7urrg!Q(9YPT(^s{=@FLSu8LS zbnhYP-Wl*+H=s5(_#Q;Xi7!ES6@u~z^zIvQ9znYM2GqB`@eVZi@9^`XGM0RttT6Gv zvZ5tQ`yVvE;H)@t!u|i#LHpUjeH75RHb2wP7oc;H`JH~g0FMhf{RFKA0o_{;zRTt? z;_hBzQYFO&ihbzK8CvU zIV1QkOt3qV?z929vjyZ%*qMlE2uZzOur^^wSJeUabe!BThg6A7}ab|1`_bm&|Gt{~rdmi&%cXJPvI~o@V*^ z>bT3#m#4w)NXXv)_0V?YW@tMy8`_S{2e%_PfZLI~q3uXe8|OO9&zHAB*yZQT#Y{h6 zfa=V}pgPV8)Rvq0VlvZDPayipa&^*tJ^-l1!Cc%4`L40W21>T-K z?gYNa47|60y%V@!^rD*SCwL80JriWyrI`sd?gDAcfyP%r<6Em)e!g1n^7F-Nm!GfR zv;2JV8B05=+3Dwl_bxvles)1=PhJ4Iv)<_^c#M;k;Uj$SGU%R=b|%Q){%R-id8c4^ z6hqxnj^vK{(DvM7mY=WYyZn5y*yZP|?<_xGfZBBE<16J(KOcN|`T6j-3rd@E9mpNU z2zS8uE}!S2Y0x+5RS9n+!in9cI@)pVDiFJ`;^eD$2==Zn`^!Xw}5 z=Y!`iKOeqEZCCby+>woN2L~gxU3nN1H=uosFQ9C2yAm2sFTi&pGJJe-e7+QTEaSo7VZ~3(y^kpmsny)6f6V@y-{{@)JR0q5q-dpf4XQPJHWVTxZ3IG)5A&=A4j|V zd=l^S6O>P3^}#cczIY}`n<*Z2M!dY`i|3%RDd(S{yU<@e2aO3a{rrEM`RD)p%s*cw z%T4@$p84nh%gjIjUkBY8q&V^Ad8j)tL*03u`R9w$Lu+z`~%5s*VaoHEgL1QnVwl-)?hzUIY z3L2Mv(JVU=G;RtTmj#FCW~e(sW3$Q%;IY{k`=RbU%>47ge&?SL4@2Ck1#%~}{em8z z$nJcgtS}MeR#dcYi~evWlldI8e_)$ zBXiXB`A}H_+@6>F0@^D94NGmOpZ}euEkR?9FS4C~zEEcR`6A!>=L>bFpRlpX7mKAP zg2n+s7O^x)F2-8z?M6NZHe30z?^I!iW46xD@;rT^_S$K?v!`>`9E385;Vs6!rvKuAK!~$=bta6 znZWnVfyO3Z9G0B;-xR~szYw z6AV*cfXowy)}x0L!DDjZ@fc;a@fc8D@t+Yg9>WYBj{)5|s16$YgU$>52G0vX_Wfb2 zKaE*`zA(o!7V_Ki=L2KcpAXGZ$72{k?)wg%7hq*TjK_fLh5w+tf*3?zdW_2&zHEN*!2`166b>(7V!t|;R%`#^4Zj0gvmdh^LZj#&)m;Pf2N`tyG>>(7^qwI==#XZ`sB{rT##;>1_ctUq7I zvx4@*1-(pW{rM{1_2+xv!K^=DrL+Eg znGM3OKVkQjyu9uB^TmBfNE`7wBchE6x>qEfK-xaf2x%i;X8idopY`X=CmTIBf@k!VF~IeMU$d5t_C^W34ZyGw*zHIMMRu;v`EBM$K&SJ%H1l!Sm*zFaq68 z1`0<|eFtSceDQd-wzGLZfKbHv;KU! z9~zd2S%1FT@A~uQVWhBJ4GqintdO(zler<~L^?O5oM7ai_60FVG8&jmHp7Lw0HRly2s?Dvdhnxt08uR!w@tly&9C}py%v^^66s6pUR-I z0Z@Kf%=l9Q#0JeZg2r(`cb?35{P|)w<4^Eif3qEbzHkQh5wd=O=7e9WyFl)1oQ`D2 zWXGQ`!Sl+TkTdq7c7V^=huQ%?KXEoVOg_Gt&-fF5*B|(fHb`6+GBAjM;`;w&)}Q~U zqs1X8KY-#8lpjEGI2js;(^-GMn(X@X<#ePtEQiKnH8c)?L-WIbSbpH2__`SyhwZFC zU(IIy`Eou8yZ(F$z1!_&H|U-luzM$h?pJ~Lnc6{NLm&=8_o#u&`ew$TuNJfZe7PJN zhs};ZAJjYke6&~_9EW|NI0Tv34~;`*m!B`n8GpXCclr6U8Yz6s9e=*8MvKE@q&O^w z#$h?wy&qqI&MwLa-GKs)L(qLF>d-h$2KB|EahQ%|M>6O>aflt@J2ydbSj_kn9*4z@ zkoy|55q7}i5OjW2F(eLO90r*IE#Hb6Aah`#v$V{ee!c+R0U6Es6Et233Qrw(&^c@k zlm5SE{rUerf%5M)G``=n{(SY?_2AWC z3TFHHGMo+4PSSP+pH25D*$^C-`;RhAc>yxd92%CO@=u=eC%F7mhS&)%|KuHizElRK zNu=^m8Y%BcL-US2*u5WLh%^3t0lE)H7@Bv4k;*^NT`;inj~~enZpWXXxlmA=f#)4* zq`V^y%{#&fJK%W-H0LYr2tF4OUjB)*{roSD7KiBNpExuQrP+SI5_kLgQW_}^nW1sW z4vj-$XdH?o#UVd54u#o%zLIDA`BE8#-G07gW(41-{*oCqz6W;iM9{q@Aisg*@IUBo z76Ney+NS`@55F0HzEWrV`BEDihoJk+zk}8V8i3=_4-|(W^Vp$r2rB-G06Vt^Eb9Nr&DW0^X+vnlojDu0aRwi7F?M&OqyhLFo*% zcDSDH=gVejI@=F9clXg@BXBy~a)e>Z3y^uIp>y2Oau;WxYCCj}8`h@+-JuQYQ>};2 z?Sk&$2Ax?0S__7)Pu0)%^TlK~%sKAO4nH6CyZwAP*$rh(ay7_(>p|%olD6P;+@Lym zJ9LhFwZl(P+w0|Gs2f0ca>Lw!txq+b?dOZxSlqDO;pc;ky~bZ0ko zj25L&wVmN7xK9Oh!)&M<=7ZA36UgBo{`GOysmxP&rKHzu$`A`^=m!e<%pZ)+gFUpLX zmtKI*0tM|mh-dtH`0sylaNgR?_VfRCHvIj&&Cv3EJKN7!o85lC-0t@CH6z0Z@YuzC zXg*ua2I=2<^Fr!mf8L#7HK6|8YBos!Zav%2SG(DMzT6MOZs7ZBKy#kpdC-1v`kDy3 z#|B=WgYLQ54asLO85urk3UW_;i9U7#TJH_YXU(9!A8bEg9*5?$W`~~->K%SQdTavD zXSWVBOaYyN46+YA2LR1y;Qrlr2F&)&cgVVEP#A&EeuDS!Kx@H4Yru;cApN`V4v6** zH~Y{3{OtJKH{9%y_6&D;Eu>21TOa6(knb{%j8+P`e zuY}ouz7z*x_n$AJ=hnOgor#ram21Dyc(0RtJ3?E;B?sfp3*8;i=9dwTxXl@nOzXR=Qgtc!#cc#PcPy?Oq=nk<1 z-o6P&svCo$btCAkVyGSPx)HR0IT&*0GrWCspY7-W#{}9p_o4aWG272q_uYQJe2kPI zPDA7HJTwj$L*sBcQXF1~wr_5;{e1PD?dQwaAnXP{W1rx8zRwBd2hbirP#l8J^L@|u z^W|q~elT|U2|Aw7s}!jVe9z*zi0XhE^D7N{d@@;|9=fylcF&3C3O8Ccs}?$ z)6WN=oqj(2?gXCqVR#O@9|f{c6n!ih+!uN*W(iso_~O3PPtcys7mp$Lri0cufz}MZ za2A^gTi5jeGSvRlQ2WnA?Z3?Q^Tl;0$lAf%Og|r7cl!D8HpKo1&p>C%JN$gej@fR4 z&q1?0T>S6MeDQ%a^UsI!%s(Hwv+aDW&iwOg6vUHXG6?Gi!=W` zdzfL$Lv^>EkHnpSK5#aicoL*f+8I9A$;i(T@>1FvGSAA*44G%;X9n*fc)`f<0lYRx zne8Wd4}m({&j-qGKOd^Q{bbT?0G~Gi+MDrl&%fy}_#tMlU}D(vg4_8g$V~7YB|Dl~ z(onPH*?vBdcKi8I9%2^gUUHCG_dsT`L(BrLGd#%55c0p-!1BL1+s_xmZa-gu(v`T| z&ljM&nw#zCe|}I~!eHWmX11UI*+Kmkqlqt>LFI_y#Fy-BKVNXO{RHo^;b;5#fZOfo zLw>iPkC=@o=7Zu8x{mfgyTio)&dezDhbVsd&4d~rzgZ#S@t^hQgWs+{AO3g!nS>M` zYe9ba4V^#bWcc`y8FKdDi)MYx|KC}`V+Y{1t>0aLzW5GW&k7mqc)_ec@&9AipZ}k; z{(PxyH1XwQ(0G^O#Fx)mf4+Fl3h~E#)}IevyZ(Im-WBW*TaZ7Xc>}9Ipm7b~FL0j~ zvR?oi=ioSc4xL8^t*ZsaIj9XgpAE8~VKLj!SM%L|zF6$`^VM>;pD$K}!do77Kf`OM zpAVM1{d~CE4P`&WuY;g;h7(_&XZ`u&GBixCv;KT= z+4bkc>yR+{@$~=n2lt(RK78!-6I+-(kaqt0nAv#Z!(_LgkJ8qHo~ytwW3^Z#L8%NP4uf47J>-7ZpD#dbCO5PG z{J$OKPTh(BSF`^7zaAQQtD$kXp7rO8%}{r4XZ`tLv+K`?+ac~e2Xg0mr=JfmV|V9^ z_0TY4*0ub}|H6FYiP9i`eSzP5Gv;KV0?E3Rz zJ0wq@dh&nzgLSm?4sx^BM9@6r|9GgI zL350tvNoRe=Zj>ho6}i;K1g=``7j;g=D8p@L)QmmD{Ei8cY&1i&03bAdCV8Vu0LO- zGyQxK?)vjZHq+1l-mE|W`-93|t%?7gS%3a_huZB74KH`rpD(-Y~4!CJccO`l9_%!0EJI7 zsEpUN1kX8JyZ(F;&Ghqyz3a~x@k~Ge8?*lW51J2m)|~iXoAu{^eW)9?p>71t5gS9@ zXwC|sBL}rJLP2hXu4Bd)KA^hj3A6FUN6BtKAE&$he5hLFiZbiZhw7kk$+Ud2 zoMq<=byvvRB#>LfL2lKsd?C*YUSsgWo9X8ZdDovW{F#2j)753aS(>ORh;$b17X*n55*zjsReQ?Z2b?mHqml$T$=x9*0B5!-ml^M^95*aGP~=~ z7w$|y|NmzB`5&}@p;>+6|IaKx|9@wJv|~VfO+e`gx*iS`4=?_+!1pwO!igJXw=-mY zGq!Mgp=>nqg*nqt@ct5grk^jpL30c6cG(4RJM}dSq+Rx&<>!OfEclqh0+Ykgg zZyVIMbl>%F`b%S{pP(>*Xzm2Q{|hw6sKLna6FCm@K;i$G<>y1tx;f@_%NOM=J6}9^ z`T4>g+8(e6g}<8Ri~B4;U)**9ug7_DAGD7P)NWz<`Tsi0&lk>W6G3Y_|DT730cd?E zC=AZC{Cshl1=5zg&hqoYWtX21ue*TTa;F}H&N+4Z`4F`32V3};!@^(960~OY1!(^a zXdUu#7x3Dk|GQa!{@>5?^F_1j#Q&RFe*WJMwRs`QWfWYOCG-wT!Dkv?3*G9eot!)Oa*A!;@`F}Rc&;OwD%4U^`|0lEj z{68J)?#WPhgT@hOL)|@}<>!OhE>|3T|{yIp?1 zU&u&kl&Oh{*Pw)`9B`&w`i!};#q#aNQU|?o#p3)WS5^0 z(;_1;JTTcA1%>MJgI{VL8${=hs@s&FJ z&zIWJaW{STpRcstf4E0%h!xQU%Y4h`SP{n&lm5Zb5fx7Jg~Wf=Z-&L7{kZiE`Y}{(c6BY zHRy{$<4B)U94`=`RKbrmLYh|N}ufy4YzKUl5`LY`tp8f1UUv<0xeA$l_p5@T+tY(MI z)Bc8r=YLpu@=tu-3?0X8XaD(XGW*Y$(?Qt%=gZTKKVN{>?3{M|`Qkh@JdcCYD6}mN zT3a)jKzM@Ixq!m+Fyqfxv)O;XoDU7p!;U{6><7(xTZ6+h6cnBy^Ug!U6Es%v!rkpB z=&T0NIhUX{GoW!V@EFy0NATJi5Fb1a25Q4@X8frFYBz$~keeBQg6=&6t$P8D7ra={ z_!D%l!;967KQ%z(V4(9IK>K~cbIe&kUMvQ!HGu5>dAS_oKd?QE9e=(At#^Tqg+c8B zuXTXh175EJS~tVW@DXIsGtl@QXxs*L*2HGVpD!*m{wxOFu_^5g?i>A&XaD&>88t3n zf#OlwXd*Z+MILy!+3W$w+bO42?^7Xk1Q)#^rRRxb%m{Wib2CSLy6OUuJ`_ z`_GrN8GnM-)4T+&)0q#AOX%7h@R;;;$Dc3K3B+YTm;yRK0%RX}d>`a@MhEb@4WKmyptUogxC4iAyW>yL8X6EE9+%BX zaoG%w%XYAvKfVCn`&IAw^F=i@E~_2E^EQxkPqTi!C}sq=12ikMe!MJ4ipyfhpD#h{ zUXbIm89Mh4ipyr`+&gIf3@9$^8Gpj#5_A_7>fEI|GB*>){=LK1?T2W^ZTz`F}T_GJ88TUG8T8`D(lS&zHNA(&b`kx?Bz|vxE5|Wp+3} zqRd_oEweYX|9rKd{pZWWAngA0Wi%uBjD?rcj^K4aptcuioed~GfYW8T;>m@b;qACwLxnhpz}|lvQ!x3@;Or8I1i1>%h0%74b2`92ad~9P+Wq{P1uxz^{Cx460aE{h*1&-31XhQip!?8XJZ30P%9l+;}yl@7G9k|T)U|=wl zXJ8Qd->e9|^N;1{3uBj`FK#pZd|~eL^TmD8S{jz0|Mfw8qZB9pS7!P7UmaTBDnrX# zb(Wtmw4vp#KFiMs+AcpI>O;!gIMBH9ZHJ!^?>k^^Bd>tg7cW5TF0X^uY%~PD0H2HK z@bkrG2k@F6P}!Ho%MkM9JoxOa4WKg!U+iW8jl)6qMN32bwDK%JA4t3Wd?@eov&pz2 z2y|`-hXUvxb`GtH+x|@lo#FUmx5H1+`GufykEe$jej<;3JlGF9vlVg|@~c@4Q$Y7m zKLMR9Anp7UHukUqbbg62%g=}6pgvE6<%@pCoiD^)e!e&j(#x>r#c9yFYYLVx_*s6w z;CA`>Vl%_f7yO{J3mATa_Idqh2i05h6G3NL{Rf?81saR~4LU!?aN^7V%s*c+L&K4s z<>v!tm!A*WA>qga3P16&ll?%z~^a! z_K>}Rp0oA;IcPr#X#NChH)wCyYi3BF`#tl|2d|xfK70>4v&DGgThN}{)eb*F_giDN z`#d?LkC^3GrGUb( z7#e=XpzxEm1nq}=u^V(w73fZP=bta~L1(Wr{{-!$d*LiQ5p?F*|Mk!`wHg|Jp#5!| zp=oM6^UnvHoqs;u4oOoHpzzCf`1vp&d-#FIB0*{9^z;AIUo3X``2e(Dgn{FAHt4K` zbcdfW!E3HKUo){XOhirxps_*Fxkgh#bAHKCKO}?Zpk*yVXPv!R4BEHI@bkrT&{>{p!pta4#@gIdyb#4tUZ3dvqu{gpRc?*e!leQ0QJMSJ_Oxu;tsw;ZlaR{Be!K8ISh(`7quCWv*ut$bHtJd;~co9KJ>nRChXq>Kg_T&|L>$H|Rs% z06O0R<_2tYJjonCU!-Gk185yfvd7Pd=^iL^JdGeXfX)kMgt!5|Mi3ev;5CBg4v_Lf z9qII{GEc8q| zaG6}s{PRJz^UsI%ko@R;@Behron{X~=R#l`8@6|V)RE58mY_52!23n{86f*bg&BUr z_lq8unh4)33aXz$dqhEYL-&Y+?MB`s%4|GQ1!OnB!%xsXidgGN(B1RU^?Bev$ZUq6 zUjP1!gX+H*%~F=2{i)#nprCsV!kxiuf{PUqdBrF&}?tz^Lfh8>9YjB)xFFq(|`uVV$>F1+*rk{^N=LRq|OnT9d zbQVN66L`MuMZMF{m!LiV&^gWr&1MrHfcDk%K<@AR3Ql7tko7j%&9)B~n@)TX&h!&} z&hc^<#F`s_rk@{nF-&>n?*uyEap!}>CKDe-GyQyxEcV!V;)8gmpU;rRn2jfb=As@V zizypTe2~uc^Uf}YDG!&s?EG)f_Vd3p8+aYhgKVasu=^RV>|&VmHr(mwn`oz>uj8G5 zzDjob`7+(<=ZkEopHK3ge!kUa`}qd6hr^id=PPrzpD(T1e!j40`?-RlA?O9jJbSmF z51rk9KDzAo^YL}JpZVZAlIbS{=sv7s(73&!F3MErr>orFAtkce96uB^W|gXi7)vKYwT8wxZhWAF6yg*DU9&j0;Ept^ud zh#};KwbM@yPKJ*T%uu!G8PGm+=)HJhpmun<)6XZ`PCp;$JHf->>(&415B{_Me8|l9^TmJHpD#e?6tP=l{j}mM?y@{(J#iLj>9v{@WEi4+YvY_5U;L&j*L~CO(iyjT0|WoXA7t z^c&!mQAHHV&`Qkk*B#nT~d++-5;b+&Mpg2(g#R+WBxHDRu z7=zbgYy^jovC~h`T?n9aE40D=Fg;7~nx4z9kUiqpUBUB1u=PC;7VA!YAdKo}S&*BB zp>Ey|b@OhhoA-nEdmB%D3EJBUD$79YcTPjye4h2^gVU}*AD)M}`STr6`3c=Wj_zhq zyn)td+cW*l1=aJ`PVltE&B_q+KUvo@1Jsw>%=+`idROqg(TmNlKS6U?pmjN*bw3Z9 zbtXPwM|JzVoeWc6utVJrT9X6H1E4*OpgaKDUkD0s&>lmO+ZVI`e6bwr_SLLEA1rtM z`EWJF?MFav=XUz}kRLM-ys~!s=^@B4(UYMeNVAq}wx%e<#FyV0e}c}n0`(WbY4ATI zY8w0vJ{wsJbe2yuC=LF0{Q0Qd>F3k`jtF(kjH_;40WBdtP%K%y{@qk%t;)C0$el7s{`8L$gpmhwOcn7U(0L8mE)X)CVdHG=0 zpD)6p@gB|k^Fg@l&xg^Fcy|N&`M%@NhmSG+{19}$8z|j!GE4-`JAmRDUd}u=o(QUY zL1&0uss-&SVuY0C*ByWUKa8}-0W{|WTH|n@5x&OZ!DEey500by#|Gq|<52&|L*q~x z8i(po|A5v)fZ`Ck76KfH$ZH{*%_a(g{Bzpz=fm@u{y}j+GsOL%^b1?7@o_4{lm~~Q z{y6OT^Z#NE%NNqDKVOKu{(J%2V=e9a^TmEf@OlT(8i)sn)h9mKj_MCCkUv24NuWCE zHw&cv`wu#^(|F=bW~e{dq45Ge4-)JTVb-4y_+5WK6o$mhgWLb7KiKW~^WlC1{=l;4 zWIxCso1y;L3_2%P-SP!!UBqY5*+q;$Uwn7@37T8_|C;6Jf6zLH#cC5DEJyXnjU5bA zK<7Y%>sHX&PN4J!I^PMDzCdS?g36W0&~Yr#8iv;_ka8Sk9&}v)_@E!vZwoxZT_(7FYX-$3ga zKz`c|IwQ+?;>-O|zk$vYJr4ETX_lW4j=TJPc-jSAN0o#8Hres#!|9lQ1J&CaJfQn# zoqnREyTzsxLH+V7kUzSi{^$njSG5G6lfByI=L^vM5NKUPJLAv)i&=jDUk;i#SDE;r z9@QWDAb-?D{m~CiYoPTEAb)_?H-O@3Hq;-WwGWG-{s5T=JsTVpN3I}$G&}x$*bZ_B zYPpB(_J^Q$CNtxzM~h7-22}l@{-7G_{%Xgc|CLoNUv#tle9`Xm6EtV`0<;FAoDsa% z;eRt|4oP|9gM3u?+k@Pn4|RVw)cyI;yiyE}hjOU>9qf!{vaFbe$ZSQv$Ew2&^m@>=v-Mkbgm4#rU7(@=Yx1u z_w$3?9}jiEJJkK&Q1|;o-5(5fe>ls}7tv7n$Fux=5bg5wVLZhBPj4a3siCzSki#FA z2SD!EuLGU^4RwFC71yubXvIm=Jb93SX>xCj2I?!Uhs zH1+^>KWHo(ln+2-)1dUD4Ryah)cwXRKVO(b-EYnE^MSd`&xh6!_iqKcKiKi-L(o~` zc-#+4_n@(*N6JPM4^;l2{=ggRe$d(8hZQVe$g})>A?*SgW0!aN2|5G(zc9+6 z&xfC#!R1gW$of ztseoM0mb+eHm>_%vFyYL@~H0j2e}`#&mH7`(Ai(0@ZSw}Kj^*&Q2BEh>VD9D4yU2+ zKhOO0!D;8856?r~uL^R%vg6N(>X`W#-Te!>~erZrWAZz(zGxR6Tja4KmCEQ4^{iGoZAMpKW89^5Q>eyw`N%OVFJH zAU}fc8UXn*ADYHMV?!W6LdS-{encJ{YBrm=2joX)$Da?`G5u)Bz##JIvLn`d?f}RS zzZoEH!`}`+|38+pe31;gZ@~HI3(%Zevhz>SoFHiY1~g{$fLUtdgZHR@*b4FkXfHk} zoq@(~Kz;z-KLGLr=>7pvJo!V@Supd@7va!!7R~(gLAdkJhtZI9)(!H*XNR8;zk}wO z@YHjlaTicMr))HFTE+kA4_-sv{~9!wFKPM09&`_Z^H0z`Blxa@=M3Qc2mYHg|9tRR zV&a4QsP1nCx&J;i4&3)>-bJ%1eD4)M-`ak`_ZK&ICJN*2=Si&Y0dxXFE=~!Nb7sF2u76b^UH=Nm!y4uJM6K3FU^5j4jK8vBE}@$*)ODWJI=NShoQ7ohtH zKjjMuo>$9?a;IY+G7K9Kj^%7P+0`p7jzuz{?kl9A3*mJfy&XDAoovq`1ufY z7CD;xUnINz1dq3i&zIt4Xb5^K&$!b=9eSSv)^(&t6Txdq7n|Z-OL`i%AD$n&_5#aV zQm`8IwWQXN^`0;7-G9CW-DB3x@be{T-+MQ>??3Sc=nh-hTGD2RpD(N-YcIh2ok08H zjoBglh|EFjQr&;P0^NIN?*8*-J?PA9_Mb1^p=&Sd9ezHj2CcoYnE1HaY@*l}hAE&q z&==j%J>1YaCD0nP7w;K%zIa?@`7*f-v5xdT(th}2$ovJUZx7pd3!1BZ0vdaKkF+0t zGW*Z}pmm*(ttP_OAie^HVLWtQE@(~SWav7U>7aF>?mu5ncmD|vC(yZw_0X_vhOT4b zhOT4b=idod13K@l8@i4Kv<`JPWUc4R`R+eorZfC}k<9?UoAyOEG%S-L>q)@tSdtxn zzL-rQETb8Iz66D3Jj2gdi`jp^Tn-J(cn9#k@{b-{gTwOhW`-%CdksPMf!7{__9+E3 zfX^;^84j@%ytV{-<~nF>7`%q1+vz80-Vl7=Sv!OcKJP3T?B0(rVCRd2_Pc}Dkh+7) zDd<`xd!+R%&PaCHJAm)}1=-OFn!|?L0bV}}wFA6<)E!|5d@nU@|9w8gPxyZLboQVB zLF+k@;}A5z3W`HeT!P{-9U6z(p!J`ivj~vl&>I?u{?IsF3|&9EoDUI);m|mYX8-vr zAF{^tWwHCum!NastwC`BO7~#*PJ98n!x)wyKxe(@6Np1?kbcm5Z-$?*%GrOutcJ#+ zzQfN4+Mv5etiW*?1d2nDdDhVU09psE%m6;?;wAL{QE(iB?%o5>@j=&=fx=fFx*r}C zzVguh@SuC7L2EiecNT;8z=QU?gW?c$moRJ%Fh9dj(D)#D-6-_lb+8@$4nJRl?g)jg zCxhAnk3)Ir8YIx3d8i%mIE3xLhn}?$E9W>E8H8TQGwysL@3`}Yv#90&^-MostcL7I z2c3rvJ|`V|x5a~Gk%``xjY@TXWe+>%h{kk>qZk_g7y+F zhL+3AnSMT444Q+2)GNl=t+8KX7Xy$_NQ&-;t z8n-)O`(Sm0?SsXf;63Ub?2tJ%HIUyR^Y|aZ`4V(y1uMhGE+&SM|N5XYNl;&zbK-w( z(3(%qi7&Mof4%_UozxKY!k7`fKJlTkMr-V8q%GBAWZ z0Nqd7%r&u>5p>5OXpR;%KMpEC7=Fq#GW=Wt+7GJh3a%?bcN)LUcR<;zv=X%E7A(*C zx)&5ypuQC7%&=yTiT{P6VFl`Ei9_8l&G_?yxZ}@<(vYy)0CGQLLlCyGdKm8T^8x6d z(`K%TkAoe5J_!e{sg++f4YVG_p5bQ#6T_DO+@Nt*(E3S^iT~N5_OUbm1l{)puABH7 ze?H)L{P~a{V&9Z&|EE8&2epe);{_ZCoD3h|g6@kBhTLTdS~CIOA8QS{YvTkcEI{{C z{AYlS-7_(4H>P+5^y95e-F#iC{C0 z(aih~HS;&a&j;Tfem?x|@RMma!pz+uGmT+p)`QLb|DNIJe^B4ZnSJ8_*Pyi|oD*Sp zGlBgMy4(D{!_SAG9l+@_6y$ei`Bms?@V z_Zfb^Sj;x@|8=OJt~2}ut&;@%=|02H2heqnAiWA8KY{MiK+9(jogrz*gNfk+$3r(u z4n~H;7wq$;o;7n#d=l*V^J%!_Pf&aNF|+(CGtfE;P=5y0*GYD>eBsWp6TBu;o#AH& zD2*Lw`1v2a?vQQb|HDu>9cK9X;y45N+zil~#0SS6em*=63FqHeL3`)0q%n7gogNGf z=Gy=Ni@$US!P+zv0YvNhZ zn4vf{K0s?4L2E0a_ZPnenGag;xE^Z$W`>^+p!XSp%-;htUmVl#q{PQ1&>b6#8Gb$l z^>>(EEnmnp?0m7@;V0(3?fJV{TF{>@38X)8zc^%G;>XS6zur(ak%48 zP#nnDgT`8*Vbjm>^Z#UqpRoIm!R`RvEz}Qn$7F_|5BeQ`KAa3m7o{L~fa^TevIk#W zvzCMEN~nF!3_t&a`Uj7hC;kVWc?F6K(E7t>sC~$H8#i-Jj0D*SIu`~luK$;V*8ed4 ze9_E2@qaNiJ%jEWDuc56Q{EAi}`VFzLTDoSUz70+$M2n*a^xH zp!5woTN$*r0d5XRoioGEQw$6tptjEn7Fb<@WELY6!YpTooiCjoc49RPq|P2;76&%7 z8j;MhXW04D9*0>Vb=F8`v0`%<3&LI23_D+1<1mYn<>L!;gjpHb+{MU-Fw2}_=Sy>3 zX0d&IVT@!JGd6c|Aj~pm*!j{JmsuPiLH9?)!k&W(n^`;vv-BBuzSPHM7SG2Q+6Z@f zU^R;mVU{+-&X?M_%;Nj_LLFfiXgvg^{eYY%1Q2GaGwgh+j>{~8k1v!FW_iHdBFJV* zAk0!`*!fZ!mst{^bE)8I6|_eS(_IP(v*a0ezLdvhmcqvu(g=5PV0D)P!YpZqoiC+v znPu?tg*d{j6AW15k<|fVmN>)Cm*P0g0;v;*n8nS&Aku-wEY5}|@Y*MM{uXA~`BE5R zo&qDZoM>nYdd1A4#Q`cW7`a}*;76DX8XH6pJ5GjXRCDBkQaD?}-*c~qZKg@UW1vAG)(EWnXRx|v3yq@7F zXe{;Nc2Jvv;pfx+3_qV7X86en8q--1xlix)YKNb%_B;H1bJ*eM8_+&2bH<;qm^miC zVdh%(WA2c`ECU73GP2@dbnXhPJ0 z+5|7>JN$gT*x_duqr=Z^R)?Rj=X3siHJkJ219pdr3=Z5AA53TX2^wEiU(6Z0b51h1GY+nAU7SbW%g{bWpZt?Wpr$@Ww33rW$--$R>#566a*Ttec;SJ zv10?n6mVN=y~EF^(;a?3$@l#EINS5*BW8K6-8cSEf5^fvmLp9>fmwt)NqYJ)uJ zXZR@w+NZJJ;peN(4nJRRcli05nRC_adIs=bwb#sCt6n!V`~=-Gr^(3G4f7{xF9PV! zJn+5Mpgo!0ka&QN3qtlAaK1jp2@Q*Sho7&i9e%!S2H$xIKEqs_k?XbQ#;#dl`?5iH zaJ~lHmk$~%0);KtYb{oWiCm0auQ|7N&H~x@vY6o~Xx{?J{h+(=UVzTI1nmicj<hLq0k>j;jW%dv4+EcT2YPn{=On3bGD%tU; z7bDMVO-AlruR!O#gU)vct#vDB`1$nzfAJ^P;C)9II2eT|g6_dS0lG^IG?yOl_!D%0 zHHQOakI^H;hM>g^4MAlq|4n}Z@^iA|PtCUulU_M6y?-3~urLC5)CL_7Qh z->ujVO`o7M*g^Y7LHjtJ8Gk->cl`MPv`-A`x5La0L0>@r0^JSi%smmdukxY4qW%$U=i)02UOqe-Vy|QNbsinv;@s&NpPfbpTpRbrXSG|IcGj?%9)W5KH z_<53%;ew_k_r#aGIe)%nYY2L|pY!L--JU;R?f3lon%!X{`0NC8hM%vFbN+mJnDb`` zjFa44`z#`T7k5!n~Kx5V2gSzn(ce{Cr~V@DtQ8Wn=}7_c;7yDr^jDW(K7P zwpBu)@N$Qk_1fCu=PP^YJ(j%O-I|QtufgeGn*rjMM&609^%;J?+RXX$<#woh*K;EL zu$uGd%hjGgU#*9_-H~tNYtT8G=Q)4AJk9y@1q0OWAp5k@+^OyG^C@V2*4W`EvOAff zcVfR-@o)MIkUo7#9KBr3`SZnc&Yuq!d;Wa5-1Fzd>zqFyT;}}wb0))-7uP+1GJdSR z%=!J_bWm7<`VgS9CmA$1+z%-WKz$4F8u-I}C}T`d=Y!_K9Dcq8l{w7vt6qWTRi7~A zKd5f7eNf(D`=GeNR;!WWBNt0UkmA9vSuCs$KbaXp_ZzcM1eIkS*P&&ZI>S!}Mrc{4 z4&8f$W*6veV~{mXM5H1&gNj`TK$Syew8L8 z*REIh9e%#O4RRCjY7n36t;3|OOr0MZA5Toy{9AMRC9<3Np<~j*3_ov!%9ZsXe>(hp z1rlfE>IS(DG}izMhZoWgKSAz(_1xj-D{h9LPhUIyWMSm&e!|WGy2~6=#$1M$J=Yn) zbD$3{JN#_of{X)Mt@t6FAAQ}O z|I@LhW7M{a_Qeb?z;2QanMbz&>Jn1jm126V9m<%!kkVhu_Y%h1IZC{8R~$1vsfX{VpB z&O7~ldD-dblj}}D|LgPo{BO+j6C9R|pnb+XKmV)q{QR%Y^YgVb&(BxtJU?G*^Zb0F z&jUGc)|lt#1AU*L4~>0(J~H}{r>4Qvcs{!8=x{4dV~3D*Vk6Cdn{ zgc%1XWL!M}6t?@Fe!gUPn5el>W8%y2+z|Fb^@%TkL)j12CcgX+WizTxe96oMQKP6j z@g+Ny?Wi*GB{!6vs66o{Ka}05H1VY{l)X@K;!AO!pD(0&erkZ$$b;M^?ep`YywA@^ z><$y18Z;-0fYKf43{B8pox|EF<>t%xPCs9~2A!`5DvLmE14x@Qlc6Dqk@w`RhufKc zK4o{9xU@lY;$vgqpHIwvA^v7igU{bvg2p3vL&N4h_s{>IxglyC*`Tm_4rPPF<~8@v7w@?t zVFPm4d+(nQKYPQ&=IjMfo`jwsg%&msw>x3?yMij*@4rCfMC+k`Kg|8}|8c0_AIMC6 z0J;O0SzZg4E>5jwm;#!6f~Sl5P!MW^-wm*@0+1)kl(jM z*&x5~hO$9^-_QN?#bK!5LGC*2{qx~*gx~u>eqWE>@2@~-dP36$Y;VKM#Y{gL8985L zO%Dz#@G#j53X|o~FqzK%^Z#sUm^4UFd@vt1J+y+tWIj@QD2BQp6ei_RHYiN0p=?l? z)I-^zFlmOeL1EGkWrM<`8_EWSNk5bg3X{p)KVM9Th6%`B)4hK_oQ((*Pf(aF#~vo2 zbF5!2cKZ49wbRen+ns*CKFss;^>Q9?pGK3B>-EcSo}Vud`}_pW2Xd&oT5>STfye(l z7#K`IV=OPGGyMdgYYEynHJ#}v`2PCIOg}pq7`A}#>FsCwX$v~5^fhRH(qSS8quNAJ zT?*RYWC|0X?etSqkzwM?d?xT*1+47=PE(9(6G3vStPVdp8ChR*Y;2tcIurB7ai5={ zJ$EM<88(3X8O2OLUlj8~+WVmU>dSe5J}CD6`LNvgr&51o(4+4xJ0C;$WIU;7`Wd{yU3NaHcY^dkyP1B1?@7<*{rMuF_veFb-=7cjeSaQi zYY6gM_HX)2(7nIyPCp-ZgUXqPAf{T**(<*Mn+|R-^@GlW1MQUq-FeQi<$pH!&;R+* z^r9dI-hT&P=L0QUf35-D|BRGg+@Wy`N-y3}HYmOLL)oD85)5U7(n~m$4N5Q3P&O#N z#6#Jj^pXr^gVIYn_s34HD)I6Xu=fzO+?gT*_j?pIWWrw22bcrr9SSYt^KimI6D!5=jL?ep_R zFcYZ#1xXK}J$$hA06I?+Jw5az(!;f-(6nIf^z$WX-=DM7&qw_(JD+TarUh@@Y2oH9b zP7~@*;BzKX(uAW5W}484rU`Z|X~IzjGfhZ?@}SSp7xGAHf*Yxf0G$3b3xdkH1QeA2BnGbP&Oz{ z{D!hYY2rVW4N4Qt(6|Ss33ezOlqR^LY*3ou=l=OZ7@8(P?h^L?`A{5@CN`e~?d8Ls zCctfP2DOO~*&QY-HfT>gU)^g%PFW%T!hSbP?Q0c~ zXG7T_zt4xVL4IEhWrO^_9LfgyeKnK~^80!y8|3%RP&UZ#+qr(e*bVhN$X&a=em>lf z@Vf@c@9&{!$f31KUxM<=dr&>28Ba4lnn}pdMFzd4$V+DC>+|MY*09KbNzhL z4-E&9yZXI;KAemQhi7O1Pk-H}s%h`HnL|g1I%wwUWDXc>E% z@h9laMbQ37aJ`$%_49u^G`&0!ocLfhYI>Qr3e=xLN-y@%xCNybXDAz#UfiK*vFCM0$w=r5Dg%N-Sjt zD80N4_W21ub9AXAW_nnRlpbLB-_D1o2k70q;CdGn@1XS1s02?B;I-7vVnOJ(=*fIcNNNGYC8h@ZPAr57O(u6dW4N4R8P&Oz{C_~wxG@%Yn#e~=6G->>g4<%C`+L(F zf1;#`g^HMIq8OScys@N-g^HMIBA)T*3u_2cS6~q;Zd)l?+or=K_NJsGzpkb52BC>@}1PN)zv)Y*3o`3}u7T z#CIqglqP;d*`PG>AIb)$31*};!Or#b1vfNJfZWCH_46S=B25H<(u6zqGy!gJB`71> zV%Cg5ok4R0){c<2Q-jh(du09s#fjF}|4)Bvjn)o(0Bz4Xs7wTp!zrjv^veD}9kfpq zJcf9m^XLD^&^g-!yb~Xoqvj)fP?(t`*>>rgf*AKm8s`Qkn&q&)_5*L}~Q49l9qRuC9>o4nXq)W+3dmi;@HEp8bt}mK zlc8*o|EELQApg&XvO)fz4`qY=zZl8}`F}Z-4e~!|-U}2iApfuD{P|)t)c+uNZT9^6 za67{Phe3Nnjj{Xx!E?-ULU3Dtfg;534N4PFXF>Lqg5$oO^XLC=sNWg5Cq7U|jr#*2 zzk|+j1-ngS;>%>Hn?Zh0hq6I_&xW!=e$R)pL4GfWvO#_?hq6I_uZFTgey@kJL4I%M z{Q06C>UWU4+C6_h>_+>|?oK3FXE>O(Ak2j`&$8W6uHC{OGG`CSvR76Zw&Rj1INS%;;8ZN1oFE$Ql96Ax)bDgekdE{cVQ?S8{~IsC>!K=c_A)bGrkKmW5s{r-RrvELXP@5~^-gZ3N4;{84cqK>m5I-dwBzBfbN2a50QP&UZVyP<55 zpZ7!AAU_|5vO#`64rPPYCI`T0DQ4f6A4j-M~Cb3n>?kh`vX{Cs%Z175~=f&2{G zOHEFEGpJ3RlnEN+fckwk$It)kp?+6jLF~PT#&sZJ}tW8$te# zhq6KbPKL5U{!WLoLH^E$vO)gNhq6KbE{3u}{w{~ILH@4h`1zt9>Ti&{>OFowY)1H- z7vyiy-g7K*4)Qm8S_hSFvy1;vfAAUV-(ZfP|HGmFO<+XqPlx)K7vx{i{&ZM8>qFfJ z@~<(J4f3x!lnwH)HIxnVFX((zkY12~L1&SI*dYIc&Ljn~LH-4uBMM@J{0llyG#Kh% zkh`GgRf5ao2F-~VL3?#S!`5}6&V_>fi(amQ{0r8bpgi$b24uf`0%%NHo#W?!ZHT`g zJV%Y=3(FX$fbP17w_TW_{sH-!9m)pznH$Om`I#Te2KgCumOaQnAU}i7n+LH$eg>U8 z4`PG-3_2?w#0L3Und9dRb*P^~Zc_L7`A{1X$5TLl2JO$s6335l)!#_%w-u%Tr$2bi z@DuFs-|RpC|7ZXCV6h!yFF!P{CxQG8+RG1im&U}G*V!TI9OUoYP&UZl_n~Z%zaK-{ zAb*3-eFy0U`5SaLJBSVPH|UIZ5F6xg(7Ea$Hpt)K*?+$H%?>HgKyLc&{`28~cX)Xg z2J-h~>~W1A&)_&#P@VXInQ0ZcJa}Q>KY{$c9?Ay!doz>`^7nQq8{}`$T@WBYf&2}+uK~mc`5Sa^1BeasH|VYf z5F6z0)9gQAoQL`w!MOZYUe%Z_qtE zAiW@egYLosu|fWx4pjs4_iQK|uON* zHoCvTer-@f#P!K&(0xH5KY{!m4;2Ub8?<*ABo6X7=-wC*8|3e7s2Y&JLHmJ0;vjz)v;TZi4)r(4 zP37)CA66s$JqP4((An_B#y8mC(D+VJp136a|MUlkq5k$}|M}ma{pSN^%ZZ>f>yhVP zXMy~^AIaaK`=vl`1o>MV>UNO7LHALC#6kWB-5CX9gZvG;I|{@G`5UzVAH)Xv+a9VH zsfH|QRFP#A#x z4Z6=B#0L3Wn*HYsd8ogY*?&HecmMfN8R2gQkiT~m=WlRdtU(FV7l(~SEKr)p!?-P;vm0+?tcfdL4F6_0}o<@{QjQp=Znv5kTMhI%hKmVU*`}u&`bmD{MsBwOO3FwSJq&Qy; z^#{n`%b{$LzgI)qAb+oivO)gd3}u7-y&cL1`Fl5%4f6MXC>!MO!)!la9EbWFac)kl*W}Y>?lZp=^-f+o5cb-@Bn~ zkl*{+e!iFt^*hK-lihwkoR08&3drw^iHmb^xel(+p!N6yjfty4{m|LaI8SH$`9B*J z=SJXt63G5e0{MG7lE0myZUp(;9m)pz+Z)OT`P(1L2KhS}$_Dv69LfgyI~vLc`8yuU z2KhUg?dOYhsJ}sO0^L8FjqtY`$lsuIT(HDBIF7;ogqGtCniFLT{!a((`vA9Btl55o z&Z~Z~*kB@PKL)ZtH9-FCNAjmQ)J-6NN<-Nof67DIAb%=D*&u(aL)jpIYD3u|f9gZo zAb%P|*&u(Kv;BNw4fUrz+s_BqZa*K|BmDX17|7kk#V^?33~GommIURA450ojPDS)(!W>Y}_uYfc1o@jC$=}>;KVR@e{S9&xzuV7;!U%t_1Npm~1b>6p=fcV|2DOP_ zLH*8VsK252)<1ZxJMlq1s=wEO{9TU}-=K4wLGA^`H|XqU5F6z0<4`|={0+M29V8C& zH|Xwn5F6z0%TP5Se_w~PLH-7vXAM#Vif_<;@{d^|W%zT}pAR0p{(Sh{6<&rHfc)J| zg1?c=@C6zZw}bp$4fXeS)}Q}(gYI$GnfRa_)!%s_f0rZq8*~OV$c-R>gU*2lu|fU@ zodpeIgZvFT4;sV<`FkniDnh|4)BV4E1L>>rc>q*AJAnCq4k3`+?N|Fah}!v?mGd z4vmQ~)1ht!`7;~J2Kf_o{xe7o$e*Ayph0YqKSAd}gV-Q{g3f{lu|fU>-JK0$gZ$YH zH3#HR(EZxoP=EHb{(R8w`txBw!k<5mg4~VWpXlvyu)mShwSwwIdr>Y} z=Rt$mAb$r#^@98z4rPP<9nJdlMLg8s$*eyg#Jm1{n2hlEE|9;o$@F)F(nLm(zmuW< zhTeJoAX#JLgLu?*y#wU$cqD&=?wAI-9prCesCz;F7KgGy{+5QaLH-7vAq`Rw@;B%l zX%HLaZ_ruNAU4R~p!1|bY>>a9XG(+Dmm{Ak4I1Zd(41HU@;B%n94z$|dfNot9)-<~ zH7HHw0HyJ0sGr$ce}eAJe!#3g@j*DMpQ}NB4oC7c=zL|6`#^qv&H^dNL4JM>WrO_u z9?Ay!8FU9WNIl5UpnI`FY>=Np=TL*#AU}i7q6V=+er9I<`GOr9*W9c>AF#Xre8`Q6 zYkQENqe+Ns>Y}=P`rWAb*3-WCpQ8{yvQ4@8eK5$lstlut91-{s!HP4Pt}*eHp3-JvRc{`Q8(_j;C}pnI|(IIB#2;Ew9= z{|gzWfcK4o+z1*c?S{G$g@gV-Q{gU)pZu|e?-I@=k<2KjqFR4>Ti zi=k|gzn4SVAb+oB`3X8>8l1*Av;2Ip-sR`R%?N)VJ_0(E7rVb-Zg=_#+GEXF%Q+is zdI!xJ`!P&;;0*P5GvvCZZ_ruMAU4R~pu4p}Y>>a9_iKaw-Hvp>HZ*Uyg8c1_ z+uxwQ*Es!sKz$-3$lumbe}}XD1l@!EpjmO^19Mb=H-r2Qx~B;2E{%yVjiLSn`P&@I z2Kn0>$_DuxbT=zVJ;>kAP;rpILFY|_#6kY{hKhsy4LWxkBo6X-Fw4&u;m~v*&GPd> zxXaIn(TMnV2l?9?yT7s4VaQ`D2h=C}C;y-Rz!>UpZO9#m50n)qKF~+?w=2ls`bgy( z=xkBw?($0p zod=ET@6!tyro50x@;B%{JCL71{@x6AFUa4Zv!X%bAb*3-iw3bl{sx^H4Pt}*4LUa( z#0L5MI8-ml-=Mn%LE<2PL+=*^$1})Hmz{q;yzUGy$NNG42Hll~rOpPeuf-bA3aS%% zLGdgN_3v`#pP;+>9x%&Hd?1eM-+qvP#gY8m40R{SzwJ;q$iLlCHpsvIP&UZFpfjgI zegXLxbnY~W4e~GO>}e1iJ3A#t@!D6Y25BO329SHI_Xg@C4T^bW#hC}@X@;B(NFOWFM-|>Y}=TL*xfcy4pxQ(l11dj#8~G4UnnJZBIa zH}ILH+=pLxm;&;CqFcH7`C0X8iduobl(QXvUw9L3eH^GyZ&<&IrDX{6(_k zPtbb4m(V*^9voJi_`sbJz884je1<6x+7H=2$ZxWJ@K_aom%zhzCd9pJ){H-A&1aYb zI)~w5yVK4G%&HToA@h}0CQd@;J1bA@L*^$dP3%JEH!DtTL*_45nAikz2k6d%aL1po zKzEe4JMDbx?g-vr2RbVRcD9G&U&qN0y%~Q#zU}h!$$b~_nRYWkV`ct~KO0yWw*2R3 z`3brk;X$)JVqG2d%*#wr{DRiiJyxCg5>#g}t4@3gsxOpPCcXsUm8%TCEB9rx(!`gb z`x2TJC%y#L$%_>xzT{^43BG$5bk4mn%g+b=Ewx`4Z&* z^Pn@vRVTi@3_4?6W#Y^0pu78&C%y#LsUY`*>Qj*WL3Js}{m^@OUx3_?d=KwowTavy z_k-5AF{8Twp||7Dr^s$rM(p#n2Dw=q8s^8D!S^9NaF#`^XM?(#2jphZdNz=oS3}(l zs{cS?4yyZ{l_$Og)q5Z}gX%nxn?dy*$jyhDf4%_Sj{tJ>Y382~jywN+c-k2p=JyVQ z>TVoi9*rZ+oe}$ExIyk$hPr<-^UwdwnSVY|mO-pZgS!9DJW$;Y4RcW41xhoZdJE)! zP@M&GKd8O}xgS(lf!q(Or$FwX&;0WRsBQweA7uVw=bsOkL)^a({;6V+3{kT9Dg8_q2n;9#qeO z+zzT^KyC-sFCe#r>K2gOLG=pA?d8lrUxM6T&HVF4J@Zd+dI6bV@BH&&GsNxnAh(0o zhM~C~bk74ydTB=NMOhDWGe6YL(ab;p$AijX$%zlRQQh1Cax*tHyg_vV$jzX70OV#+ z9RPAO=xzg$n?ZLQfZQAmb#plL&lk~9H-pTNcK-P=9^&R8kem52(+h^17c0Q`&oqJD z%no(4IrGo|*33U29F_o$KmP=eMM1+k802PVsGC9MJIKwT`wT#C2Hj@>ax>^Y1CX0R zbtA~lpn4G$&c@6?UzkJP3^L!``R7Axh?`YGZU)^effmj$LFG!c#bd;tQxllje+S6Em)i`edypSv*>C!u;pdCPF5vqtRxmO^&il9z zx?h3yC-}Uf#|%GT$g}=@Anp3|p}Z?(|M7W7_i<-zBI zoyQ$6Po{zP0zu9t0i90*3l}F)xGV18n}ox1!4ozJ!cwqG4|-Y6_wKxdw!hl@EPT-JfY1e8`l^IMZa z_qsd$d}Qvp^NBZff7E>3VKRT(zv-_)`3f}m3Az`2xdY0cnBPzSO@EQ?@)LBP)(dtl zX{H@1Y(Qt0wj+fND1A7i?I8n+bwk4@8!c>{vFslMoqL)Ox&sZIW+3~=Kwf2%Bo$VG{uh8_?NfpgR?sQNw1-lYi46 zgW3tn3_l;5r2g5aP-z;4$syxc}21g3bzyclh}<*#X|3 z1C0-HgVy4tGeFvN!puMai!=Xxuvi>1E(|Sqzs_Np0y%ARTnKJ8F9f zrEXiSF!3R?>cmIR$`kK{))fRp-TR*D=l{=4KOZ!UA;xo|?mY=|FK9d$R3Bf4y7xNh z{CJg#FG2T}fZPkZuLR^?(0wH!_daKW)W@%xe!h6m1gVcf=D&CP`S7#TPf+`FHpso8 zaapu_0>!<_N)Y!xR-L#!4m6$#b?<4Wpa0J@{d|xtiWrB5x_2(fy`b~EK<-@+buZ|C z5>WVVXZraP;GyQzvEP@z6g}S#8`OBStK3olPuQSNKpm9(<;rlQdw4RJ{)uYF% z6Qe=t!5Zq`W~QJ2+nIhoP!>jvdqUmo3UV)K+!N&9bf|l?q3IzX8otF$Kf(Qxa;Bdz zLGG=Fy0@O`C-{61P}>q@ezVihhwTveii6w>8o$KjUQqsg*sM75(PD*(%AoKyhPpSN z>F57srk@X(g%IPFQ1?oL+zT471i9B4>RxxKd%dCV^@qAQ80y||sC%P9XIwzT7i50C z)6a*=5cj^`2O2NMpB|9I*9vWJ?LF0QMw_b<3^)}S4_ZcDO!eh`G zlu8pp_W*;_?Q76o1qu^ig6=N<%m^vRK<0mT{0Tbi0OZz8kXxnkr-Mh}e8#j2ly*yF zLHEl+-3z)$_cG}I3tq&y9MrwpAoqgCC;$x}_fK7SMiX z&^~5Rx&)cu?)dXzHze%d?FH=@kze&6%`Nb8t;6gWpVc$`eB8|N^ATt*PdDgnd4``) zCo}wfG97v*BIr!hZik<*L1)2EcKG>by2H;mpmX}ZGyHtT%r@}>GuJB6x&hc3y${nH zY#$_Jp3(cbyutQSaf9u{{07?x*$uX@vKf9ps6GHz`wDa}DD?bTFuNFJHs`8W<&g7i z!Dob4GyLRW)`zb(E0qk8Nl~HfX-WFvTO)?q|UI@nYkfo+2nuIUvoSBeAVsn z^GUG7&qwMGptH@v=lQ?UcKF%zvG(#CeTJXenK?gR%QHai6m!SCThsF&%#6Ix(p3Km=nUB<0nau#cp8|A7bdyy>&|$`gAg9UyroRG}E$j|I zLG%5v^F2XkgYwdgaE70m|No0Wgr@rk$Nx`9&lB+S0(`zV*TrY^8Gb%q%<%IOXie{G z&|Mu2Kc8-9`1xczB+b15_3t)A&Psg++A}E+-IwUVKJfvljA;j*0eirfk@bM>!|E2> z2jwlc44emS8F>%bG6^2AWfnbP`?$Ns_ECF_?Zf64+XwY6wh#J`fYl++&Ssyu6LhBS zYRDPlp!-6ec7x6nmS6SiIm6Fak3nS!$EsKTp!@<7=Unw_G9;fdGIDmmU}jwPVmiam zC+|IeK7Q>1K5zT}L1vG~*3TGrtZ`PSdz=bPmYKfz~o7emS$P-S6;fqPtZMOT(u`>bJudt2Jh>73<@jm)f|jmyFh0EzjzMuGpOtar`ddlp9er^ zd)I@`p@sV4G}LeB8GeGsTR`W*!p`s7$p7#V6=j~JOSnN^$tHdSsi}91l|9{=>Qp{(*}(Nf%7pWKJ-CjdJI1w9(VZp;IP9_Cg+Br zN9hbZLHXHl(!c31wHbHW% zo)|%Cmh<%sb%_5#{ec(C44|{o5odsd%z&K%E)G2dTpH;NaCvB0LC7&MJ?Yk-KVR8H&(UV&n)q56RHt$NeCdpI1~{nQEDv!L{0wj;G58ta@(w?r zK+k+eK3f}h2Dsp)f74%p?&Xt*)El64r9tfgFXS`8*hpgr{< z_v&+k&Pay%L7VgEOKs1euk@jAcjTJ*nxEn4E6~1qZ=^H8LH4mj+zxjqyTi|?pgM{l z`x)TRCqmuH4azs5x{>qe3w6$)50pKBK2-Po`7oUG=YwF*pFf&FV>ysBz&Rd3&j4?C z0N=HgbPRT0GHN*oFZ-Q^FTP+FoCwOx;Qe{G8Gb&x&+zl{V}_qko`cSvX88H=wZl(X z{(Tt?I%5#j#}%9i+WQ1M7dd(c!xYdxSnzX^l?5g~0JSBU<+UExGa}|gw=?_M2fJr^@t&OZ>NLYoMNWo^kCmN%K2di9&u=Ci_&*(V|F8lx!E~m0r=R;k>jXD5`~izkUfCn_kcG6Lc5T3(%faP#i$TUaofd`2uui`E-V#FK2`5Vfj_B z=7aJ#Bz=PFs~6knOa1R>{P}+}5qK;fBz7D+-ki^XI(MTifO!^CGsDjppz|Etk;;D17;`ccq+Tdz`1v9o zG;Zkh^I^IZWbWoWV!ZkEgn!dtPj~qF3bZ!87*g*)`tGpvNxuVR-liTp-V7ZVdJygO z^I^Obc;05ugn!dPZQmE5wn?+Y&j;C76FnDOWTaK@kiqe1;_fr&4JLH%t0 zi7&&Uc`%ys=Zko#JCYfHK8Sbx`7jyc4hfJuKx>oH-0_rI5MHJ{Oy-*i-rMfXKT##} z|MUmpP&arp{`?O*Z|X7U#Q*k;KmR*3{`~I_b%Q8uAU!75Vcl`MRv~B`)7K|{<&lln>KOZp5Pkiv2;U}z3_H8P|ln300Y#)4Xw0)o~ zHxYCe1!#=_;d!L?*nNhdpQbWQd34|5=fm@$_L%I%cgXx?nTfBE`OVT3pCR)XOHF)) z%s(tS@gB(D#|}SV{&x8J;=JQd(A_1V`-H&j&)$RDmd-z)Ja-1S&whZ$GCwo?bO4R< z8#Dj>Z_W%^Cj#oXg7#{$LE`7+RE8E30f!8EIsih zXr0JnDaabi!;%wU>NEd*Va)s!bcY>ioyY@Y=bsPFok3#)6X$}$9dw?Fvm#0x4z%Xs z#cxo#2|Xv4S$^W<#}M~|)@Z@jot*-?`#RL!uzA+Q;u9Z$`ou`?o(*#MWl-B)4l=(A zayMvx736Nv{3^)Zp!rphyFv4-Aa_IOSHbQ^o?m5_pO_DF_jOP{MRhma%|GieKSg$P zvJ8Ap&Rme2&qLk(nd#^M@1Xec{=YiaO8tP{7+^X!vm*BZonTapK zbF0!5UxMdWr6#_74Z7P~a^g$S{OV^WNLYi+{p|Gf;ddu+SUZ8-e4Ye1H%r6aTmW+O zaj2UwGyVL39pq+FaNh%zmSJvo1iASz)XkuIRZuvC=2b!A44PL3h4XRHoR8GRm#3j_ zKF{>?#bv0QLFQg|`uXrW#Lc20Hy_91=JyVeHDCIaQFG7c>2Q33BstsGC{d_nb z65cyOZU>!DfFnP?JkIeK3euOd$q~{DGYLh=wcij18I<$?y7}~CpX8HL- zp5^BQX_uc55 zhKb-cQm{TqHq*}+`Ak0_WIO$QnD6w{nWG_SHpqSN9e#rPAP>OnT{yd6u6F(jTPqa+ zN;}7$f4%_E4KaMoWo8Hgjd_C766hX|SErqSg65Gx_i?bWGJJfJ4h?5V?ujpyS$@6% z-SwxA6uxZ2yB4~^RoOi+V_fivIMnm&1=&lM-yO*IM2)X|U%DX?ef$YW1yC`lv zEIIL^v+TsRAU8%s-RR8p^S?W2O@|<2jSn=B{+SFK7lM|Fpt*Wb9tF+SgUT1sTs^3K zF^A?+Yp5GRcUm|@^C;L{r=JhqA$jxy$c^Cs5o+CoQkEpkOaz7FBWKx(cS0e1HNkbe zGSkoh>L7OtAlCLk-FXS*PSDyOP*{TI=RxiS&Ci3}DGV)3#G&q#hPqRp34EsmxQ+yw ztL*gip*qB!%Rue~t?5B4OOV6zVX_Rk9~T7*OK)gcGBf@B&kk}UKVm%()Qu}aZUl{s zg4_t2j|aK&J*ZtRGx6nT(A=%`#FyVebGK3xUxL;kfXci7j6Yv6L&FkeF0<3mhwKnH z)`Hv!TE~OtMwGB@mY(r<)dcliSs~xVr!^74>SG*jk!H=2A$K3+QtY4xf3*Q4RR-Fd<+zx>!I!htup|n zP0%_6kUK$Rb0Bx_2aVl9-Fckx=YzwJKOY{4xKk74PSCm?G7jSc29RfYK#sO##S_pm8{m8$si6AU8tC z;lSw0{m8$oW=hK6G^<4@2!1MnIH*uFq$d^3aG2-+72 zawBN01r&~;F&K~=L2C>^ZUn6{0J#yg#sK8Tdd8nGnxWy?4qEr&`12v?40LAsiPyJ+ z`nZ_o5OTVN$M<5XiH}1d`}n|NnaubTG!FE@nG3N-2kOq7lR$d`pkk zoVXL@PHAX(LdRwvICCP_=Rn=L9^_8YoB}93!TosIi7&zZc$tYWjiLF+9GcIq8GpV6 zxzipr4ghthJ1Ac|g70btxw9GMPH>+Vwak3+9aL{S{ColGt1>ct>;=_Wn`hC_Daqs1C`mwxDnU?axAsKX|{lS^46F`wTxHK4$p&=sCmB z$FD(ix(q)-`T50bho7K%y_d->KVPJS_FgN3&lZIBdo3n`^7kRz2hvTp4;Cv-1dacL z>h6cjk@~%-8Gf2fVwm#iv;%0IeCLD1@)He^`H$r$>LBx(61li>+NKBztR;CiF&gWHX^;JqQB zeLRQdC%y#j<9RGM@g-;<53?M2AJ2>3%;5d-FZMJ4e6ZX3=fnNZKOZ$KPW-e5be^Ka z&;QNJD1BAX{3fVP48L>mFvHKM&59Er8@v2`V(#)27camvfSb4gKCGLFJ?RZROIFA zetF*+>^2Q-Zd(p@+i~ZguVH&3teJnluxI}Hz}oreLwo0+O!*B#kJK4=MtA+2j_w|C z-)=j!Z#Nz4F6jQH2hedTP~XW16M%xFI zq3Ibk#s*5ypfNU3dIpWLfzq=&^UoLB(Dba&{PTgf^UsI+ko0_FGstYratgUjdU#lV zB6$9US#IK$AW)wN>K5o28n{eimYDdUxzYAPJJcfS{1EnkI_SJ0aQXe4>F59dOwjUMeBy)hM%xF~ zP`7}`yX3*+UEuQQGiYtJ+{BmPnSQ?b4Z4%EA?U?_rk@XfJNuAffYvG@y9MNqkIj&N zBsgxM<7r@bFpExn5Zq|{AROur(3ly>9iTBYkUKzQW*~P!$IQU)Kprz|R-7meatEld zh!!3war0OXo@R~X|4#>#qpgXc3F>`2b2i5DKbAdqh6Lh}> zIBc4QCqA%lw0&R?bq{DS1So7kdm%vX0gc&#+ymVU0S+7Fy%5cc6R&{W1L~uqg$;82 zJY6@~%TR8#eV`6? z3uqq(C`>^6FhF4f8pi>J3FxlRV5nQdnZWmLJ`9J%Q9sBnp#Csgn1IqPs#_RW!Q$vT zs10Ec4IAj53ve7c3r>6>-e~(k8tNX<7!AlhpfMVddq86}AooD`Q-I?Lc|S$7;>2u_ zd+Z5^4J=P@1C1kq&J_ZM4RlNf?3QMMi4V9NZ6EMM-2xhS0l5V&^}*4?202_{?f{j!lR<7VhlUF`)6f6>(0Bsv@%Z0h`+ynh7VvnA z{KS`_JslvofcA8N+yYwP!3~Wkex{!fxSf7J1l^(8tT<5>&%-VAWKAn(m+R-DKL zato;6j}|Ui-LhC=qA$oT`p|H>&G_^GeMV?q#5eK5^9I`ouc2-MjqiZm0vg`|g$rnW z2jrIPpnLfkA$^Jaj6WaTcKrG9z9YCUy1()N^auKw;qvmZ16VzHtp!qD@PJuvVw^Sf zj3Q9jK*w~zVbjbz@xko|+Xwfd?g5S4fZPKbw*k2aG;RZO4|LoH95%?~HqD9?cZ1vm zn*T-%8<2ZI^VAsbc`P^43gjMjX!tKTdcYww>(82}O zr$TlEsE_x}3bGymTqjjC{`_ALOE26LA8c>1eXtwq4$$}zD1JcWL!kHpjSqp`0b0WY zx~C2_E?v*~^Fg&EXl))iy##~Y0a_P;<_?rR4Xpz}c{)A-vMvDZ7U*~oI82(kCO%l* zVEbS_)GeSfACOx>V?H3afW~}4Zh?;Zfa3;v%%@p#q5;S)ps^G*w_wdj%yJWLKyDF- zrW5G;9I#ssb549PzrpswVyIid<2dpYUxL=@fZPIFrvq{ebe#^^Ey(M1niVJVg4`mG zC7qzPFG1~>M~CGnN`l-1ItK}qR*V^c{x^rl5i{q+2a_9YA54e3MH!k_)S=}IXbcME z7JbH_FN~pS#hmfy17pXZ56vNI<<$nzUM?ctvRGl_H~;_BLFX@l<4BtECuqG0I9x#E zKJ5**54xdl0gdy3;s`X(0}2<=I1k7z;*39ENJHHs&-n9!wByf*@({Ni2f2kG(=DL2 zgrKns@EQ!*co%4$#eJmlE_S5xE@tp}*98to?up>D7(jDA`7A#lWV`%)nD6pa2|DM) z(Ee}wOJ>j-56GMkc)aUAmhrCpknuL~c-MXCco%f73fS+>>=PeUH`qR?hx#3~b_3*h z(3%dA-+wdwd-NeWe!i-9`1!is;pdxfho5hLGyHu0pW)|I zXVAVZR`9+o2gU=oj;sf46AEYux@>m+!<)>-s`t+Hr?t&(7ats-xO ztpaC*t%BqMusZNQqQeZ}`s6`;gYARp2HOYW4Yn^q>ngJueljwG*3Gc40?o}mIq&fE z@o9&j51d&ig7!r9Zv8*~1vA5{7sU)e8yF$`D8T!)Kzoy*YcfImWF9UD?L*{19jgNQ zD;v5_Z8gJBj)M-CFPPaZ!E5ZZA#w8xWDYaes#nnrKVQa!)`&sE1hhvAw6EX=XkURp z!_Qa23_o9nGyFWk`(ryu|Eq9^pRYmtpg?v6JN(oXJT;kv6_g&be{g){S_R%`<_=n~ z%CYK|H^Wa3UWSh^)aOfSGBSL830kYc*eS)q!C($H%iZDUYj202FF!METDj`Mr;OT@ zvwdngXLB&}bZ6Fb&gT1DbD96+$;mI6`BuGT=3n)ek$?3WM!sEZ8TnWDF!JrnX5@YC z#mMvPwK>DjSJn(aU)nQ(_h*63egT^Auy*+Q%HHAUYtWu0b%vj>v>ATB1nmnj#_lc+ zCaAlh`;9<2f_?LUxM}lR6_P0yaes(0ekwE`uu*J0Xrm|U@ble%hM(`2Gfq7CvESxh zI^)CxANy@|MHznT2r~TC=4JS)#mVqfgB6n29)a8e+KF1-%Og|rAXZrc%Hq+0i_nCe^d(89`WXA($4y^~znSOFGG)#K&n(61m$4)I_>oHCHTw$r=KsDYfWVMc;4p0uoEU)2SJs&5)59?3!FH#gFE2a&d{OSY6TF6ulVRdhX5ER87rXv^ zvfLHChAbU4j=G=eCj)2=*?*Rw|Cw2TK5$l__+UN6T^!Igeil8TH7ia(UoO_3_!4y9 z@nNlrFF|J=Kh~W15_HZnv*yH?pfiq@H736N&GPfbf0mysKy4zBdH-F0K4fn>owU0?Tq`h(S&etUS?=_hiygW?l5x8MK@kHt_oZfE)Ve>Z3?qUyv4^HJS+qnlyM zi}_GDg3c2Lxe;`hFvyLoS$@6*xp6(q&zB%KZf5!UVms80AoI4n{Cv0@;>L9#H!jBF z#_MQqe5?tdZx9E$aW>SAvsr%rpAT9;qB8NpbW}I42f1-N)Q#;dKVO2}2s%R< z$sjj^&Q1ooaXQP-7qg*m1erJ6<>$ls5I44h+&CN4jW4e|{RE{GQ2nQQ(82PhH0#b6 z@~k`mH)~ryc&s_`|6(o6hs?SYKW+Ozy@MUJKY~MxgXiQd4p1G$!14OUWTu}SZy7$m z;$jGSIoauF275yg6C>yAN9{}~@$>Mo7I@4`A2jFO4fS_D%g_JKEI%JOD^GmTjOy<~ zkiVOu{sx_k4DvVVOk|M1LFXZZ{0%w_8RYM3mY*-`q5cM$SMT!kVKc^-%XEv;6!In$H8BQ&5fSK2MPQs-f-!okt9EUoa@|Xij_?4oy4J z(6kfJ^7BP9)O}#{Tz)=GhqzB3 zz48Ay>(Bq7dpDZ(C;tD;`t$#H)}OBqYfXIhnf2$Z$C?vgf$r+~&H59(59dGY&sV=) zf4=vnVMDef_r%xtS%1D}YY2M%nDwW2Z$r@Q)7(3~85)9KpXc5QR>R0Q@%3xg zpWRFiL9gGl{(QyF_VXn_2)q3Rt%Z64S_c*E^z%iy6DS-fzVK%P?fHMr#mo@$(%wMmclCO&4?otWFnFy#fvyl|$UPr&VrY)cMShQb%(^QB(2v+R7)oNf7X zah4?qqh@vjBSXlGc9)$U3=C$VFnVDRiF;6;3u3>pcLJYb@&uF~+Ff>f@Ilo5PiFi1 zKb`I8%Vfie|Ml5^{x@cWgrPngBuqi~wi5SE~`TR>r{&GhpX=uV(3XUb6}!ff4)?P*a;3pd8eN*mBD+6UiUIEguHm}^z(%@(@$kkxV?t36+moxuzNqg z5C@&N;`H-{Fw;*C<{#T%2|N9K;q3a8qcZEq3((rHcvtYg;g|eKc5plWe8~^7qZ7#v zP`mX7)DCu#9l{7Zo`d2a)Q*#8`uRc{5|@Px3?iVo{%_9q^S?D(9D?!#C=NmS0ThSk z&^WYa`}xY;?dMBtq&Sp@#-Thk4xOQK=#CVJ>d-jUX8ZZdp6%yL(49!mZa-f#GyMeZ z#d*o>^z#L1?-eV<#25b=5&7Z2$Kh+npYS+* z&G-`>hmR3bQpPj$Ldqp}UQoF-AsbZ2x3fXY z_-?kJucov8d^sD0-G0LM%Dz18`18eaaQsbtu^$rm;4*%{-tGAF!FEuZHU_8ZFYOFdUVzLy&WKsYr!!-g@#)TpGJZWHxPAwh z@u0o9>m9-8{ea8(bZ0~v|D5gTf6(1}_{#X_(6D^X_Vd+qx1TRxBZcKyLLF* z_XNTcv?dW0ma`duzWUDg^W|@7Sk89*`2ak=Yz7X?g`ltmnYSDomY^~ow7wBk#!rUW z2`(S{9e=)@49UCjGQJzBeCURj5B=b{|M&uQZc)1rjBj>Cl<}Z7h_Eug9?6bs z$Dc3jA$Gvahi;_up&MF0G$ZVQmk-^HKVNi1;u2oQ?`He?A9PP3avY+U@w=gMxS#Fk ztKDutU+zbW!{yL8Tn&xGXlNY9BgNrnXdG?_)%|QgUmgcxx1TSI8GpV2t+_0A{Q06B z?B0nl@*#c&=ZAd9pDzv*h(pl+Sx_8iGyZ&an(Zg({z!0}C)@GogLKEAkCaWpacBUF zLy&pp&^QE@@$rm5UxLc`WQd*MIE;7v`7#+2zVJAVMvB8|XdK3a-TU!HI3xJ{?H9q& zGCmloj0dmZgqHFCNOpKT{(R{Vu>&55(MWL^4UNNKgdOlW1ntWOo$CoYe`__!4Ae5d z{oj9a(EbACzA>o3BxTAlP}$@dExB%^ChVL&dB-Nmw_Qf znwdf5RkqX5m(CFXyf9`2w>?4oGr?n{pt%58{bdg^M-kLkbawm+)>rNNlY^1#H5V(x zM-GOEmq6!?=rJ&eJO=IOw0HdZ+Su{u8)wI#@5~*4a&R;Rb+R`Ey=CUqTF=P%k>ewH zym8ejUYE-!R8P#}_{hBKoZ|UeAUQ9?PB6`3*f(n}Bg4lGhK^Z1tPCGP=O8&Sa<5`! z+viJhF#Mau0qPI7&zI6-VED+v*eUfuAGEKM!5k#_LZ9*HD`&@_ zud|(gzR-94`Lf#eCuo1a7s%aj9VUU?4VMRvyCTWIQfK_B#mm+0$>;#;<4n|i>oCca zk>TeH&|HMN&CU*(;#>5+#n9A$@Sr8p+BH|EIqIg}u7#&zJIy zpt9}b3uRCkGkoj&2%PV=upD)B6e|muS zfU3Jf%a!aO9;~3X+nN(SK;t#atUp0+W2(&jfn0Zk=3+L2)&UDc>uh$GpZ~c*{WAH9 z5BO2*?6shL#Sg8sLFe6r`kSEh?m=}n=)8MSo&6tle!K?wy!#jI(0&=nJa(6#54j=z zvgTEwxf#ql8=Nk=U4Oo0XZ*>*$?)+7H(EF_L&Jd^l1@SUSza(R{(KEehwP3&Uoty_ z#{@y~@(N^5yz9>#R)&w7l{r5=Ss8x9#560je|T~-fXA9Z>qK9I?g|rT|M?$uZ!S_> z;We}7#MhwyAgC`W%ns?lh_nBECG7t5rMNq&{{m?z{D+o{%_1;gv;TZ455n$0UxLob{?7o}7y2JOHazjgcLqe;_q)T-7t-$F{MZRPF9KU% z5VW@zR4#r7`HB7KOLcZgU+}ZT&j;@vem;6^4lWm8wK7Zrt#JmO-wo~y9?nGc1+O#i zd~rC_^5x?UL|^c_Bch$~9I}55+)e!Ie4u_rHZ&~r*?+#ucK`V@A1N%u*&%(wXm&_na5pq8_rt=Hf8y(8c1T|^o&D#l zV)mae%R$)v=gZrWvz}hwcK8XNTLbkYt|Nuzb%&oXiV1|}dC>U}Za-gMX88H4n*Ar} z9&&IUbJ^kNgYynQA1$^5hvjroSc1&E&j4w2vAh0!aU8VQ+4bkk(-1qsbqwgdhSQ+A z9Hf54VFpA$;xGfGA8{NU_a9$?&NbTa06yCY+)mgH+M^B1^I1P$Y-afRQXN{yY)7&K zdS*9hA0xbuIn03QM;wNpVYC}z2fU6s3_5=a5|{9Hf<61s|De0Gk=qHNxC6x@C@w*9 zXb+7;XZD}3?A?F9bViCpZD<_oL*pY*uiV*xzVrrR_n)w{R$%9< zfX~2M4)H6vov<8qwi|&soDYq|#h^2X*nhqZhUSOGko|#=oGrm|s0NBdka_E&aj5M2 z6EvUklHC=2mJ296!Ep#W2WvK398N}x!^zM%oDL0N&|F8q1Ndxja2$fx39Ccnu$kfK zOKxZ!wnO{{wgWW((+;r%9*2{W;&3uF4!aR{z~c~fra9<*a?ttrk3nWIe0*_yzLW<8 zgPA613_u#(wwU+=bY9y;#*exz3?ctv_kt{zoA>}U?+TjpgZ9mg+Zd+2sCIz#%|Q2n zfXeyXpta_j6JLVv0RffspnE_-b|UCLQ_vm;*jxrH z$lajx+CXy|pu0an?gric0ji%s_gsP84Z7nBlA&=9+D`xqJJ9_k zps)koPXY=%(ETJJ_f2O0`C>ZMeIWCuJO6w*8{)nmko&-Aouh^wXq*u=?#L*>5Q6O1 z2h5N-hRvIN0_l&3h9~T9EM@75pmS}I-P;9nZ#2}sp#23P_k#8pfZPkZg9PMW&>bWo z_d@Tr0;kb>=ARF$oqs;8hqyNZY#(NLVvFmCh7404ghSmH&;0X$GHCt0)I`wTo5*fU z2DvR5>Ne2bA|SVc?iK;L4Rp5%$Zepzyg+V?X8!pi9vYS)^WvRg=ps^Q0ko){G!w#08k;aVR?O;$FkAs!rBdBk3^Ur^A z&=~c@#jZaeEqDD1nm>Exz%b>3I`hwm+RQ&+C`VdC$D)H?^fT;a0hMK!ognKZ`Wbe< z0L|z2JM4VftZn&%jbRIT-c=jqSKWy(H~oj49eCR5CpYLUzH--}ugh6~axpUe(jL+ zz69-G0EG$o4hT)i86}`F`Ooz81v4~EK;|(!|9r>}2@^k1n1I$fq2*Qhx&~*_=Tm3KpU*&R>OlQGZ$`xW27gBIeo0V%c?r75teoxVi)yx? z515T6!uIqzgWSGcAF_@?x!LxCvf)HfIrPvS>8>?(#-H{r3{xJuJMDa=?)dY8v%y4b zWPY;#L~~?*v))8wWd35^iTcR=!#WeSk@=6cC#oa!nYAY>BlDHDCdz}{3A!iE8Z?Fh zS?>gDTY=`*IC)RbdI{=7GcsJzd5$g`|MqRK6D1HdoY@KVHwCRjz9l9TcWH1`7g}+^S?Oj&j-os zhNa+$+qj`_ z<7fT(LKx~ckbThmik>hVO?>3+_Vcm3+s{1kx=hBO46F=WKlx%O&^^x}cU=d~H)~IPc^fp}tUd81Xzd0l z%%JNxz;{W4?0fF=^Wkey|KDh0Gbqf&F~baWA0TKP1vEayT+2E8F*_qlygx|RpZKs@ zZ=w}wUY8r{pWQ4!|L+IgcdY`NI|r}1;eh(55#%4xc~Bt#OlSG|66BxRERZw+y2lyh zAJCc$kbgjHE^h8YzECiXo2s_ez6;R$1ljf-7Y^L?uYotALJiyEdBwd zd2L7V`XSI-1<;*XFux(EXK=n%)|$uy^4EU`NIdnk{QN%|x-Q{6s7{mDg89oEh;V&kXWcJ=9;#(0Br^;{e4|H_Oi#{ZM~_ z?CW>=`EWACUy>ky{Ri!PM@`!(ZeOfB@!@0biI0>GCq7QrpLpco|LG4tL;V0-yYN_X z;)D07evktB;XTw3pt*dIA3*mmgZu!xa~b3Z(0$7wKY-UZ=uCVGUfZAzUE82N@g;a| zgVw~C(6tTVw1%>_!D!-(r6BiU`r+Yk(D?$0Jo4bN_QXtmhAE)4!oc~&oaN_#YtT5D z!o&y9QQiI;bhhkssM|qvRv@>7=Bz+&muC6-66AK!oyj1#gYHWPg}*v9{I#LsuMbUE z#w$W_}JO)=M#6gpWw6u4u7qQM_v9;2c2gI zc0V`E&;R_O^*r(u!F$F*{X1yB*bQ<&=p0i}z5v~a401o{E@Y7VLH8ho+z%Sx1GyhG zz6WwYXnYS;HiE|YK>30h>V9^XpD(zf?g!b&?eg;>Kg9i=Aoo8ecJucZ1vyI{yyjeo#LTeETSMnh?0I*B)im-=e7%_Mr#EPw!*aHtuRwD(huMCKba;$?iT>!EgRMzW(F zY6oa8w%zULi*C1{ukN$`eDN4z$7%+K5YSlq3xCI-Aa@&q*FP|bJl*W@^TB<$pAR3q z{ZvA-a}UVQ^`LeMXbm{SmKQMlmqYDejbwj4)c$6+pRelOe!ggS`}yiT+s_x55%$CV zxEeH`==SsBWw)PBNcJrN*|!{G9|t374g(U-pnE()?qvgoGw5Eq{gClkm_J_Z2d9aR zpmjYS>I`O&*d4*=X`+@DS`)$Z<%^+t3^rZ?I`?NjY98Cv$S?(bwlFA+13&^ZX8JO&=m(1DI;Xit0z9?#H*j%R3r&vgKeXMoFRl<^Fsi49BsPY11! zM{hrY(&0mAx1WzdW!z%jiC;kD7@)ffKy8?I=AZw&LE{+G6CX@Rb$1KM-P56EGwA#Q zkh?+S1E8`2G(G@wH)wnS}~A1WJy+9azUDQiuPbN)a5!DMK-!|p3xEIIK(KdSpfK<)>f zUkeI%P+uJ6eo$W=#`8%6=${Bv5lx_LYd|wRC_mI6f*vd9(_Mb20*)hwuVuzm(q}_i$ly^rd+ZKV` z1v(P~RJNrMI*I>HW=vaOuqC%kOScKG=~+5P83b$67qtrcWvI;5<5 z!OXA)eBK<${&=YU$w>BNE8B$Gf4&e$*bgt;k{y0N5O)9hP~07*Y|8}M7Z0%yqiic@ z_z5rD%8|-8(7E8{AU%+|Z_t=F69a?DkAMHgAG4$O3qfsA@P21yt%-)9ImT#ce$!|E z`QI2iCK8UC-zq@mEok2bD8GTmL_qlsG$sPdZ=f*|P<{iAiGcDO`1}VQ$Qi4k{02V% zK^t<$Dk#5!#;o+AChBQIH=%=K`Sl;h{F@yndv%G_&@^X*vv3K;w>Jw_j)a z`TsWP4ojpvA)#)U0J$A}hMeKVm!P{KL2d`#1qpIH=nMr=_=C<+0J$A>h61R(1D#n4 z3jfofee&89U!Diu!KXFx=O8n(DXlw)$ z{#p}1IYRc!gWbQH>F59TpgR|l?udlC{{<*bgU^;TocI!SwkOE_pmPpD?gyQ70CGR* zoCA>iL3c%h+z&d}6y$!;xu&4<8gxbjDE)x$i(CzLKghn-PCp;6hq!+m$o-%__Gn>` zT;DuU)|&Y6unxE_ea`Ry^as|^^k2{P^M5nw%u*r5osm%Y?*O?UvfCY_e0Msc#tfJxI+@^{tl4)!ROH#PJ9VEBLL)n&=~TXB>dj5AqoY%tjN#K<)?a zS4VUI3uZ{$7}W0K;9)RBX}28KnRv_-baounAL>j$|7(Np2|>DB66%jIkUzj@))`I& zt%n7VReE{b| zXgq-IQ+N9LP#Y2tDj9f8hL1jWN`&{=5u6JLVva0Iy@bWQ-s{m()Bd37ef1f3HAiU-j8TTncJ z&Wr@P|2yN)7rz-H`50v1Z^xex|AWp*Gn)8iA$05+&HeL0_j;k1LyL7MmS{6fc_0l9 zf7qRlptBc2`~8sm#NX-|rhx9@0go4g&t5bD-%SD@F9hx32e}`#9uwq#&>ntJJ^Y?|5W3ns@}{e$akxH1~tXI8nkM)F(cyGx350Xsry? z{jhTxA9Ew_q=bh5F_8N~=d**tA9P_PdU9ds6*-bB#dAumDh2d!rWxgT_1 zBgp-rwUHqAgU$v3xgUC7BiQ{Y=QSEloC0z`=#ENs_ZvI@L~*~f0eqj)UyvSdhM%B& zG5%MB&Q|1__<$X?9-anrKWLvI$o-&w@F4et_Q8YP584M03V+ZVK9Kv9q3I_bv>#l1 z;!DsTevtb?d-y@_hpsgQyB}m&~BNpfN1a8NRTy z_PAMoz5tDR9F_y0rw1FCkF8^v@__x2?SuD?whtc5!q16*=#O;P-fD)Qk#!7H9{M}( zd<5zXGRsbUu$kd!2(p;64ETI(e`GOd>4~5_guIZ&lBFg-*w66O6Coo?Z=FuMNGk^flAZ|L;L}zKBhH0J>8Ulpmq@gbIPu!(xY@FCT->Y6aEv zvf%ptrLxS#m!PwqoTVXmTqjFG+C0sYkaO4dq5wacKZ2fK||1DriLJea_Ai!lO2A7?neXd;{e?a1lk)5I-?rYuYS?a@bhIi z!%t3zhnGNOA55V2l=|-Aq4U?1$d93^ISe)6a*8A>laz6rRnP;R$vx z=-dZn_db@L7yxo_HPpS(v!Wh67M=)N-vOGt;()q$63D&f(D(8{=nQp`d%^82 z>4`7F?JOzCc~T(vg4hI zGQZsE=fi499Lj^j1bi+WYMwxGue0>ThsjbCA2mx(e9SC6@zf7U-=qPwzZlj&TP%n; z#~SKp1(2ITeG`zILG3Y+n?da{kefm6F_4=LG3Y+n?da{kei|HF>pL0x5p04 zP5d+;WItv+g8HzaFbAEdh@4j*g33~6##I|YVeJhKYkj7l|BXTY5&^{7)=+nUs$rM{ zx$ ztdD@)4L&~%HLS6@^^vpm#0z$ieh4_6q31z8NajbJaSe6vF_3#f{SZ(%zX#o`EDJe< z8{}Tl-YAfJL1#vR+zUE03glkUnNcA3LeGo>hcoh-QHSLw&H%X=)bD6Ub?>8i)UpVa zHb85MBS7H`yQ}^=EPjJxaYK<)?iFF@`GwF^P+2ek`9?gyQ{1ad#9T?leNs9gwhKd4;@ za{p|`pP>CVVE2Q}pYQnd;bKU53xM1Y>QA7%KivUb_TkEh=Rk9d%FuiWJ)h~pW27^( zq2Vq7ayO`70dhB}{ReV4sQm|WH>mvwayO{`2XZ&4{ReV4=nN;2yP;<|f!&RKhSOoW ziI3(%`w?jFMouTNG6R$k-`PUWa02H;=v`_LKxZbw`Vmm~KB4c zg3eF^xfirA1LR)No)M6HL1%u0+#3wqUjj|n(TqPIgggFx7!3*MZ6No8`VDCAebEl8 zj~G6J`k(N%QtHsPQlRsFK<9#}gX%JepD)4pQ%hTFFfnX-aNXf2$bXLx%S}|V_&@#S zWrv+Ft~=~RS(BuUv?fWJVdqQGdS_+mnxxwfKRwtOwmj~3K&jUrf!dv)+d$_Zf!qc<{|MwZ(E5Fl+n7Q9EXj$W{R=NaZsUgB>jicj z^1WV%Uf3ey`U1a`Y)rp$b3{zf#_8Q-J`uV?}_2>U))}JpAYft=N z&HD3IHS5op^{kM&&}P=3uj*ZYzHD{{&4oht&!<^s=!g3d(5u9vBPfAepsfTucov9d^wvHyl3L^Z>OIR&pZ8m0BX-G zYfqe83A)48=_klO@Scg+koAY4wX6p~^PwO<^c?v!EYP_+cITfjjx+r%0PWd%?etSa zkzwMC-Jr7(9Dcss&jgtpJ(5uqS%1D*&5AjH zaMsf!k*o?(3+ns(sSnvAt;bvEqd4+tK zTQ(!yvH<25XxM0?yJa;rT-GDG#UJXHVAh|n{9S*(2zLGX3Up4-Vk~Z1@AUJ*eAl0# zwWP@NsXj2btVXzngAp1}%#e5j&pSZbpf#8;pyBo6IOv=prk@y=L=Sb ztuK~4{p?_1*a}{^xfpUr0%#8V#bTzPFBUufe6gA3=l|_2KVNKi`T1ft)6W;%U4Fip z&-C;EYL=h>*F)DTp`Ec3R>d&o1?b+V-%dYYI%`gR30kj|tTFK=XuVRi`ox!@^-7D? zCcXr%S30aZ@#S)spD$KJ_g8_;Txf&2nmlLYb$ zXiXBxFU>4JU$jI00y4AR<>$k0m!Ci9{Ga}y+v(@Sey5-4etGiS>E|PN*Po9;{%BSQ zk2Qhz(=7#!Z#F~y(d_i|e>Tg{7x^qdUu3)dd;uDt&Ub-~Q8P3If&BqnqXar%r5x2C zA3=G)9LXP`bx0t8fYu>_{1MLb^Cie1pmj(fe?ZqEf!CQMtwTBv@<+AP&xfEhR?y-E z#UG2+;QlBE`J))>56~GV?kqoFc!SP5aRHwR{KDG>e8&_h{=ojQXZiWxndRpLXT^yR z(oy}fALNg8B!7U`Ac6b=T7v}g2k49ykUz{p`|wpKzO-if`NAF=A0RXBU4A}vcKJCK z^cbP=6#l{rs=Y^7Dl{Xg|Np&ljM(devRP=gGkRA~R zWrc|k!cqOv3-Sl(%wbr%VrTjJ666nV(3>i7!Ft2!Q+nT9XBe4{?^CFQlRV0GSEB zFDx1459s~C=>EXSBgq=zI05Ameo!6>hWaJg>F59d%s*c+gU-Zq{`tZiv^Ln~C+Hj( zxL>|A|NQ?Ov`#^O;sbY7zeIuj0y?J!<`>X@8jxR}Gyi-EiWAU!ERbJ7>#;z7`3$Px zp=*ypW`1}6`S7>%PXmx&yq$hN^vBF2Aa{Vrw4nD_f$M5}Q2FBY6Es)y!WeRf+W*U} zKmT86{rS>aZ{q*ctUv#sXZ`s)S!3es)2u&VooD^|@-p-soa?MVUtMdzPIbK4|O*)CLCc$+AZ}3r8AK&V#}fbe0SF{1ni+EueY~ zq>hil3>3bgwixLA8_;`|&_$wt&u3v3L6kIv)mfh79Oj zm=}<9UnYXikAb&~K=*H3!`Fym4^PmT04O}!nSQ{GPZdzu zf!YJ#8GkB**uTO1)IPrW%=q)gXV94rj6XF%=i$6}{0TN6e12ut571dFFNL9d=w2h) z^W5?0%hwQlz1=@qljTD!!p?TvyD`YS0V`$!Z4$B+-6JLL4h3sYh z&HD2d=zJ*9Sx&-kKS6V5p!>%_=fk{!oc}WM#chaR!Fl7hx@5N ziL?EDDUB4D*ByU8xa|1zk+c59CuIy%UVzMd3^^|WoHzJgf4(@)2);y|7<#S`*OOIH0v7 zxuErhzny+AW^nkqgave_rsl+lNM(G`Y|wojjF5KFX2+lZq3c6m+y>pP$@ufdednJq z)BM2krTjo%mombPob_Z^=VY9$D^)Xa|AUsA^1n30|YBJ`r?(C%F9p zUZbiy@#T5upD!*$%XpBPmz{q;yzcyS`z+A;gN{ERu6M-R4tk;Q^b<5+02-rdVsQA` z%mV7)YD@%;$E9b3*4IJ(v)B>5KM{1N(u?iRKVM8|{P|+H^UoKvk^Hls`RD)5pmn!0 z6CX@Q_0L+6eBuvjR>#-5h@%C%>p>{0TY_5FY1?)h0eXtU57a=Ktvr>Y-s%@A&gS zbYJ6($<9AtfaVaVJO2coSpq8a!Ep_}lj*@?>4^{WQNtz;6gK%tVFOxI2nrj}nnF<6 zfYua(>T~ekO4W(5yPCjlMWnl$Y(QaC?D+FxIcC^^{08?!v--q`&YBY+EmoTt?Dl{9 zgKVfjvK@c^&xhQv^djH+=Zj>hop=ASRpp>Yf{Gu`>;!))iDTp)iWL+++SZ)3sB)_As` zptIwU+a0e!ZH{L3iQsleJhW_0X8ZXn-tFhhWTdjy8(L5LL(gVf46P@Z!|F-CiLb+< zXEQ~!{d@&FpAK|xT(;ZKm!NZ8Ky%9Bjz3>SgUgSJ;4@tqq3aDn=end5C|f~ecc8M> zpYi7_&{=fFNM)h;tYEoe<|PI3u0U%^82b z0F8B;gU%y^h9~F@8CZB4gUWvb;Rzbg1BEB(jF#hUKVL%Eri0rZ`i?&zXoKeOO($A{ z!V_d3X#d>*|Ki}f>a)vF(3vTqvv6OkL&^hi9ir^`6SNlt-=VI+G%d!~fJ<<09(&^Q68PLxNgtK^||l{ms4 zcwGg$4-j;Ii#;Q1yQ7=!=l_1xxCFN$L3snz?&yZbWk1``SKV$uU-l#AjdEyQRzu_R zH#Bejhvg0aiLaZXaoNuH^VMXwpD#gYmrZvApS=P)cjYC!Aa}sy@;w8h4f&n{(uVvDUI+j2#cPJ2pgR#? zJZFHkAwlPrfX3=zZOHo!KVN=#ft;)O7&3ngwgxDY)}ODHGc8{^XIQ>=*06k~tclpO ze463si|;Ow^Fly-X!k?+&>n{FSw0TkvwR-pmWCkE{YX1X8K%774LSqd;pf}K4nN-< zcli1Gw8PI==N-Uqdr|H9^Sv-D#(rg(TZ2LFtakkQ!khW$e}CqmFT9<9g3cy+;qUwt zwD;o$v%D6#zH~;~gT5X*<_~Qf%>w0P&^>Ih{x4`BI;frj?L!CEm!P%pp!yQD_8rug zz_Aa#U4iSFo_uX8rk^ISUb%%vy-B1l@}c3d`vX zkp17YplKOL+i)Y(DHme?@q89(AkBzq4nc^wx6#+XZwN9+n9T6=CFl&3 z$>4N8@kKWzkATYn(0L}WA?3LzY_Ab|82~!x1XKpJGyHr7I>+xjQW?-HrmiLZK9!P+Qjog!;^pF zYh&n{HsCWF=s zfzDWF`1uNSR*pYpe*?IFOn3PCAQ`mB!E$0DC_F*t6+^-k)ZPG>si6BKK;=q2#9nZj z1Uf$hydEE^UmlKBriMey)M#)T`1m52;pdBBho3L}p=B!QehK6<)t%udyk8EwQ-TrN z{|Bw__J+(!!0X3wq%t)eTBbtpMgZ9ZFH^%Ae!d8I_z8+rlzurs`_KQvsBwwXFXxBG zr7-)?SN!fjUkW3|X&OXK>FpNb1GnAtnKjgr9LE#;q{|BQe3J-<5C;!=8rFw8GgP{2HjZ!jZ4rR zJ7_LX7}_rvXF&AJLFX^P>=AeP`BEBU4?Hf_k>XMv8kh12d*E@Y&hQg-R|hCAUzCIH z)?(NSst;cXL-OzoP`^!>;pYp`JsIlEKmUXFQ>Z)t1l^DGLfiT03w{RBd>Eu|K|bdK zHfIa1TbM!Z3U&uXzZ0;pfZa4nIM6 zV7*9p-1&4nsGAB4Wi;c@7x9ojBB;;!Al~uk!(>pKn`h#5P&k0@4n8b|GN1Hfx5H0HR)&vHn0Y2X zYIgkjxZUyR17+@sRSFDKKyt9PjVqZMLO^#)KV{~b2y@dzke`?tS1oY@jcq{P70mea zKd5h(%r)^pXiWsjUH*(eL47lD`5w;r^FgrV&xhd8W=GBAid-tF)c zWal$xo{3MI9e+M;cl-&nv--yW=?|7e?R01S`QMxI=L=@8iT|A$f4&6S3F>FLL&L(G z@#h0~$Da>D{W)fyi6J06mt)!q@-HJR!^DTP8GeGox6pU7cis=zP>wDuDePfzDN z`~=-&09qRZ3lGp(jpYQ;SPj%&)}Zq(7=ON4%sCNsFBaHc(0&#;EbJM7KCpKD`OqE` z7J49eEyi@$ya||#8^wn{ztG~&^y&%Jm#1Px@QaQH&8!F z85-s&_oDMm{5}<=7t^j6haJFY0fFY?Ux?3_%HU!!Lr!C$vzo#ABa2td?*d^^Hq>L`Z3+{ za5m^H0n|JYCeJYCK{qrmxfy?g)|k9d=9u`O9h%128GnNMSzvqk8Gk;c^!jwNi5oBW^tpdD)0e}=XZk`e7hHLC=^3+r`ZI^TB_IpAVTK zb}aze)sAV`D^Q;R6ut}%lm0{RTYTBfH}U^v#-IPMGyZ&inepc<(E7aFjF59N?=${< z1wGFk+`e?=p7?q{BjhZ{!;Fw~F}s-|Ydrdyp=~C&O?IP&x z^?HV%FFapX`SD-c*XilIU z)COhz`SLp>c#X$H&>h#spmQ;KCq8E8nW$0-Iqwc+A83sSs5}LwEv|zOmR_t3g|Ect zOTD_!03N47nIF23)DF#t)M4N-&Sv=e0@MaeXZZOB)DFGxu=50{9eUW|=WEb8kDxGh zX8QRbwB9vYU?S*_&;PE}y#Cqz3`p9vDC#!Qeo zg=`i`nC7!U!<2vGYilORoPs^m&sU(ewEj##U-~=2?+<$!@9-0JZx}dCqmjZCwC2#; z34GQl&M*btGX@INaL}D&Og~?SGeN>M+~MbgV27WNk_EwGdcJ^R3V01;GPLaiy0;zV zchFsG-q7}oKg4cuTNHF28L0io2yKgk&hT_+_^ApBzn?GM8Gb5(*r0YK==?BeP&>@w z=L>s=pB|t&BGB4bm>sY_zBy7G2HHjg+XY&8YK_!}f!YP0C%O+hUlQ7ev4^%{oEd&T zh0PPWGyDXt3kI$EE(OgKA?Fiurl0>oYlE@HsW=lPpGY(Pd?oJm^QAOWoc@O9lmCp6 zIAw;$DLYb}vP0vPo9X8((7I#Lyr(i~9+%TpD#gi3c7m@w1!z58mH=@eZvkvA06fg$7vKOPC@1wL*o>*9|TlJfZ|jd8mICQ zyTRcs?eOy@s2zwLr{YL)Dh`cPP;kRP<3@{9 zacH{~6sO|QIOPY2(MM356CS7H3_n48zd&&cTE7pQFIvIOUxb=cQU#Tl=`4`;X?}z4gU77!_45y>Gr;dVQ!Hed^1$8U=ZonMJD>PF z{CsrV;pgM~pu6lCgm#1GUV@?Fx1HhV|J|VSo^|4X&>6RnStq{S%m5xs0+*+|8Gb(4 z?(p*=s7-g6ZQ|$2u(khODD6?u{_2N^*(PRy)JPC_{J)&x=Sz_Nps^s(-Fl!fU(fLK!D@$} z4?*KqhuJ1x2H9^9>Jy;a4_On>Hu3Roho4XGgZAsNg6H5~+e7x^g4-PP8Gil;-3xh` zW#a$YP`hSB?$rbPbuq)w2lE|%K3ojScWe`Pfb6oywCiCwX#G9HE^s^RG3&%5M*pWj z0No!A^4DaBpZ}+W(k08p|NT(AKxflVhQvMStlI~Z9ezHX4zX)4$S&~x(5U`;747iz zb+`jKjey#S;P$99q@DO*pYi8wZN{Ik^cjD?G={bX%o%^aGIsp=(%cbLZ$Zw75Qmm= z($F%_nh8>G*)xIatqb7!1!YD^y`>I1r=9WVOVB!LchGzw5oMgSBdp%K06zQ18rl}H zXZ-of+VSTrP#Fh0M-NoSf#z=fp=|+J8Ml~Y;^V_?6BYA8>qJ0hDYT3O)rla#6I;gR zgZlr_GOifH2G?8o$~c%Eq?U0|yTJ7p)GqM)20UdPXe}eCtqhtA2lbO4MLYb&mX-?5 zKxGs(f3`FH{ND}gd$UaZ4{DQv@<%hnPtYDVaGLFA`1zpS;pf9{NIK#Mr6Xp{G%NG} zzxe-ZhM)gIZM((H6aSY((>Nj&;Rooe!g7HG7*&iUrlEKpXUrdmuWs|PQu~m%lQtF zw8bIuAoJWIY4ZiBEd*M7 z%m`WkuffP*_Wv-mB`AC!K*R8Fb;Qa)`Qa=7JF`tZz#M-KrU%q!0L_^@GD6QEZDzIv z#m9qUho7MKF@`=!+v4L|E{2eYpgT{!9e(nG)=KC@;_W3fhZd+$3%*wtl-EFGJ>Yv> z9e%!2cKG=kdf(~`afY9-r5S#{g0>U5*cn2efZ7S(4&Zgtnyd~#UkWq)1l>{O!N_od z1GLvNo8jjP@Lk6YKObZ}{Ct@2@beIVW6)#9hM=Pv|E9l^b^wnVf!i9DSwA=!IlD9% z8MgjsX14sF&Hx@8eVFd>6T?p+d*vN|YW}Rh%*F6;k`^P^>zCXN;Blstpm{uL2k`oJ zP&*kW{sOd50n{#GX7~v@w-j{G@+)>wK8M6TxSWCd{ow!q;^6#on91^gJi||L{S=Ss z4zQYLCd>cf4B$32C_kdR^?x(##XtEXEB{uDt^}Ry@X#J~mo7BDH#7YF586-qn0X>7 z?qAh2{CwHW0Cqd*Y@Juov&Fp`87^dl(t9>Ez2`Ih%ob`4di|IIlHQ*)K+-#-=)~9M z3_r6$>Aji(ybtyzC=X3{`1#V9;pYobdNp?V3A(!%6gDrQN8`1wHH;pZb~=85}q8K%4dnP(17 z@7AF99S9?(cZ@g=UHK>H&>+qNI0>I6>2=435u_yc`T6ptarLyP%=> z1HS}~$x1u?d?oMj^A%`JQW)Cy6=wk7+t9_r5b^|cCapD6nr25!)4|X*jTGlfB9JsK z07}y!{h)Nk?*N{o1f@?+My}VOvCu|P+Juzx6G41XntTCDkDzmGg(3Hoyo9>-DyZKA zO0VJ$KfM?lf;4$g%>tE8p!HDTyTY8AEdTp6{Cwc;@Dr4;|5l@h!+&Nb%m3~SKOZY#nfO8;a)0teb%vjhv>ARr)@S(n#F*jdLr{7F?VkgUQ$yQ!513gd zJ^+OoblkHaRKCeO{A7?kV9UVRVEaIsc_QdecF?}yhw6xSWp^IKln49{pt0ngPsAO5 zK5BOO`M4d@u2cn$b4o+&t$2o?|C2%Y8!%1$51Ri_W}f&m8g%9`q|ADe%<%I;JZP;H zq70h0cJ9mQY<%ZfD%W_ldGjhIu#mo=_ax+K{wC4w0mocN|dtqq47YE%D?(p-WxWmsya*aWU85@Fx z(*I3=3Ci=#koE#6!@o(Oyb3yZ5#1dx*umu!IRD@M|6g2zp&Y+Rya!*<_}l&p~@praS!v?fZDy@AUJfu=39r;>tfC z2s=z#hL zCx;Bf$F-ocs@&-($3%vYy3l<$;QNU3q4!~eoF4qB- z6NSmeiooT->*(^Ce)7TORLwu0Wq|DSIRVuNY8!*jtOW1J%ZIGz=3s0HdXdlc^9AUh z!)(wRet9j>K1xuT{~{ft26R6Yi2VX|mlkNx0<-xbPHell<}Y z?vH&D%ml9MH5DOc`zlcV6YTU8be2MA4ae*kpm<{B>;~;k@POU>c%BW?rn=1b^TB!O zIh0zBLCnkzK^zJVK~I@EwDQvaO$Ut|{y)z4^Z#kKpD&orCjJMXN6Pl|#c?*U+g_Yz z`}yFw+s}um5pL(6@PGOXko}T3R)uy${$=j3?WZIcVMzN1flrXmQvBqy7JPUWA4)w!o zwx17{yZwB)+U=(kTAVS0;!NG?=l}U^KmRXg`}yLq$;AJlHCVIRe!iFwb=zXLpAY7{ z{d~9>;kJ1ow}I>j#hE_S&l{jPGk5y=A4{Bp?;8cF^Je-v3#9I`@x%wxko_$W?OEXC zKMQj}XD>PZd|~gh6Fr}R@`x2EJe8S#9^hoy^1qzz=l^Q9pD&t?C;kWB!TZ>F;>%*T zpD)UxZU&uwU+(tvVKu_dh5i4hgY#B4+t2^`Y(HNp8&3q^L!8d`^F=mPUq0K<2ia~v zALb+UC4>A5iU-hn4xo4t2dzhk>^lL+18DCAdRpQ~iidb;JS4OId=T&U^I%7vWI1MYH{U5bpN#VKl;RHXyfw><5LfI5ZxV zal}Kn)6WcUhOH0VG1KgW$Ho(7L1%GuL&Mjb?dN}gP#76a{13Vx7ZkqkY(HOkL*3%f z_VaHI$n?Bpm2ik5wAL=9g^rY|q^cNueLE*~|4PR~?;rsvp1r9^$ ziJ(0#Q49WFwx17#-F`k4N9fxK@(U=OLFcA{ z!Wp_}22>`3(=lkD3wkacJ6JNe({rTcE)NS8ce?Iu^`t#v;S9sl;3=8k)tUv$12JI!*pZFiNckD6i&lk_3 z`d+jCeDK`$=fl?seW4&ffx;Vf4hbl{?}OHOLe>F;!~3=)W}SN-DZFp9Lh9W6tUn*z zcK!MAzAHxgJrNY%*ByVt_T;@t)|&|0kN5IC>(3XLp>Dg*`t!kM*PjosBiyD3avR8g zPmhWB&q;r+xNOa42LSa;(8-Oza2&HD4jeyE=gv;KUr-}UFi!w5h9 z?1kow&8$EFZ)g4aB3XCh|MjdtUqbhzgWFEqS${s*?E3TJc7(pyz0i6Vbgm32o=$`A zU`C23(0$D4`Qk8=|CdAkznT@k*B-r|RR_h>VaK2U=d=F&5897@SZCt@*^qMtUd)I3 zX)!B&Pdcn!cLd}%ko}-|It`7d%h==T1+)CB7oal+ok9Eh9e=)n?vLt{W(WbrA-pZO zobl(2$uKuF{(Lc=_2+}hu0J16cl~+DxH0HaJo8TExO=*p@#pvCf74$s2i*_s`14V` z^G=X?Pd7XMeA&(V^F=@F&j;PEKOgqH{#?x55cDSb-}Hy)9WmNPpuUuU-2dqhwnO8% znf2%YcGjOS9&1kood@v}RL9h_{(R944Ucx#pAVW{e?DwS#8m?}npg3gV2(X2i3 ze=+ONm&L3sbgG%QY>S%3ZqogwmAb0X-jotO3?bD;X%LFbCN{(R_;(8mk%Hz-a(=LdoE-DJm~ zp#56#I04;-jh^qik>bQ0>VIq2pAXDke?GLvj1x~#oOC<>{IAdY^S?33J(?5$YqS0Y z-Qn{>AL=$^)}IgbU4K3_M!4-+&;RK!K=y;;WHK~Prelwj7rUYR9`-Z-R0NHmfyzse zKG1ndAb)|@DKN8bjF`Al%amiX8id= zo%QDfW!Ik%)m?uknKlMJy3d4~Pm39U@+SYA{-)XS=j(XKpRbY~f4)q2{P`l=@#mxa zPCK6#JN|58W%$@#!#&%Jk-Pg9=pJ!t)}JrrS${r|cK!KK-u0(5b3@Rdq<_;NlsiJs zz{FBsAGUz(g9Eq2q4yTONYddoN%-Le8BGd^C34PP8vaR0!lBSHHe^a1>JQW4hdIqeHxA>4+n$8a{{X3gkAB{h)Y{hNc(L9ziVqAyE8#Ffu^g^c?CYq&ttAOi}aj z3|M>+%ESK9Jba(!=YP?usFHQ z^7H?7kiXR?{s-ONbe`qsi_1`b*I9l(xa{)t;dO*Q8IZq0aRQnn1;q*It_gRfIB~}k zC(cN5avbXa(=0z99C!Ko@HA$eM1bPN*%5qi)BnRPKVKYHo%nw@%g>j)S$@9Q4|UsN zmY)yyyZn537~!_B-Jp6Mnm4_napI374>v>AwKM({2K7;^G5biMb_%E;Y6_ZTw1cR+!{dOheY7pS|ov;2Ip+2!ZM?Fe_B?}n!To9A_pP)O};pHXhzI62R(ikbMXG6n!KFiMs zvt52ZoR1mSe-r;re`yTb+sg9u|8!6~P?`9@pXKLE==m<-Hq>;MpAROx{Cqea;kH>I zw}I>jrGIN^SleR{>zB<=pmDENT8xnSGSI%J*UTKNUQ09n1k>`2KVK;`{(QyEu?lpL zI_SPP(7Mvs(vCmh$b;tQA^Y@RXgmIVtMB;pEok2uGvm)U?2JEOgYE!lW%&4tpYi8Q z&>Br=oYtJw*>w)O!tht`AN42U_!@9=S0 zNIq?ch8@y*GfkF_L7?+nH-N(IyTi{{puK6o9l-N1AV0y}09qgV;y-Ba$MNS&VaK1Z z#T|dX2Cdb3&hYcqYlfd%f2%KhF*;0o^_~GdxA^ii!%q$-hOIB2JN!Jscw;+AFX+6{ zSDzhzzJBfS^9{S>&$rx;Ki^6-{(K|P`13U=tU%|SLD%1I1Jyy0yTLym6lVwlnbRSD zV>{^lPV{jVP@C*k^#AFgJD)mP5)^Fgu8&xhp*eY~JF11dXiGeE|- zKEX!)(m->(BD@MKIJY;VeHN1iSov7>;nu;Vx)- z;m-2&Kj=&!W~GUsvwL1Tv;2JF4%O$)^7Dba%g=}22z^^YegK8~%zRp%HPKlT{*&hld9Sp`~0q0Pws`qg%ZpP;=E zpu3Y44Ip#5FV-{s1dThtSnu%j1!ylHBj@WZF@_La`AH0vpO!=8TbE820_KiV@k>-Bh$N!rS$`7D9ZuBw`RL5*Hh3q*1*D=SLfBpyEr_L-l@jvKn6HuHT zX8!r&IMjcqnSVYw?)>xNX@vipU~#sa`RD)rpm33$2)aA{<#y(upz}$GTR z%s>CH2A%OGJMlmGY!l|6FP207w3_+ngXPXYAFf8Y%@^c0ko};zsE5WGXm16!I3uQx zDTd~W*~~xx&j*E(%*6koyVpSBJDvIGi`h`O%xC`jV7Bwmhw~9`(Sn6hzI5iF50agKK1@gGTLcPAP(1rX;~BJ<7rJK`9M7P&h3I_`ccgd@hsJX>^Unw2 z&OaYUW5)BnxPQ}Mx;uc+2>2fi@|V=a|De0-yqSN#@Q1oBnEB@ef9IbMgAs142DuGn zKPVshL*p5A?-aTD$Qc^G(DMjhJeHjJA9R-VFK5OQm56qo^KD0*Y^8)z+6u$P*@CB{ggziBBhc9Sd z8hZGeGyK#5-Iobk^Qa9CUw!7E544?sKGeqy-!@SAg4Sy*GynXr4vKq;iT~x9f4-Dw z{`o=~>Na)epAVFse?C-4xJ?=4Hjw?G@U@4AFX)VSEa3~Drv~l+{#kz+yk?YE@h-J{|~*>gPHl~ga1xHA2MTxxh5#gl^uTm|IYOD|8J(BFPgIqZC?p9Rs-yWIrg(wV`3IkGu<*Ul^z;8?rk^hki%kUG&-U^*)6W<8p?-MG^z*@er=JfW zJHgvoQ$cID#ubjz}K0vgVvexTzsI<^z)%H)6YldOg|rk z&f2tR`uWruysm213wMZ};ISER$l0TyHAxRa^IM>ENv%O^&p3X*5a;;$fZ2W`Y|R;G z3d58K+(&F5d~UXVplk;@%iJHa&g79c(@(Y(&|OL{J0EE~{e0kTJCO;QpKLSnUow(> zv-QMZ$o$1t6Tczz4_i+Bgv@_zG4UNTpV?yKt7L{LFU---0tfNIYXKqalQ~!!%wTt^ zJ~(VP@qsdAjSL4z1Na=Cn;-JNKVK%>Onmv6?dQv8>xnNx z=f5nrn)niQKFeXti7!ECv^=($_!4xc3bVz;m*3fbzWB}d6TFV?Kikg-zukU5{O|Vj z5wrcom2Lm0gVxi5!uvlvXzdjb%G#^{m)U-T)}lRVHifU>fw^rH$ZgV2KVO2}2EOOo zcH+zJP`8237z4QtbOsp6ZQwOwmJ?rs&g}xZ?KIoZmms%6?>+{*?K<1f2bbM`KD_Ss z^9i&4#7B?ae?ETh{?i?_j#QrM=L66^GOO8sg4R(za5kCvKpZu!`atdh?VAL-ryCkp zp!2anVFfzB3gjNp8CD?ofYv*K!fHNf{e{KEmy4n9S z71#EE`U82VpV-3bkvZi4mZ!}26CXcz|M}#(`%h3h6fXze%?5RQGuzMq?QB0EFdI*N zz>n(oc#zxqp<$T}bvx)hI*{8zXVQV(p3nC4CCKfdwND_omqXoN4Rt%{{?%rv+d=j; zyZwCF4sp9a$nC<|-Tu(r=_iW2oo(Ug8BYi4eyEeUSUv zq3#ErH|uOW@g?ZYS&;idXT*Zs4_Z?Ma=$m|zH-ZnFa4qJ2d#MmrG;>|pD&`J?g!Zu z?e_CwJjDI~TS4b+V0ZtE3NqhW!A@A|?l`_ZA7wR0~_Bv?%1b$cTf6$o~9zP$dd;C1q))1u3 z)DQ%^YkXfK!xYf^6Y#oYMu$(JJyYQI^6V@-U$DFEe8I_J_F^@X+uk!n+~#Zxaoc+L zpD*7--S(M)+q5};zR<_ww$Gq*?>v4!)JJvObdcNLgZd$$y%0!ld(XV{#e3(S;Bv>9 z?I-9A;s?zJ6Cb>Wp797RcXlT+OnLFz5t6q-=gorR6LdZ-C_X`JmO$|-4^5BC(D($c ztpeq3ZD@MbXZ!iW7#g4Eh;>?^a;Li$f4PH_9+Pb*K2)}Yr^!#CwD6n}QXX)#{ru0* z_Va^N1k6C~If6n^z z0khu32e(n(9|dwh=)43_d3G4;{^P8Wvi~&H{h+hAL3!#j=w1!Wi7!ECbc5mmbcQy_ z{r5p@5?CQ+KggcPu0J0>cLkUIT3~lzcRzCZ`(UvZIP5|5V8z}4r$4w3b^C7Cpa1u> z{(Nv)XX1m)sBYH=x&1OU>_KZ@K_DQ+|FzPce@M7?dPFxpUnF6KWGh1v-ZRXr%~Ph2b6a}XBdOR z9kk8_{Y{pZX5(DLFif%3wbEtt#u1j`NMV@{4a>z=kg$w)|M_w?G%P`9HG}pMI&x2ZfvsM!=J@%-9!prR zcl`Ol+T-U#d(^PB0EOjhEM;#x^UfFP&O13|8Hzx4g$FBx`3q|#H~K@}c-Ru+Mtk?4 zFXuzuxELJYkh|ouxzU;9=L>f%Zd~m6^MSL+&xh`)ZsZ5K5w!jYJ-+>!cfRmPxbX!y z=)4?6o95wSD@Yn}ww-9C47x{z5mF9A*8x3X)|?1hSA?7fG(c%!ItPP7PkhjiS{D2Sg;PJ&?Y~)mz67P;|DZc1Y$m=0tzQATogM0SZm8SA zYho-Wz7&SKU7Ypj3u$Qj1=#~#cLPelCqZtXjNR?TI0;%&JgYNRMocQuN%g>jf{Pr3&r(-ekC3M{j zIINM^y)fHPoC|UfX~VKSAqC9yqH`1f8XgoHiDM+*=QI z?`o)fL2D{N?TpQ!J3Fi=zT6IVFKGP-sE*zbb?;%QdyljHd~uouQpcTV`T5|q%g=}B zUBGo*A;`VW*u!@z=-lvPr2O}t3DQ1mwua=ta`&Gvi=p|ioIw8b=J@%-A4~o#2c7fm z@$;cSYW~xYXPEM$7)u%PooVNb?@o~Nw%HnzUYYGDI)cJ89~z#ES$_Us&hqmCv&ux! zncm3Z=?ex0JRw=L*pNGj}R#SXG6ntKFiM+i=p8OvS+c& z&xgw);VBCW&wT9R`9dBkEYCy3^05UZES24VzKn;4Wio-V4CeUxA{G zJN|qS?eX(rJgOTvgWMR5#f{sUcD~q-a3e-}``7}K2ApjtUQ_%({eeF;4OFxI{9n)V z^TA=Ii4VL{%YZYWwB-#=1E6&epfW2Sng)`gX&@b%r?R1G0JL@klm?2SX#ljQqZ*n9 zK=xF-{CrpsNdt45K<>bv22jddW~keh?ItbQS9dzdqs64QSy4@b?c4w&D-J#`yH`MLWwH4s<3wdn?v;D+eklWp{yZs?7teNd6 zrfUD6{s44-9%#%#o8>2HeZvE1g^3TWQQcbza<4Viy`VdWK<)+IF$8ii=#C*!c?+7y z2jw?usC(t1?p21m7j)N=HZ-jDS$;mycKP{G9}?D%AoqgSRADP`Vd2YcKhYB8UeMi! zAont}famHTFw0MTV2tWsSCD%_=dOU-W1#zlK<)+ICj@dY=sqEkdqMXJf!zBUbbi0( z#FyYXc8iHGe=|ec<EJq=fS^d_W++2qX|2YLz)9}9tU*1;FUb%&zJHZKVO2@VfAzTd^wrp z=L-ggtq+wQe?E|R{P~C-v`3S9;$u)<7|Sr_g*wPC#-EQt>$H?>En(*ozA$In`9itY z@}+YP;%t9&C&bys;z(!vi-XP`bo>cAZwY*MF-RRBgBdtX?{ob8{}>vkj;s^^ujcsq ze?2rTS3|>gJ;%?N_n~3>nB(WG`yM}EK1K@D)6g(I&jC4OY_T9DOqUBn!<2vG>+2kl z^LK7@{CxGC(4-L~|_n)9Mv|jdu#(N<1IpFifzB~MU`5QC_ z0zEShv_JGS!%t<<9$*&G+rQWijmzB*KVM9S#wF+s zopNYgg3i^2on5@y;pfZk5IewU7lY#RF!YQ#P+T5{o)NbjnqKxZ{DjBlVbD1ekhpvS zy6b_JVdDcqh7goG5!Q!pww|b{@_+gR(79otG8?+~=fPpwi4Rso&%uX|#oYj<_0nk=GJ2+fQ84 z0CERteHZ5VKZ@I7eZR*R6F-6aPs(z$`WK!DLkTdx6|P8R~v#sQcZa?gy>00EN9j=&l~Ci7!ES z_<-CGy2A(Le$X90pz%ZK8WC{1L0%)mY(G&7{4Wk#za&2KK{Kk` z-+;<9(0NLrHWp~!AJoSB&ICy}znLKE=06jp56%pAJ3BL^4-Ptq9OQP;ng(I0+d=jS zJO6wr4srV)klR6P#;~{@G=2y^n^Jtf6zKdmCI$wP*T4RYgX^I=KT3e-Sg*5ZBI~J3vv%LKPRNECCmxAhgn+)(k{>!0<{Yu z_b^LyLhfOf=luCfpY!KSV-WWI`4V*B0%#o`=q%oPaG5#rMLDEQ2iGO#4nJS$d&1gU z8^GuCp|`a_>&!syf?|fBugp1rzO?3qw6%&Iem=;D)+GrX;JU;rnqdm)-1ryu43M@K zs9nX%PzX97Ygiy>e!Kvc=h+NDvqAMgw9o${p5f<9P`^K!0WxQl4xUek z+`-Jw37IqE=KT4J-Sg)QZqJ{u+&O=~@aDvvGXmYW;O_bJp|>Z>9n6Lx_a%es7jRg7 zOoq9|+v(?vY=)m6Ah*OjK->@xbwf0g8~#J*t(ZA~zWVR+^98f#&sYAOKVJl6aYMAj z&jCKH#-|(6j6~SQ*U!L)W%Ea2A^gKI4yBUJEw%%mvDapfiI(`4DuMHz*&Thvvh} z(0q6unh$R?{d@^3|3G)5gUXP{Opw0LbEcm!UW3jhXb3`CC&O$%@m3xFIjk3pE8*>Y z4mJie&>S&JodhixAIScn{s44-7N{L?nCT~IEz1LD(TNY7QOlKUpm=kJmWhi&XF%Id ze7PLzpVd(RtcUt%Gt@uZnIPo~XsrsUT-gs=%LDb#ai*US4m#F#RSR^eP~!Ia`vBS>?`q1)Y0T;OZ&;q4PkeT+-@&g)&;POKrQhxBTLCOzMn1IevP5|W> z=r|YX3_0+9>FP-N1zWk%&H3|1KbHIgI)AF$^XJ2U)N(@^1dZbfL(2qlB>SrgYNe6{Q0mQwM=*w$uI?UuLop4 zo#7)&nV^kSCTK&>QGWsT#|zMXC7?24`+O;U`OFnG2E`Apzh^W31g&{`a9DWa18&rO z_6Ou|&>4=Pa-$lW&+4K1tQnfm+M)TZ8=BAhq4{hwwA`4^1isfD+-{oB^b>a9I;h=u zruP4I(Ajj@){#8W2d$^Gm}oKD^BM^U-z2pO0@d{(N$u@#oXWp!+i9SAp)~1+9w%tuF$tF#zY8_l!Ru zK6d>1;=be0m!SFW)vP~XtOv~_Ys1%bO^srh^5FU*+XwrbY#%( z&q+}XQy%s^?|gLH@#h0(t%-fed}YmvUC4ZAjfri@{ABfsP00LawTX40@VpKgqwQc| z*a~v@i*CrA+{^2Zh<$>nbFh%M!Dd!S+h9BE&sUpWf4hFCS}7 zd8vsFC1~y>S$*P5(A-J0+QgU8xfAgDXUKCWhqWgv)gskz z%oeEY!dA2V1nqr&(5y1?!Dhyv$nMYqxdU`g1jrqrIR=nBKywTrcYx*?K<=0i8jn_= z_!6`S7UYiQEI(hYX88$r$9k5Z4_3SUe7N4_=aa+Q6CYK({(M~T`txWz~;M4A1w?XUU&TY^sx5C$JMSspVYhl1f^5ZeqqoZ zBA%eUvzqZI*sa+tKS6sVA2cf=?*E0x*+WpAFNeA{7&IQNHSuLQ)UDvLdyR=N!DIL8 z6JLVI?$su~OlSG|A{*+~e3qXNvR!^Y%!jyjE6A;@G2Qy;y5rA>m(kqItTiz|7j&Nt z)ScceKSBEw!Q=AtQNwgQ$eo~jcR_Iq8kYyfDQH|C6sDkYc~F>w#^ph23p6ed3R8EM zpD(<}caR%FWA7k0g2vuKZUl|JgWL!mdk3dG+8Q!}u=m~oHdR%eZg51A2e zoe$E}4|VHn=AZxHgZi{`6CZS=hOIfst=&+!g2$A!CW7{-f%DXDQ2$(G;>-I`w}R#s zKyH1`{PV?YW=Ng}nfu!L=fn5T;5@|*winZ_$oU;KzYWSypmj%~pm~LMs5?(H|NMU* zAMlI^7H!g8`L+%#gef9y?h&vxvgZ8jty7Ps)D`L&zf9O1-vLeI`8N> z=sXPhRVZ~twd2nRhh2X@Jno9J=5S#+sDBHoqd1V)9R6q8`QpFR&I}O-vxmx>kU7J{ z+7mZ}#u$sC;kKIj=l}JfaFapYO$|+p`y&{pyvT>f?__AWfyU`TX%RF|2TF^eaXL`m zSqvI~QJeU3IrGmKtD)frGIzD}&xh+F;Wil*ZpB!_?Y#>k+^$2zEm<8BZlL>IlcC`T zx{DfgUIwmkJI(s@1?aphX0&iicl`O_wCm4@=TXBg7!+>FSi4z#w}oT6%>p#P!Htwh=0oG!SpyQ+pnE3Wp>gd^Adg&T{rTcLmOSF^2tVTtxgB*Q zjA61A4@eSlWGM{PZi}}zz;;aFQ*TdQqUxCK;oS|U{y|4B`v*bk3{4a95<{Kyt zf$oO@l`Y^gMy-i2L3hxC!VYu?Ehy|jd&WRv2O4h$#j88$?ptWs`7{4~;O+eLp+6+- zPF4M%{s45w33?rP87YsHL&L3E4H9nGUBGu}fct;u1j6k$>(3XU^`Gc@#M}{nwj6S} zb%Dao7)u^0XWIFq98VqrtwUmFT=nR&*2FiUu?&4^SZXu>{I3rxZzLu@&_+#%i$P(j z4NZrjyB0y|5OmifC@jI_y&4lid(>Wn!V)~*t2Xf^X#W~$&l~8BA&|MyJ#U~kS~(~z z^)b`oLzvqRYfmfy#j`rpZP0yV51Pd%K2Sz=TMfuys3XRmXE#%CvFgXY5DvqI*=KePUP#m@HgB{vAW{d@_!+YU6B4Z71@9y)IeIy(h+ zFT1$o&ll{FdwexvcX@ASh0KLR`#Rt=Pqw>)&t7>2I+Icua*yvrVaJ~j!1vYZPkek> zd*bC#hAA&V=E+0v@_w8NA0K-m&b0Hz<4nt!%$bOJaB-x0aCW45aL~PYpt)aW#-C3> z;~C;kJ3V0Y;PGrf|AY5W7*2$p`w0$1ZML7_Fx6-K`7$1QCvq~|&sXtoKVK#zg{3$2 z-dBIahS~w1|AyKDp8viL z8S4ej^TOv$LHAZYcKG>%nek^Kcs#0M(tqf_gqO}paR|x}pg08O2T&XuL*vk#?dL0F zx1TS~k>XGs8i&%*IJAbwp*>O@DnsK?o$co<(0&!rUKM*c@O<+N(A+iX+?4ZR_f7=O zMT6RA;5Y=`HD*m94);Uj@G!&ASD?Kw?$9_q?C|r!e$c)42H-g42gM=CJkWixp!!lB zG;YA~^Ch<{_&gGjo#61@?(p*^XucVCM;a)6HzUR2X6U>(XxVdz{L=P(vE_)Nu4z&Cd>Sv{$M@>q;Cuxzi$>p%)dh0q*9>z2sHl+Du+Si^`LSX zG+qxXhe6}@pmG>AUJojVLF4tHau_;Z4=#t1_q86@p7^c;WUm88KOV)Mu=ZZF+C)o` zJEue43EgY@pji|#&kA+t2T(kM=2=1R1dY3c+zA?Y2e}h8?hbP2e$coaXxxSA=Sz?~ zp?g)q?mUmQSM{*=#3LYgg637x+6AGYv09|@hKH~=jI!oLK9F1cp>AEx^b@qd^g*)- zVqO*M)}tV|g6360ZUv83YE67Ooe9!E0`2<*xph9&t)MvukXx5C{d}<+bl+b?(2Mm< zKOd}i`uT9Z6SyBY6XaIVJSv)7QNk2f2Pdmfd?F3%PeI+;&GhqsKWJ=I7%_(mb?0o5 zJ3(`(Aa@pn#wtN$I8b+j$7D4oz66iSs!x0g9+Op@__Cep=ZkKrJ3;1lJNKc z$eo}$Q#5yi`f;%F2H1RQ=O5^N>2kK8|5tUos$l(M?m`om$O0UN>{V}e6`%| z=gZY@Ke-thK7i}uerVY!lbhY} z&Xt189?)FrdPv#B$;j{lJXeZd7lYkx~~bex9&N}ec0wnLFE$iJSoTxNb{s{H-Pp+ zg7)_{v;BNk@AmUWv)j*C(7mP@ZUD`bLhm zaHwYc`KsLQ=Zk8$pRe|V&iw}6lYrK51?vzdPW&j;l(p^5PMQD`1J6v8kCbk`Snycjfp04ldY^9P`E3p9TK zDhojK2cYs5G=Bgp3(}c>zQ~5=F_5|0PCp;!L-N?Pa@^x(FD^TR?_qw?&#?1_b2_}; z*TKqQ1{#~hR$j~!1ND!fWra7>&;R})e+W)|U=N+If%;pQ z=h4_2UIU(jBhC5dVSg0o_w2jMh$(hpx|q+5>KDLe6;r+w%<6wgRoSlxO() zLLQ`-;Unm7D|~6sN(!{!7@GF9nSTD)2c*tq^>-Zv{!f2--tp&)euteJ2N^8?b2I(?&ku4V|3uK8v&iEXCqQll-TMV{Bj_Fg zP(J?-x?@~(B4}?kcwXo~<4%xS{zRWG=VU&xiaFH_idM5i~D|mOuVC zgYHOTT?x9c>!CEm&qwkMKVO34m|1?+OXwYFpu3YmXLr10XZQ)amyCmv!Tcq+!%x^< zMVfydFT>P+{r_JabRX0MafhFO>i&c8J>psL#di@Dp^W z;Y)GQU2YCPxfr>+LFbQx*B67%0IAIQp;4*z0~D?x{U84S7k>hZ3vq{^oS-vU8CkkH z85w?p_Q?i2;p-JmmtjG=c=nKS%+VC?YoA?RMo$&EpenHz%Ceg91d+4n*kVkhWs zKG3~>pfcm3zQfO1h742C!vN(@LeTwQ$_zgrsWbe1tj+NAi9W+mkUr4-{Y!PweZmYs zLH8>^Xhy_`FepBh9ezGAK4AMm8WJC8;PHWa4;?ICL1h!D@6^l45b{9Y;pdZP#)*%N z9ezFrm6^=)TA=xaCDow&z0mZ7$_UWClc2H;dJh@s4rq{hpnLURLeH`3Vq^$;CG7AM zZXc_|PY*_pZVgzNgUTmR-(Q;H=iC4P#X)yYg3^lyBg0P(PKTc$^FZzc#S5tI3A!&6 zq(%d@&H{8-m?FbO@V#K%kaBMoCqoG6&M$bo0(7q`sBP2E@Dp@zvs70u;1Y)Q(59`4xJ2SJ^=N@FEjjne4XJZBdFdw?eO#Ed552`E<5~uecj>bYiGuvuiQar z6w9xA1->(w@#ib>J;soGjX~!!zi8&1_`;g;C+Hr<7tCB*FYFnAz5wkHvUmKsnz141 zwLT-HuMjCV5qu}IKhsVv!G@q$-b_1Ju{8vN&Oqj3Wcc9KC^`|m$0VHb=Zj!Q@V&|} z!yUon0-$y6AoqdB1VHQCL1*28&rOD|WA9>S2m#A)clh}NwCAic^T$ethM<@Jj6dQ1 z25-inulzylCb(9C)}X%xjioblu6nSU;peM(#-A^v8Nq8TLFPO@47u0(!Dfe_j~;VO zd>Ftm{R}_vgX-4vkahX54m?vf_Ca}r ztpn!)TSwjlwoZZvY@J09*go!Vuzl3tVEeGS!S+FYgYARG2f*rHG0U%d1v)4BF~iSS z_Zfb^y3GLJlknm&+eFYl3=hy4@NjsTIu&jEqoZ;tV&=}ckho8Ue{!f3% z%&_X=YKET=7#OyI`~kY3`+u_#$~uM@&^Ug**x~1!B(dV@Sczt(;a>?vpW1_Vg%itDX(P>8aHod_&I@*LF5H=Pe&soByB$h znSUCgkA>CYCo?1H-bs0_S0(?agVtm>!SsR7WfXwudkE7r+2QA_=?*_V86AFt%C%SO zp#B2W&!^4&6CW|Nu6k6?@RNb@fGr~^zW+DaKKR{W%fNZSmXY^>EtB8@TV_yv^EcW) z;%>Bk$lhrCfVt83f$%}Fx);o>t6o$y{Cx7=@#o{ujz1qU%WEAifu_fLNL>%|_k((e zpAU)|euja@b;_ZB0hM#i469zIGyLRaaQLYRI)99raTTbog6zkNN~n4HNap23%yR;j zUD*ylU#2^N&I$ytO$Ogh3q6ApWH(3-ehy_Y!_QaYko#%DXJJCmq~v0PgxQN=ho7&) zA!VU9tHV#8kF}R`Gjo2dd|Q3lizzC zUw+;JvZmUf;U_Dn1Ej9F585Nf06EtHbp8n_ecg8a+2q_11iFtV%}vdo@!7!V1TBBm(227FQ+r?Ewc%b&XV?ic>&0}3ohz6b%s}i%ptO11;U}oP0o`Far||#uht-Tf zAC!YI=xhaspD#dj^~@ZrKx=qcz{(nT&>BaEpASKCI~g=?@9-0z_NF`hgvI4lQ2Vc$ z;pcUzI?&!IP(A?da{|YOHN#IWMu(rCtPB%18yP-wvNQxKUhSF%(+^5pzWmU%V2_j* z>>>6aWMB{h)nTA=4s4!2#JpFaKI1_LOHkhdR5!oKXZ-mBbl-?MB<#TV7lYbM+K_Ys zYBPY=+k(Ob)Lwgi-r?u_;|@RHoOby63bbw@+YwxD@_wwn+?SdA<4o=O+2?BcXKOO@ zt@dK%*_FfU@KgJ(!=&y^-5;JGPfqswTXXqUKI6}q*^HpECh(eG(B7{npz|1E=|mkV zounhBlVrx94?*+%$&No4`85PBW^4#L_CO+!NI1Wo6jN2rWlIVS~~pQ-+Rn8$;4NNFT`Wp#BEf@5&B8LH8Gf+S#jl zAo&Aq1|#S$0FG6!gc*KnDKboaCC>0ulM^Jyx$2cPq#dWl4N(tTDGBBdH?dE&_n-1y+gY>-?cKG=Ubni2$9OUKh)@0;< z{hFC`)oW&kpRbz*C%$H9`1uMnrUDvI0l5>>hPa>!ay#h$4{t|sJK{C7(8Sl=3_oAF zgT`B!e!gIUx*62Zg0}VG?gO>=K<#U8ho8vqgSGj}VeVsxw3T0KGyO#FCqD#_*D(F; zumbHNaQeykvG($e>HnsK!ssC=zn*va`3bcCt{IY+A2d7sM6dV%H?v**lP|IIZ?)vg z2Uz+gPeE(N)g6AmR(AOL2IL2Qho7MI1)8sY3z|b&&hYd9Y=)oz=QI3#nancre?P;| z|C1Sh{-4h9^G!d)&)1U~euC=%m$MmuW`f#Y^FjBRJNyK-Q@KHVm>WeWzOH8YxtgsZ z=yg5A&(%T=L9dw^A!EhtjG(dN3)vIJCcbWG`1zWlA?P)zjs@*m1f5e1nhz3Z_z4Hs ztKAGgU+#zAu@36@f!gET4nH3qW}cYp2U(X5vhN9~PYzl)@5}@qXMml*xYD0t%4^VF z=b*lmy2H;W%nm;v1Rt<{px$5$x^o(IKllsiz0t6Hq+gqZ?xzQxZOQQSg)_rX&^d%J zK>Hw^A@_(s@^<+7*x%u22WYJrJHyWdp!=KIL4D-Nm4EUhR{n2h1K+m{x&!+msE;V` z06Ir<;$v@zpHKW9eom7Ewf#}m{y)rc@ozQL$_MNWKOb^4{CvdE0PcG{;&%A?fZgHe zVg`qwOISed52jV+|3UhlR{lTC0JaCwZ{WTNZikjL{CrZ)@bh6k!%t8>^SGVi=c8^& zntM?X+QZ}U^K~_-Z|3mx4XBScpW)}5#SA~+-4YrE54YmrF4Ysd}8Gb5w9ssL_wWGl0xH03;6U+@k;J%2t<4@4N zE}*sqXm61ns2+su!TRU`Eh}Dt=2$@YrNo2ED2Jcmc0w}v3}L_2cCk zf4-1+{P|KEbRQN2cyHA|P`d~eFQ9h7e57_jJ*ZuR)DD;rZ3oPE*r~w|X$OGq@rK&t z?eG(nPC4E(eB^<(k?I|OzH*1$Z3DVv8FU9TsLiiw*fk53ClA2NYj;T7`-L~d&v&3U zQZvYIho3L)k-`PM{sI~>Yl-c6a#s z!WmLlYB4kfc`2TrmCeZb(aW%77HCXJlaZ?nwm<&`zvEBP9(`CG?u3R32QS0NMyOw& zm5Mr9$@A!2DN8E=fW2| z{CpYj@bgu}^&#mTRDZvKwsl^B+BwDyKRdV~b=DKm7<#kA&sU(fjW`2%3_w%x)MWU+ z8)2ll0^h9yjjO{9KOY`<`1# z9~>V!SG{EBTJ;h%P72C{$_zhWooD#@0(5r^v;3+z%$%#L+^=7# z&zJIIWcc_Bw9k#POX{UQ!_OB?4CbJ`03It7+uza{U7Bw+F3%c%TnS>)@~ewWUDg zx1e<)+zdaTJ_e7WL)z@Sp<_P#8Gb(8@9^`%Zik;rnGHe7j158Q?*FF00_~##om*_| z@YAzW1Jpoy)>ia;_1SniUeI3wz*vsh*KVQsd z`1x|W!_OC>bp@dDvdIiTAM`u?1hpIfH*=$m4ZzF$!&(=?=Nn#U{Q2lMyAH9FfeQd<*WaPwNUH@^|4=r?r8z5>nD zMKeLxgvB%c1l@fOy5}0+wyJ!me0Ve8}9jz1rQ_P^|R{Q2my;6y(k zhAA&V=ADPE348b&)Ta^vpCbrsTTJq0nDPp=Pw2km&nMeK=NBHdeZbym`=6QV=YP;V z#bN%5|9><7{QsZv=d0h0KVSX_#RC(#&-Q|y>E{Dxr=Jhmoqj&zcKZ34-|1%wXk1}8 zBcwe6Iy(?8{6TT{ireYuOMa)HuRv=H+97TS#TjT{5V%g<4DPpxfbTVHcl!BqGRw~w zpgYo-l_x%Q7J$zuB>OT<0h#x}`;hGe<0e~BoWsm{06M#MJ>$i)z!)&No zvms{91L-H=hD9JZOo!^54$(IO$ql_Awz3jr|Cv0}{=AZw6gYKb_pZFiNuS8jC;!Dt-N8h3MBK&6l`QW?r&xgOAf3D02*$?q|5DS9{ zD1MRM_#jzfB4`f=$gLtEx7I_~&qDW#ykM4}`2R8U&;Ot^q(E*3?fn4x8@l%c>{jHx zA0W3@Gyd!bxwYEy=YQzAC-6IuKyHPeRRS*Wk6iP~E_=>OnH-{uRbmpz#9GnJ6zVGyi;X-WfdBAzT5vE5`BX zgX7FUAA-(JIqv-PWj<&umGkwh<@2RpJ!jhK#mG>^A=o+VMLDSaWB3S~t9exJ_!Bvd z9)jYYnQ_%>(7b3oG<^0m|NIZS-)J%9&Z7U|y(fwjL3bCu1clFT=ASS2GegR#!^}S) z?05e8@G$6n2jz*6q8WcWgTg1;5xigH|7OtrBeD}g_YA!Rg%9Yyq4m(XM7pEM3=}@` zknp+B%pii{&SVAfn)gPKJ7IeT7Bm0+58B6ZSZ3mX=p8~YLGcLM^8s=v_)a0HJC`&6 ze6ZO0=fmYtcLp>5lmxjm7<6|e^H0#dLobqLCjRdS?YB{y__Ck*=ZncucTQ*i`Czj1 z&xg~UfAWCb2|6clJ>$=<%nTx+yJ}ySgUUS4*9%w~LSTF*M$XsR!Z{G+et&2v%H`M*!j6YxI{h$8G z+wmvpZlV9xpgbcz5p=%}IGjQE?36>@U(NjULAmqKht#9`&^;P2n58HFho0dA4tLO=3sAU2_gsMU5AvQ1Q2udd z{J9(CZqVL=Xy%`wyL?_OmYVn&R6pD&`J?v7{v`5@Z)=fimCpX)&Gc88>o zaFDzCU4D9)Gi(8kY5d>L@)LZ&D)dg%|C?EUzH(Na_-Z}N&sWI`6JLS$lWu2$v^RFM z{Cu_D<>$-YE}*$A$QdECSs-iB=d(c8pgVIy+8geip!UXwY|t9?<6t20gq)s&ImzoZ|F1rd$OA-wR%|1L`MoL-Kbo14GCQ z&^jGvM#vd#-yOkgzrkzJLHA~X#tr^6`~>wUU;Kui+w~iCrWPpvvwnciYkR5h0$GC& zU0V;fs3j&=52ekvfewi86UWCLYd=2_*mY@GYcR({E z#UUs^fZ`C8A3$;V8k!&8v;2JZ+U4iV_elBSJTyOCW`V@vYG{5~56chy6JOtEfyCi` zmY=Uav;2Jd9fV!L>-Rxt#DUiBzjzNFFMysm2X22qcli0@GblXp#3AVXHc%Xb=1@WB z7XOFlhsO>-AKZ8N`6yWp9EW+JI0TvZ9=eY}+XdXWe#!3wo^yrA;dO_fFG1_~8KL_K zK;e5Cx&|E-zL%kE&_VkEK;aAO$DVfp_hrH7=z;oq`XD!F{djSh;pa3)0JK%8$8WXq-T9W~~KOJ0#d_2g)5CUo&yaxFN z6nEM#KVNIJ{CvgF^7FNFqU9^*B+J*#N|vvb6)hDM8749+GE963>d)%CfcughEDk?G z>)bgw9Kd~24jzY}FFj!7%pAYPve?D|}{;3Aq3%=X|+=n>N$RGl0`+?V3fZ9~k8Garw{XhLF zsPD|oxa#3-(3%{`{brAhoqxjGw4i$*GePsOu=V}WJzy`GB`5xe-a!Vg=RkY9K=mAS zPZ!u9$a}g#{+P`0lM&>P$qqmNOEdoj-COozvBX5sxm#d=h%^6uAr1A1JoC>7($1i^ z_|Gpnkahl``gtxRgNWO||KjLvp$DKgy|d!Ptsu9;*3I)X{{-DX_5ymB*niMjT%a%q zoy`SuD>w7c7yQt+gfR2Z2mH=I9|}X;65R|xujTxo{s?rB=YOW3|CvEyE)en^-XfyPs>JO2FtSjkd@6Vm762CcIMwfUMEe!g;d`T5$N z1vJdhKAL1rk@WUJND6F7;W_3mekyrN}f5OK}py$uO zL@KXegUV`9IqeLsYu!Qn>0E!lbO+b9kiB#I(7M(bTGwVn>)L#9T{|Hgv=-MITG!gM z{(J?x!vJ)Dfxqj|m&uUzYTz;NbZ9vZ9!H1PwV-<*z2SB31WnK!40^jIoB`5qiDvlu zDwy@>%W!C23tE#N4l1WL!R0iI2k4Az(Ec$q39&J@fJ(E32o znp|t7HM#akc7euaL1!}|m)qV*<+e9;PSqJ4Mjt_A=TAXn-^}u>K;z(`HRzx_+8fyz zLO}iG2cUB`kow7wl$9nbhy0)Zz#LjOUT69Vx{K~bve-n>{crz4dxJpv^gJ}}U1s|E z;yN_#-Ddjv;JVY#hqs|=&zRxoo9zG7LF)lQ=WP8y4Z3$sY~ugJp!FY06JH)?`uXBG zH0_;c`uX6v)6a*eoqpcW2H6kEryUFoB9HDn{sf=@f#gn5+4ocY|8&sUsWAhjFOAJF zAA%c0>KLpXuj=-A+Fr?uYtC zo#E$BkYCgte*TB<`FWu%I`Kc~OfXQH0o}I)Zm%Nk+gSthi#EhBpgl#8Ze#b$F{oca zV?QtTL1V}aKVPsgYyt6M$Kb`3(_&z&O`T*^70);8` zZaZ+DgM7CgsLo+$_?ZFz9C7Ox?wZa`A2$jA@^j#pvEpZ~=ff4&rU{0Z7y3sbMk$RP6i zxdXVqdCAP71sbyi%}2f351LQlSoP*Gh~`}N<~YO8*QX)#4zPKZ*C2ZiJN$fe9Mpbu z`1$I*!_T*u9e%#M?(p;7a)zI8S2O&41sa#%%<%IKXg+#3!%t5}hL11J=Sy*b)`prx z<|sHAJEc6B7|cO;sK4Co@Dp^G?wX(Vm$hp-XLHqZ&epHxn5|cPa<&&Ef43JSU-w&( zo3Oa&4yddEjp>8ttf6hJH`^V4zTNHc^KC!FPte-D*V94s>kL0%&S&`f0yIAlT5ASf zu5pi*t#KQ8E8(3SArn~w5Aetp7ZN& zho7(79e%!HmS2^{$knaO&=BPH*KzWzXojEOjNGrY{?<=^8_)3bO)|sJ*XayDUuA>J za)zHTKzpy^9e%zB&4s3e)~!P7)wjhCKi@ht{Cwli@bjfN!%tAT{TjOV3KTaSj9jNQ z8M#hzFmkS1!OpM+RDOfjUA+d)H-gG(Mu$ltw`4Q&ba5~`T*_wTImN-qz3P=UWDb1= zBg0mZ`Zw;NwW^@CpAJ7gYk6jK)bh;suH~NXReNSO2P0_xE?4(UYlfeobM@Z2JN$g_ z?C|rozr)Xu-VQ(CT08uF11ifo8iF(#8iHOib80y-GJX_bW%vl1L(}-@c-cVd!Ylzc z?^T9s2WElgj3&+sWMuf5%{XBeXx@{{uyfYQTE5vYYWZfLujQY8uJ+t)4o3cN4p1E9 z2(K-mb<&`@v1W&#uiG7dzTFR6hv@M0UA4o{kKqnKKLk7cd{gf5^L(w~?Dy&nKYMBg zXJ4oln0>DH;_Mzqf$ly=zV3J03_sT}^1XfoPKW%jUzpFATFc1ynuD=N>NRMui!sB` zm*xzhb*<*0HB6v2=dVC(%RuJ?8Z-O^%}asq^nO+C@DmjGAUC`Ntw(z7@bf)r9!=lj z=LchlpC8Q~etzU<`1wJY;pZE1sGaSgw9o(gMLUw6ptaDW_Xm+-P=Jy$Y{s;B* zVROJxJ3(g&zUX%N3F^21|IYwEcOBG^hm}d7{v&8_`OD7?kh9uB=bnSkXMfG`6V%^* z@Y><$!}p-QFPszqs_*2`wA?WpOCdin~ zeJ0SD%!KTRViR8%gVyOb1idbYtn&rk-SiT4W)^5XgBdh01qwTG-*h4Sq=ymt8c;P?UC z2eTV&|7$b;{I3rh3jv)C%=q)aI^$2!di0l|u`X>!$XK;L z@x09g??zjWgAU+vxrGc2A)s|Z;5dHH@H35xK?I~0wD-n?kzwltcE_Jjnnfl)n(XxR z@pLEnyqFGXjQKgk&nPAakq3)~A@eu;84>3PK4$pYBl_$Dg1zsVuAvAD^6O_}RhU5Y$n_F&nf_K?Am* z<1)if=w6!%;PaqB>%T$!IHoiHd@$MZ=fmlaKbxW&!RrQQ*#Dajs&_%_8$f5{gYF#A z584(5gZOTL2dw@>+qc6=YDiI92T1RkXdjdsGatRnL|st;Q#ao`=McRnepfU>ri(v z^G$s4xWV?pbErEGgUTnNi7$^c{(K2?$7!fL&V$wyK-~elgYhz?-42S6?HT{4gW4^i zGeAIN9^f&3=-CP{nZ+l9?(hcnv0oh)n)vE5)6Z9ng(toO-39&{x`yCA)6ZA0oqoQ2 z?*u9HK91ymlzHn}A!QzDO#e0$WK91))6Z9+vvNS^ywSH>7X;qB$5`cDxXuFZIHoaVLoXGC2e>rtj~FxL;*4 z#YX<1K0Orh)u(W1|j0ab^B88RO1&iwNg=xi>~d``IY zPxN&w;4%HlNMSh{)Yfwb*B>t#pyvXh*B{-`u8Tc@h8yu0_ZG*YEb-V{dfU7vmoB-C#Z~j2^yz@on4df@bhIc#18P8 zBv3oRWBO1#z~jN?2s_~8!SxJ3L1R~-eJ}7aeR<}epfO04I0WSfP#l8t11JvVp>e3p z{PUH(^Us&cNO8yvjYD>59126@P#h@^`Jr(r%>45e=zaoi=ASRMoqxjC#lhAhf#Wb4 z5}x4v0O~8K6NtlTXdK2f{Cowv>%bTqhw%6no8&x5h#59k>b!FI;IaAM*@uzf%+_7v;&^UBPvIDd)A2jX*8ykY!0gpp}=-3csUF1j5cn~}e{Xu;sNPc`V-{GeQ$B*qV zK`x$>e*zNf9A!vP6v&clp^#9XefX+UD&hQg_-o#;{iLXI< z5tLrboqoP92d({L`uVy!*z#3!h~?{K5zAN2!ie!;&^qyIr=Os;bznb(`VpY{4A2-1 z$j_iL7?7VqdlaC4wsc{b@|NA<=NoQ^pRf5HeuDP8!q%C;jc39b3ugTHU;M#yP`e$q z-S?jvw8ma+<=<-Yl@F9bd#@ROKGJ6R`54p}1FaL+cK8YE?||wm(0X}LIrqPt;U{P< z{Yzz*iT^?STcQ1PP+#;VsO$orUDNLXDOW-5@?z*3`f`S!uWcHFUVmnQl&jwvAmu8n z_(V`&AH2>DG=>fu8(7Zp^Cf6J0W>ZJ>Ysu3MT5=-0M$|AkhBZVlj06PLG=M>FC4sF zoef<>4_(jyiXSxQ;PCUMFlbFZ!_SxNp=;>%9ezF(cK8W8=lfAJ^Ta7mpt({=+5^oy zKh$^l`GA=Te4YTT9el%?Vafw#ho6tx9ezIWK4AMmxxx0Kv%}9v?hZd~L2UosUy;sC~%1`+XUR%(-@nZ(a`9|P9xRATez-^R9@rj_Z!fv*Ppx5Uaes(iA z1ifAi-LtZs5t83RB__VU&hQf)f44#HHin-sL1O{`9e%!qjj@2%Lz{!^?1?WxWisrn zLC`v5(ENO5<_~y&`wY!*pnmUXho7(18Nl=WptA>Ff%??!(0;JL!_SAHF>Q6wUOTpl zI~*CNya1VJ4ygkl`h(VGvrGi-^?~KLKTZr&9@snld+3 z=082mGV$?jho4X8gZ8#E2rXr0m;%153A7#=)Ybx((V%%%X@;LCK=w&H`~>a4BgH<@ zSrbnVvrK#f+SfAM;U~xsj~6pfe8Ir*fum7;BIxW0(7ihyp#COkEq67;PYw|KH^a^j z#)hC5{~30I)rLw;1hw~GfW+EC`*N5k{?BIk`9GiG=l^1cpZ1cFFa!DR38;K*ci8z1 zR9=}Muzld(U<;c6eBAHwla-M{NQHr63h2B6&_1-+)($@(Bs2Vcn9lI?Nit}E8pF?5 z=?*`$I2nFE?RWSI+S36#Qwr3Mc^L2TlZm|{=rB`5P?ycW>7e~`pzwGF8jlTT`1vB7 z;pc1Uo>b7@J#9urJRq~t;{=gcWG;f%Z9f6^)(z)-#AN8d~=)e=j&|dpRYi7fPwmmpms<)=qzdGpD#i8WP$Kw zsfjO=p>xupHC)M{wx9FQF2;r+P`mpT1H%WesS*=kg)@WC2za%eZ6_B`L(r?mY&*Ny z8iHPd`VJs9jp7quf$r$4Xa4!3ni;bHzux)hOVGUv&l$nz6TAf7q3|3so&?^@eI2r9 z3ci>7y5r9m)sQwNcq|EY1~IIEP|W=ERk`y|@ctvvTJK^In{(9z(4O~p(7C_Npm9?0 z9w6|V?en0sb{&5{a+aF-&;fK`ALu?uM)3ZBkUVJJF!(+P&_0Iaj6a!J9ey%0I{e(h z1l`ARn(=1?Y#+yI$Dg3Fjz3GU24A2>VzeCY1{^S`qUY99IzzK2{GR33uvE&;9O zfAQaW=Zkjcoh%FtA|Bv03XQLJ=bbN_nL&5`3UhEW6uyS-w`qo%!C2T0+w%mPceG}P z>^DQY7YxJx_l`d~Ss6CI*w6S=kp;59=_#o1-|V~-?BCzcJ6|4m{Hem~@KYJI$C8mj zXdMf~l!xZbKOY!_u=CFcptha4Gh|;CsEr2;1JFGUp!B27{PP9Ux(5t5YzM7$qP`P0LAZeP&xyb-ya=iAmIX%1Mlxz%n07w z4K8Ou>oZ{Gk1#X%{;~(c&OaCNHv~DeK+gBLXZ3ITi^YyVUxMO^5!5E))OyLxpvBRs z`8r7wYBngGLH9|_XZ+a#-IooTV|%$76!r`spMdUhXJ%Oix)0!GHmJYM_>+~<;V0M) zpnKF97%o7{K<1wh`JI10;CBAWBmmi?vd`+@^w*Oef4-XT2sv|sSzgOCQ`_Rjd`Oss z?U@g?2Q-Gv%(CibI^)lm&e9V>dzZoX^&{C=%=q&K=qzBEo#mkMROX)#*+Kcs`Dc`13`(l>5e}i zg3s3k&5wp#zD#EP3EMLd4zp~>pRdv#f4YFiL&HIP##mN?&Q1sIrv{xZ0*@cid7ZGZ zddvh~=K)&p@dz3}VIcQ~JN|qX?fCOWyyMT6tPMfn_(_Ju&&$=0;Q7{9(6ikiFmtQ| z-I2|~$n_eWFF=1>K+cDj0Nbp5xD_{-C_%_!E4tk254azwl;+q#1L@pD#db zP+;z|X8if$Hq+0C_nm$|xb5_lNvI*{Q9aYn#Y~VitP64@$iJXFM?h;;tsQ?ps(0G? z#M$v@HY2Fb#rV?|w2tRG)6W-|nSMUJ?)3A)Wv8FYEDb?&R{y5Ibawpt0<u^hC%60|>#W7SJz@ZOY<@I8m1Grc(( zJ}N3A@)Kxo`hh-<{G<$xFKy8NeCMB_@qc)HfyVD);c}P>e0SJ`!%jbwgdzFqmF2(b zuarS!`HtXu0?^(8P+9`n1xin#assp-_kl3#Hb`kmqD3(#5!nE9adly@_M z*E@jLJ%GmOo-lK09TIK`di0-hCo^+H&^gP0(_e$yg`j){IuH4`!_PL6XfYwxOX8QSXyVK7Ho1K0pvqR$X2{+@L;_?{hJP&ZwBR?2fG=5KD^KH^TBO~pDLid zbD81i15nxanBgb5thvsBDBJck`~;oH`T`bSp!;W6Gl9=$eX!c;r;|uS(4&6FouIvV zEg*k^_RZ~f`1$I+!_SwXIljXVKOglw?mWZ5aG|GBb7C)}!_T+p8Gg31I{f6W;hycn z$o={WXfGmY9m!&*pAVOV<`$fOHnTJY6eLlmM=FmpqBT~9Ux%>x_1^7 zChMVLvKlE&ri0ENfR^`@nSMS5%|%Rh`pF~;NuN%ja9HjD-v16-mjEwMHbeG1!pjrT z-g$6+#IfqZe9)Kxv^-f1VspOkf|e&Q7d!lXI^W^vi`Ag~$NBmN=)9|JXYf8lc)Wnl z=IUmGlr5k(bw3mMT-pcSPCu2z8iF3lGs4RfDNz0al_TvAKS6V;kK`S9g3iZzo$dS+ zw8jBkj)2a&ZD#uUu-)nBgJwuM!ejYw`b$t>V!Ff62cY){wvpcpOT8@CmwW~pE zo#a=&sAu~5pxWu@!+Ix-HW#QK2Bl9TJ-td!RThhsI$sQXG~e#bGfM_&%}+#ZEt)#36Bb z(c<6qSJ1KH2cU6eW_c}e8B-03!$+V!g!K+TA67g3d(D*H=+<=Vr zaK3)w%>-%J`ZN7}06o(bqpkp@uW)Ey0-d)2iU-iz2vFO}8z~+@Yb8MEq{7ME}atr=Jg;oqjHo1l5BK;PNHM;@@=8cqnMB@=?9RPSE)arx+M6cr|KH^aj;|&I~_Y zSwZ{UnSQ>oX8QTi-s$H9Ye-oVYw>S7X#ELj5Bn>3$T$UZ8{{Quya3eS1Ff-SpAHI}hvrN_9~gteG0+mUR~n`L2nz#cXc-GS7Znr+pmS$n?MHp2w5ZJl zKBx16w$o21DM(t>1G!xpG%f);W8DGKK7sC^hLZ^mw6LIhw5=c81v`<+0qORlimt5{(K|O`13V4Sb@R*l3XgrL4;ujl+ zDWG$_K=y&hpF!tkbsw;OP~2eqpqUlEU)kIa)VFuo`JnxP?StqBTMk(UaDN)q|9)}Z z0n)!_WGsBkzyM#D@xPf9rQiM_9@O7po%m?8!_UW{a{{4fZXQnq-7gDWC*lq|lLuAb z3(!6kXUOIb66QBa)8#x&1U!snrnRE4+&F{dXPOY>K%5zNM_gxY6rha zXW027-C-xFtp^&v)CApG8qcuPSAZepDRli8=$t9I-zG!d1G?)Sbl%-`ho6g-Am^fi z{KgOR8)zN{6fcYpmM^>+c52Ep2y0GcD1711u(Jnr2B^2gPR>?FFrOR7e+l9Dfc9c} zJM83Wgs6Yv@38ZQHN#HMwG4$X?HP7*a5V&RFmh&t)mc02d=byEGaR(m#ol2jsExo< z>oEC=FgU(Ga5(Zze1Tj>bwk|_y6e3ga=z#x&rh3KCqCZn@bd|%UCYe4s)OtQ z^auRV^u>>vz8* z`01pInNF%eWhlGD&llDXJ6}BpoihkJ*OlQT=-gCL+v zLHPhQZ}S!uU+fM$S1>Y|ykK|O$zjS+2s*b1%+_Qme1Inpg4!aGHUYy&@SeM5hn+9u z9e#q&d&8Eu5ap=YMbH_b53?C}KFVj@`53gOVn4&rr=Yt`HbeRiuR-fM7#b$M2Hh6{ zT5CO-=_hEN^~+?DiJ}LA;3Us$M=w9pfPCr3sSb_Fry&VmWBti__0n^Fi}}PCs8RX88FEw9bAzL=;&N+-DK9|gt%uAZyvTNhlz*HIh2ZiK#%E+K1f6Zh!O$@2MKQGf zRnGJi)Mf?UrTf2G45fSo*#kPiB$2`4XA+CU&-}mtri1obIe^CgXFL4-pUw311=892 z==woxU0`twn%i5!1m1hR(}R)047{d2nd#?$aNE`C=fiZTpXmC*WfSyVkq6OEKOe?p zs)5-7TIU8}qh^ z3~~?fZm56vGyQzE+v(?v{Z2n$9fs^F0k!Qx=D__|4VsgJ+`rz`-4F!oSA)uR4Uqpp zYg#~UPzLb+>>!YP;d_tu8F#+Wcij1cmB9?O&JH}U0_vx+L)LeK+CSbl3{ybve39$` zK0gw4mLO;i1ZXV;Y~PoS4a1a&$qqjsf$rd77M%DXo8hOq4a1ZNptD1>9d|xD3|dFZ zsl_PkFgZ5n|MUmaOg|rj+lo#mhGEJh(0txTq8WZ30Nqy}?eO#eWyYT`u7lRifyUSveuDOh zfYz9R{PzDebr^*rOx2d5o> zK0NRE^G+P79pmuxp*N_mK+W3^K68Tar|3|C^f|9sGfa7z?YQ%QJ=4zr%}hH%d5MEz zNzsdTrkxtalY%(f78SkdhKVmKdeP6cbA?-T5Xa7iMK2~Z?d(u#4$|mZSoC5#)6Nr< z8-q^dEG&94n`vi8=+q#O(1k@W<}>YFVc8kP;k>Zu#bTzN8m5gw9wrNmUMy$YsWGP^ zh(lvx(TmkgJ3TC#gI35cEPAn?Y3B<6nL#T=78bqO%(Rn(VM@>oo`pp(wlnR_xHB_| zgKc5ai`_8yEG&AlpJ^w@n%1C>Uki#}9A?_-kv1`?4KscpnEn?%?t8)w4mt4ZKjNHdcn=S(__-a zAdX`TieB(D?>upNLQuz%1w}7}nRmW;F+Ygo@PeWj;>}w6`*s`GLg*Wrg6APMxR%~8S z^unKc=ZXKVK_@mXD0&ghyz@m@f6$AK3yNNZGwYQ^P#ol&qX?rIbRJ9&>8d`THz-Dri12vU)VeR1m$8KyjNhUR(Dy)B?M?8b~gLFW~|0IfMNb_DP30Oxsi#-E^d?k^s5 zOa$$-`mfCR^Cc+HgZ5m3^1L$WTnA{L*Jk|rK;7}@Lv6>O_hbK0e*iic(;PF;gWLvl z*CWuHVrHgQ4;S-K{Kg5{3kWWY^c}$av|fP5jX`HHsDsY$bo}{3o8c$eU7)_FFlg^O z$3)QHivOVgD9Bx)eHI{haWnpW!4GwpFeCV0MbLQ+J3;PJhpc@-uji57^$_eX##Jkr zA$0^pDs+7VsGL-G_zCLkg6`l0?biUc!9n-9y^x2x?K{KI|Ddt>WcG>wL2E`pdl5ix z1Km{!a@%JH@O}<(+v7LG&j;Tfem?x|@N*K#ZJ;){JZ6}I%JLV`H7Bq&D4;lHl46+h z;yKeq2GBkLafZL(u({6g^FL^hNiy5S|K}Ng{s-Md2(lk^o*&45(BA*+43PZ^w;6su zxbE=t;cbVXMIigd9sY7Kq|F13)q&bBpf>PJ(3&^s{sK^)4|X>{(mG(!m`lFn&X=IG zarr^xbX?spxfyb%5TtGI#68gLXZDOgpE@)CeC*En^N}~>&nL5)c0QcX z1Q}xm-6i1c`16&$GspJgYPcSF#tZWhS81ZSq7 zuRv-*>k>fc5`)H)%b6hS5~`iRb3`w+A@d=iv5gnnNb3@mLGx>zui@(wltJ^IkTyDa zT>|LrIR*wuTRk6i7M&AhU4k^^OqU0sdkH|}9iX$=>cQi2kaY>5azonj=L31jS#rBA z7^b`cnXL_3mjEhLUKl(6d};3Z^Qp7I#8=F$t3Y>^Dli_fRb)M2`;fa4e2$y~=K)(q z-UGHuf(LAsLFc+lH`+cDZ?t_V+-UoNztNVV@th6lyg6`uGeh=Jfc7nb_b+^Jumzp9 z58g-c8nT8TeEvIVe-gjb&&S-Lu~N{P^72|PvCy>;;z(;D#Gz{;4m19Iah&nzgTszL zA0Bu7`QKRzrO)t`-|^?e`A$1u2s^^h4u9ax2RcK10Vz zL1jU@6FASmfR*Q)q2>8@#-9&CXY_4${F&s_5Cod%erg1o=Z2im@&L5g2{vBO4oxrC zjz2;BctCrUG;!?LkFFk0lt%2Vj?&_-3G0tgx*il-)Q@wyAkt#iusMU zk7hU8KAhfY`(SdT?Mu+S+~R{^wH&ezlTgmx`qkVb9=8t<^n0R+6(z;wZl(PIDyth zK+f(xG|Ptpbarny;_Tk#h_Hi&nE)uvKw}fHnSMS1owf1a>E}z({vFV{JC_-LUIF!A zL1_;8TwiFqg5R;>47w|fah2NY|I;6W&)ER&|8n~I;VtS+PgXBir2l0()XZnhQ%c;`|ptQ@d3Umf5{7hfaIjo>^YBST% z7od6h?M^>mZbsO*2;`6BkUOhhg6>jf4zPULEM^H_KL#2TTFvwm)_(`xGX#!j&|1pL z3_mkq=lO!}W?k*{^JO_`zTD|2hv3P{p!+$%=TH@+#o=OT94<%9cQ<7~&hp)C_;30f z&>So1Ok>b_#-OxQ4H|<$I?ES4XUehaC1~yPdM5C_sUWw4&+=^t?YZY(^#;7(9Lrh0 zpz~;9XZeEe1_7Oq((Ul`al6CMf2RMYgZH9?#yvo1GuIPwmhWmN@cMuU{gC_!8cTW6 z?*Qq$?}yB3K0WLNTIUDJ`=E0XKx;zhGlA-wpATj`!O!w7G5k0E6=+-l)Q6vpbe8XQ zhM!CR{}%_fw_dDv`uQRmbf22&M9^G}VA}ub?~NUQzS9S--EsK&=(fYpSD^B4x6{v8 zptyVunoj}6XPD(HaGVNQz66h#IQ@Km-0A0=(@sC%o_G5Bpz(ms!^VR)@Bcgge1D$l z=fTECn*)svHgEqk{(SSB@#pLBj6Yw2_78&YpaG?&bkIH-rk^iC_uKYE&TDv)EHd%M zWazmK(-G?eUPk?&{t~oT2DDEfG_T$bxo6TxDKc_xD7 z!R^oGj6WZO&S72b`11(JP5&K!g2s$rM1$I&Ak6jpC1}4W(q2)Fx*W8|`Z07~*Pr3% zOVC<1bB3Rw`W>|2|7E(kXaXZ3o?F#Q5`JyW`IX z&5l2lSsH?#8vL978Z^h{4Y|kVC1^hpbd4FP{>xy1)O(;couGLY&>lw4fB(fn?3eFB zes{3cWMwD>_2m}A>MoF9LHB%^J3!W$f$jnX&136B&%)70n#Zn3@?$mQ&xfEhM5`Tt zD)~d&CwoEeQ-|)s*GHPeHHPFHaD0O1ph5dZK=BG%(+67T2fH%`6tAGWQ$Xc_sUR%Ps3bYZtiIMZQ7j!NdG?)HV z9yBKE@Dnt*0$w8pnukb7@((w|&lgDdp)>`6){`*oY=*8)YXkWW6i%S<0?kE$?sSlM z*a^A|5WF@GHU}Kf`13_Hxfc>VZ}O4B5WM#dG@oM0VAuefV*;@S84N*Zs-Ww6z$~wYY{p~Iy&9ml zQlsQVP~Y8y33P`i1Nh!l(4L-0iy1&`?k8|CN19X;b#VGLl9_g4YZg2g*|w! z{R9q1>4~8EJ`T`*4eAU(*J}Nn4!=Vaw2q&f;pankho2xff&2#wr@c`BH8A`z|6A<} zzw;98H%kUX2I!m-haiLD0+`=884ME`7(!SX7)0Lu|1XZL?=k4^O|X9;Zqb0c1+)(d zbg$;4WF-H9`o$ps2s8X#!QK$`LYrYHcwe?Y)ITq!CxXTfR)E%J%QO6}#N{6aNPL0( z(@87;ILd&-_5>(?KxKn6Jc?8N= z(7Q}*z-~awQ#jme2UbVCxyoSw6E;^BtPaUs*!{4~3_l<8GwgiC&G7RjKPVqN{N(t1 zzXLSa49btl=@WD>%R_#Loe!8De!lznfBF;9eU>r|MK9RrOTA=Zn4sAxIq{`3!%t79 zh9J;=#Grd%K=;8sPG*=0mUon$2)f^9CFt%VVTPZck_|yGwHbDT&-u`2*a=o6DK`;x zw}U5RL(ofk(7kUALR&RKagE4dxZ+O)d`AqjAF-zgJ9KrhxC7;JP`(2Bi_u}{3x0;3 zFZdmHzUFrLsl(6^l=(Nl!=8~NJCT7QB{GmfYt<>ya3Ux422HN3?X1PCqp3vGed|J1A_>teEF};@Dus2UU(jCl$!{; z0~K^u2I%gh6C98{2reV_8Frok?;Vf_=fMnU9&Fb9HyzYYcnD47&%u5~iYHjOg7PBt zexHZXyNp2hpK^f0n4Mwg-v9rngX*4#><&9YVHOGEb36P5shtUqE2MCPnTaQ^cvu+( zv4tCQJgxZ0ZU!_Boi$i1NbQ!kl8chx}G20-KKC9}g$9!5@XymrFk36!>2 z89su>Q^5AKJN)$d{~r>Lps-vg@VJF zpJC@W(3%ErNLuD$WhlhvR#2V?jlm+<{h+e}VfpQ$GQ-6G?4WTc`Bk>2pt{}RCn;s% zDs+G0C2iy91Nhm#o5il z!0;2JZR5;v5p@3)IDSF%BTI8R!&;^X=UrZ zPnuk>KXKM_&h}c)6?UW=HKYc9Dl1Xzh>sp(oj7u1-c(5r;(wM z!>~)ri;+9qOOQcGQ}L7(10$!_e`jc&1oI;_j=^r{cKCVY|NrSA_6uePEl~Wv0G%Jl z&hYcn|Nr1SxIy9!jhw5H;|vyGAb)}K)m-&|)4kRIO=sZ29bX`ICYArDKY-egVxBY8 z#lO`Y@UjZrW)x=l`9z%I=TmWqpP+UaDBXeF_sE*z=VN<@pHGw-CxXiiMumwl)Is|) z!R5(MaQiBn0kY3A9$KzADozCTCo(|o9nc!E!weJuOEdiZFVFB3R9HwSI{) zOaaBy1O5ZH42%u7@|+Am<#`!?K9E0P%fQ)S3#J=eZ2nezto-lHG!b-W)qiK!i+}Qk zSN^RQSqVA|@*!vrO5XuAMz-~Db;!y;`N1pyJF|k-g3eV0tsD7Y&+zkqGs92KgA5Zv z^%$sa2|Aw)bWRy~jf*nm>`l=6fmLh_Auqt^F*^L@kaYOTQ2Em4fpvo|=)TK`P3WD}(f%|J8yciWGzKUn~sm0k4^eUO*XBSID(5ur7JG($Ys#fzIXtt>>7|@Y8{TVXH7`JO(rdA`O~vVc5zKS`Q}e@bkH` z!_Oz6eYDd-YZf7U_y2b@fcNq%GJxju) z=seB`pm{83CPW;9`a0gwcm&l~{tQ1)urvg{Sj?~!Tt~<=?0m5t8lMLhCxYq_P@f!p z{~2g4S~SB?Q2f1NclZgaPhZJ9fai2T>&>1TJN$g7@9^_%Bg4c4j1E5!vO4@cBmLl2r4s%H3knt@?Mwxj99*UF4P zPlNVpt26%e=4=Rh9Sl9MESw3n$81BkquE5zUDVp3`-MSg=G%kzw1L--nm(QmSvwC} zTmOieb7HCy!<3iZ4nIL-N1(Ni8jKuWp!FZ1vszv-Fl+(sQvj{q0j7Y0Sm4{s2;B_0&gEeUNd%>@cF3KTpt~X0 zGBZp8nFF#LG^PZ)Qx>N5RGuNsL)aPhY>%rzb{(O{P~bs zUJEqF@|0PA6}bFf>|^;doda@aUv-1+i^J@eFAlp~zA$Il`JnoM?Stk9TMy9MRda`( zptHU~VhW56wi;N{9LTSnpt=uq{)(i-&l8}#uRv#7g6aU!cq*v;f6NB%FTm^g`=D~A zAqaFIyarc8(2LWIJHhq&c}7Uz!BJ`Ai`NW4J3w{(dxoD6l-VXe5QeNd1D$;U8arw< zg0v|?{RvQe0#x>a&KsB^$}k1A?*Vj%3v9hyff2)$C!qaR;-LFM9e+Mzcl`OdnH5oA zZHBsMJHyWmkb8<5A@x)_l6&?;-E)}Xr#lzJ6j1zXEM%Cd(0It^L2!dD1M30X2jLC2 zpnL2%0vSH$FfoLH&Y%Ic2|1V;w!C0=`1x$Q!_TLndv2FI{Cu+6sq!RfPya!siQv0t zLH*qM3_l;ucKG>tzQfN>Xgh`hRNpp(?u5pj2LCs+T>O(Su<~!U;K~Q;3_l-2&*}lS zK|uGGLB_%YSN_QlSoy!11>Amlp^hl4otPM=fcP&#=Ws|f`~>c=IT%7feFD&3i=K@P6TJi-euB(84LbXcQDNe1cZQ$Z zpgP!_;U_mgs7_(nc^Y)5?|cx=@FDx4@wH0i97s!)Qr?tHio8KbB3Q9 z{0%`bia~9vhM*VaAe!L=$3f+ZptFX+dCQsM=QU1-DOkfC6lTH^T{J+Ve8}{BI9BM+Mpj291dbgU5${g7PD{ z4a|+!1{Qbt3F;ri<4C%}7PdxfJ|n{vQ2c`WBO0h};0xe3uspO447zhupdsj$H?$4x z4{ifr@N!g{_)44M=POVf7<4``^xP468yK`VhZ!kOm>qsT2i?2P?(p*gXs$zANp9jm%uyX|ygDEJUL31jvnB`Y-GctVSIM_7{wny+$w8PKG@eV&9=`;L% zY|QZU0rYO^gB%P~9)j|Ly2H=Mpu8;X@bkbw(3lXzPH^65ci8zr`G75~zCw2I|7K9% zlyfC$?H9Q3D$lU<5om5goZ;saX@;Lq5%%!Za)4h9AR&&t(1Ky7XYM)_+Xvmb-*fCbf2pm`fm`a%oKTYvsT z`ti{4g!xg8fk6Zw57G`lLGG*m_kTL5|I6UWU?~T>_W;yK1KqXF?eLT5|NrTd3=AUA z)E$04Rd)CZIu8ikFPC@t`4FoAg)`&C|Jn>c|LZgS{BO(v9(Mw*m3z_bX!$@K5x(F) zkF*15jolXT8UM@;K^lw<;59#gt36l#Z-(}*nL&MPp_PBDg;zc>XW01=bbgyTXbhQC zi?!Ba@>6#3exwT=2UWo57;%8+DUkQ+Fhlm~fZ8#UTK}el>JgCtUV`>$gZ3)99{{yk zHgGhuO$7D#A2c&f1eI5yw$DRxhMlmpqd@UpWB_R+%u@b09WXcJNyL8i97s^hw5Qa{5KuczA!I=(4Un4O^1}J!7Kmd2d(_i3>hEz?+hBV zWdV(Y?0m@1@Dns<{#cq}=M#B`olk`sem(>BbJ-nsg7WPv&{^N0a#bEYo@Dm7+GXW` zXUN_LpbK7;OG1*Zjdhn%bpnadgka`g`ZUic?Pcblr zK<0|VR{qHkUHShoBrSpFlR3{(!l%mS4mu)Yx3oz2dc56mHD8pxesF>!~Tpt}TKfzGT1?KfM_ z@Kb^JfUN>&gY8Su+NW@apDzwGS%UVegVuV$!Vg>r2|N6J3A&dDbnYtXtW|b~pD&%A zEME#U?92eggRldrpJM_kH_+l5mQL6~`+pdIYOsRNas{=?P}RZb*+KmxXxrj}u*1)K zA%-cS_0OQPOe2wDq9&-_0NTF~YHR2-fbJXK3LbY6XV@tYifhpRRd#TB02dbo#S^Hl zD(&#|nYhDG(7tofxY>)x3=?7Fte|-zZ1Mg=+0hadh7ZIYb|TNe!`efz{t2jF2hCGI zXl4ZW?Lg%{s9(pb&oBklZUnV0p6WaNJm}0-Wrm+#ypXm$=+2Lq@ksuYhx$9(;V0;9J;(Ip8`4I9 zrtR?a38=mVoeh!9G!fJm{2$El^M5#In-G*XUo3XAd?C-U^Cf7Ht-Qld@H~qwgAiz* zFN1->6g1BVnj?I`4+=<<41Zdn4 zybg|8eif+PSOXf51MMeP2e%1d_cAktfWm3H{=exbKzpPQYEJ~MvFiY>Wth$I6O`9L z=OrG~{Wl%7{us1o;6*>f&xey4e%k5(o9@8g5OftL2O2wpj(?hi8Cj155?wVbm-arLU);V0-WGFW~F_1|8B&IVr(9nXN~^Z(Aw zmNKBU2-+JejwuJu5Jw}J0 zx~vXAbvPY~2@z-bsmsdnQ-_n`r#3IcPc1}^ND2U;Vo$qVX}a=iwv`2fxFJ!48wS|)<}vds)XAGS06{HgnIx&vcF&;*@-(;rkb z{Crr?@Ni|?E$ObK>dIqkQ#Q# zIn$4r9ey?nGE4!DA%ND5f!58q=z{VmT7LrROzxM=tP@{?+V#*eZ_s!js6GYtlR;x& z;C7}qXnj27TtxSXM17;RPABmq~CkF?_51=_)O+BBLKG1Kl{qM~16E?o`5OnrEsD4H3=h~|Nn+_W<0PP_J?fV7YH3+IxI+%WJ z2hBNx@)p?r%nU!*tNsI*mmqO)ea7tY^VMXBpInSw-42Y9cHOJlpmYyPgP{Bjsw1>q_ zmUIRkw<6R|o2^4yJM9tM5O1e})_(9afcnwkeX*di9R|kqc?=N>e2f+bdI~ZN{Wuxa z&NU3v_O#IjB523{m@Xy~9rq0f(PlJm5V0nv0S1HOI!zSuYkd z{0tXnnDSsb1NiRb>PJXM*5RxF@aEZa;(Wf_Z|EAB9`#1do=+2S`hKZoI zGKa0hPYz#(kD#@8Cqa7_52{WCo#g_$)9fUBLl9`+$II^wKOcT}`1$BNXl{f-$XTZ$ zNQJQ>h?S|~5^KVvPs`XFF0na0`_%dS|MXX&@T-T+D}wvppgRwKL(bKB3R<&`b~l=n zZbK04+|eif3_tl)|4j$Y&4TwJOa`s_=U4^0M*+--o=F5d7Z6l-y$0<)g5FgKo5Sbe zW%#Hh!w~WW)c&h>0G|gBx~J*{Xm8&^)rp{c3SZo3_;~^}mIfLJf6VX`bcguE#|}Ra z={5vCS`9gG?D2Yrov&2>O@CeP@bgu*!_SxgpnGW?em+|5u=DYHhn*nvvjrV~zK(|O z6}Zmu6Lg0aY`^Ypm4DM;g4_@d+EbJH1GHzCqmf}EXio`j-!C})bs0V$1oc(o9e#3v z(#&~CJicgVvwRMkZ*O+9*T3o{~a zp0PmU#`^dF=`TR{mp^9!@7o65%lQ(tZ(G{&=PJ+|8AsEJp!4TXu{8v}VrTs61zJxd z%(T-Bw2nrcX(vRD*+kHOQ!S>3An+WpJZOJ6Xg(g?KA8l%2N!$~B&aVBn$vZ6_zB9J z@Of!azaMnp3aGvQ95hem@bd-uZWW~UBCt7lXDsVQkmumV8GnNO@JihAC#X&LQW~@` zmf`1W&>R(Ly@)z=4qh9&UL+bi2OrP06Qag!;%j5ZpWyW(=8QjISu_58X%AiZ06L2U zHV3cFIq{|@=*$a{TS0Dyu6sb9g9q&+a>ks42dy!AyBu==;~RU(Ju9z3ZEd{OnzR;b%`R?`)75Xv_*!R)E?u;4}}qYY}uu0O-6+(EOsh!%xs19iTBO zQ2R{_)aI54-Phsp^Ody2PtYByNsJCZwQHGXJ1}y0GxBnF`+)KkKST|<%XISxjyZVg6;pa0RyN_cx7X}ktBUjsh> zMjkX@_hUPV&(X;6@x}7_Qs8w%@(kep9xvp<>oLGj@O`ZL{L8y)R$rg_1T%_SAp1|c~nrH z#K6eejnZz1_A5bZKyAo}RH*+Rg8B-ey(G$@c_r-iA8f7%G!FJqnBnImafY9dr5S!c zk!Se%6qMFLeIZbK0L_Vk&Q%26Z39~40-F2LX7~vj?*fIfr4Yjukh?)+9H9Ah*jlm% z1_sD@89#J9$r*I!4g+W&1TGF9PXf&^Dm(lHjjw~}eL>@aXzg9B<7kf^EfM2INb@Mj zYZO80z?$LbBYTFQkDVEQKIv!J`4m+4fbIYXe}+~Fsv zUxe--P~LjLe!vzqp3hLJxd+sr1NY078GarIm2IGLTz`h2pfR5Zpfi|)LF;!>*EJGd z1}TzN22Icer44y#+Q420P0++r26@Q-n+_Ul0`=)Wgh0z6#=%(zf%cm}WaiX*#7(#j zPOUO1>L=u!!@*bvJvC0!FBivDw8xo`%2oubH)=m9M!>d#-On~ z(0w=_)(t@~K=lQ{ z1saP1t%U>m6;x(`%EMQnH6hFlKQ)odDo{P1%m6+c8&nRxILtJ$#Q*XMdqL$GsH_InVIcSTGyHr2Dr@~Q&HE4CX8`gi`dA>yOwd>$Xzw&={nG^X#XK-tbU2~Kk(Wa zkXy7^LFZ^6uw|%RWdj|XhK|)E_9w&ZRdI%&12I= zH&zcCD+8_nWq0@qp6_ON_z9Yaf{%&ODgE|*M@_#q-%-dS-rM)1BUz1MUc2F+1&f!4VF zgs(pXt*>H-?3shCZ}D3B|1e|@58PH@clZg~3j`{kLF*PE>z$C)fc7@?LiB^`V^BQ~ z-apaUXaiaY2NL4|t!aVHwL;hFg3fdWojv<_G2_IQpfmRyg(kiZiIx`l+f?kg^{X-_Q6Rem)m=0N;zo(0I`1fp~*0 zsQm;Q8(?7s-7(8B@xM63PuP4fXuT3F?St2ZJa(`IoeTb;`H;;6;RajKzBy=l2;TFJ z9zL*oHx88cK;s+S4nGwbL2JBWYk&~p1YchWY6BpxV+DmVXiW?9Tr#=y-yNWRqg0yz zJ}>!iI;af@8p{H?2R#3sscnH;ry|xpVyjahD>M9j0vewIwR1r8;L;9|F;R2KxC`>Q z6R7V2DpNr9JZO&|vK*-W0cwYU+6tidBdEOq8jA#_$yK0s256lxXzdTE{S7TUKz$3) z7#RAzg*_;YKy5B@ho2stpm9P_8-wdLxLpNmV}a+(89u%Rt;Ghdr2?&62CvHh7}QRK&Cy@^`hPkoor2qA><&M7sxnLg zt?>k@2Zt+YEE0Vl9l8b@Tl+SaRec-t&kb8o`Wev79OwjZPnnOS?Z$SM(xO+hBpFnQ8K3@v9-vGG`bd&&{ zGvM$Oqz7~_EzIs}705b$P&){euR!Cpx=hghU*NT~4nIL_-9h8aAoqdSAT0#-!x=t; z#(N=cd+6Ch(%|*=KlAt?Yg$14K9C-enV@x9ptCMv_9m!++HFXEKUiM|x)vU^zUMJN z19;6W=nNG|f7#*ZLuH1akJK4{g3crY?SZKQrBP{ypWuBEpz)u_4xshHKVK|numt5% z&>k1$^K{_z`OaMM`;s1m?qtqp`1v%S;paop{3~dFE*-RIsA1A8&|V(UJpXZqpAVW@ z;P(XSsxVA>1zK|hy4NiEfb9eC23y!#@t4Yw{r|7p8GeHHRe;7iU-mQn1l`{Z+V2dW zPh{kn__~+@vPZofy3hVI!%lC|zPRrU&^bqqiLdJ!es+WQT7%A01fBbQo#E%p>kioO zPVxuOyS)bA0|J_Rz6_a1UJ2SCDabt$bjB+9yy5c^hOMAB-~)Hi9y#WTkDFO0E>&Wf@&aUDG~^x-&{)>PW|oN)1OHD4pF7ULum!ZQ z=)W`Sng@^?@Ho|U&|D(p&ljLQz|8CuLG6FoK9bwY3{$}7f$qnK-p5o8GS{8~w8nbN z1AB*`56r>+C=rml$IR>#LG$j9o;&=s0L=p!L)95W)Xf9UrGfU9$2np!HUu^>m;)j}@T1B0%k- zcn9#EwmyswKRMqzOv_Mr~m)OLH816Ffy2d@9tq{pZNH( z!_OzrL3gP!t^&;=g4TP-zxg*E6i#uVHRqsvZa5+HvY@sYto^nYw67B+2P(Tj<3fs{ z`*<9Fg4W!F)UD!V2zkj3?lXJJxEWP*;eh5`8OTZHvyGPps_Yk zT!7YOdhv31b1-th29-&#v_WUtGlI?!fw&8FMm=auTAlGH=&scl>W<*~_!st&v-m*v zg53dXbAtLojGV8*?qGNL`4m)NTRZ-IXb*7*GxYA@Su)Uj*0mjfz67074>}`2+VST@ zdB>j*oEd*UbZ7jzhL>T=OLx#cmkmLTwVbneXMxIh`Bg7KQyGYQHwkDHk$J`8sF`6%4s zXC7$$*%+$c7*jpy-a*ir0Yv2&&>RHl985y_1vEFx$^hQW1Dfvzjs1h#=w#;?d(!gD z3Q&Fl-J8(NH1Tn;!%xt8ouK*$mR}~n2CZ2{4L492fci3^Iu4YEQ1XpEWL*NN4hEeS z4ywy>=9|UPe6yV4=PS@U4A8oU)u6L?8GeH1EI?+Hly6o$`~=kzd@E7^Z;I zKXQI~4od$d)o zOQF;&Sn>(zy!R6f3}$52D}?jOW#oE=P(C^NYG~&Zl|hnEn25+HB53(U8CO1m?em1T zmBDjsp!qRqpO^_`4!Ays)Kh|)pg2U@_X!(sRA%@I+9L&Ot8hT?0|A`@3)-`P0(6Ec z%Df?B%nUTA1sY?!?(=^-2Lt0r@Z1n+EC$&O&^?wQGeGz2Lie2itwxvuI`a#3k0to5 zRC|V>pn27Y_Mo~6p$6nG(AnXjeIc;E255g8xJ?B*8v#7m%kc3mXiNw+cBJg^(^HXQ zBB=fFikso5Dl6y?0fvuH*um|`3*a^lXg>$23V!SAoX1K;xyLHVw=j_dxA3(3~-Jya}|v2DA?Y*^ltKRc?l#$o)3h`YEjA zDWEt7ji*EBS0xp}`v<`Lr%~ouLGjJZxN0&t!<2_0Hh7;qWUUjdkHw-0=~sfz(*%wG zqs*N9}uO9u6CL3xHjmcx%hR>BWF4$dsU3eFdAum$xoVEH%^6hENz zFQ8`(fbz2jC&N$B9%2xUJdXPibmj!8@9quC&rBb6LHP+Z#|zERq?iR7GkqWo*((Cd z+aSBJ*$H+ls2>7KbD%v!{E&W{F9$;i$P7?_0JJ_8G-tuh(GbKav%rsmMIx?;y&>ow zGmq8^}o}1yPHbdIH9A1~pAUa$1>?~e}w0YSdc~|K&q|IBacwrVu zeUD-Ptn(m!hP|`68PevRV`TW4&DcAuL6*ZWK~};KWB{ zk@jpM%>#1^9=OH9(GbMI$oU#R4~#U|`T%^E7sF1_S|ZSWV^2Z-4p4jD+TkZ??>qR+ zx^mEYqD&J(dsATjjGyw*GyOpGk zp!ptXKb_g(=Tp!*P0%~2LH!r!ryl0%;e4~ve-<$^J0}}F0n>T@cqmQG%K_Jg)fcAiZ z`Wxm9JMrZgcz*+wH$ZI=7P?ML#hLBfbu2@d3mxIfxMjVuoG17!^hfW8H7Q5wTP_;H9%`u z8JP;f!zyGtN=5M}K9ChJg(Ak%QEB{stVV(Pb zq6|4}4?I>6TQdSWyC)h^mxIp+P%$#>z69N6ZH+i1@l`YEd}VN3 zW9xsII5U$a=*|Vu8MUBsTJSzxBstL8-JpKpb9ING&p_uTz|O2_2dzOuJ&Or+)&TPP zMzAxO9>_P?zF=mue8KDl*;gcg!1jT9gDq%ZeFr1t>=4jB^q@XBXuJS4|6~v9<2f=| z{;dvL`6oYc<^RKwvqNF?w6L|=MsNR52d}9Cog)dl^82U|aJ>;kxt7GKANeuz}7v1hr>D;fc2He6I|ibtZV$ov)XH z)jde-&S7;UXzT`dMjgJnYsQ8k(A;$c2g4Lt-yS@!MPTk4eoh^U_H3k+J&#DW2TwSM zVhd*q$E-ko4O)y%b%N&C(Z;6G*GaAf@0G_~CwZHH@Qh6fy+IqB0*x1e&#^^}$->hh zjoX3wte`V?5$(WiR?K$bdC*`=Vh(x7rn8g!o|Blz5y z2_UzE_85ciu;X|5sR44^LMHIp#Go->$lmydAke;g(B2!+x{jCr3_m$p8iGLg9)j+M zsFwzk$-2 zDEF0+81Bg+zd*x16jW}2&R5}w-fKcZxT~UvI~ChCsxtW7H7=kv&uHzMJ<^bNO|TTA zT@w!)j}``b&W+c=;_&n$>~ z_R436pWu5m1s#6Ad<`0B=6nr0#|u;!V5oiX@RM^P!^D@*8Gdqzg4e=qeevGm=gZ%q zHRK0u85)~xo`CM~e(wO52d!xUuRC7M`13#L4%5YsKOZf3{P{SU2ef{EgC^*Flzv9Y z*&CA?f35`Izs3x`e~o!3xL$D8ocMA!@zmTCxM!E!!};w#XZ(+)phzjpZf>bS#C&^_89zk}8aa)8$6h|ib$ zU(fjSe>3Dx(MQdWKOZ}DPkfcl`155x9lZT|3Qq+;AT1hRaYltcJQ_J(3%4L)~zn z@#o9Oj6YvIXZ#6TiwJf@HN(%B^$ehUpSOU{0RWxVgL3W+NDg!+5$L|`W{00IL3dq4 z&v^1;Wta#)zvME*&sU%{3QeC8|No0W|LySe*>{JZPuDyAe6-o&=Zoi%az_hvrf@#P zPfbyWpA4)HKVKwsPW-RW`18Lp<4@2%MxeeX=>93#UN7+c;$lzB7ta}XzDQ@C$nf#J z&4c+3wlAz5A^QNIBhJ0WD8E4aeL?$&p=;dczWhHObdT~&Q2c}L=80zb>B$N`Cn+9E zCqwCUhMzC88GgQuclh}VbdFHE!_U{*4nINnH-OHLdj+~vIT)JP#27-rXI+5unl?PI zP2d3KHPAT|%8Wn3=OuyW+tnF=K2Uc2`B2^QCzC=$(4%a~{k)I!8FtPSLdt8P`5w@D zEZGh_ALl!O&(Z+rHEU>ILtB^EFZ6HvOVD{2*3i5Lx}OJhUXnAz&;P=V;B$+>N3)5qzC+XPZ^oZ5|AW>uGW~oR3_ULi zv&z5<=0``Y0r=seZe(GEY~fbLA- zXZV@G$kPov1BQ{2tNVpEXdR`)Po`SV*#^S@roVmf@bevLEhOj+Oi-BxI=cvzX89d{ zuI1(HUdhPt^QE@qPn0rC7^%z>X8@n)`5H8)Wk3eTgD*(d)04?2H{@#lYbM(~{?4?%afGRv=mn#;4rA>$9o`&CFzQ%Gw;K>H7q2(W{i>kxUr^n_3_8cPAqdnjxDL955@UQHbRQfq%6b0q^9(@enu5-w1l=zSx?{wh z;U{P489js*x~1Mq;b>-pz~E0Gff2DUGhJg z;V0;h9Z=t$3)H7YKd0rfljVcvQ#SDVVr$5GN#JwXL3eqA=8xqWc4~m`2bFi&2|ADT z#bQQF*qH=>t9@7gZ-(3t2b#YCttkbqX9o4dL3=Yndo-6lg{;r~pUh~9SbvVtH<;QE zVPgNLgXdCkv>i%Cpk+9yo`Rm)^Hvnnc4&dgA+;SqWj^RGfm#tn+o6*Wt?j@FE$2tu z4&Z%(pf%N?^$&#ZQ28T*IKPMYDbo2p1ny9IAwv53J-0=$wH-*jZwycUbQt6pa2bMB zKhdy_JVz9NI^Qjfna+)&>HHK-4k?}MfaDk(f({EK()oE_v~0FPDbgqakoi`7{x{RwK=+OYwWuG4tsLMvf>L;w;UojNJig94l zRV=}<0`)yOS7O_rN6I-)NuaeO+zdYl&Dp|4t~X&6W|#unrv%zV`Uq{k$rsR>?MUlQ zI6!ycT{MBLHv!%E1ip&_b-fAbt_)6Q#Cns*LZJE`b-fAbEL6~4uAs5-m!NyRKzqQ% z8GcgdE>RNO4$yUzpmQcba}$)Ds}DO%L++4$xXRgt`OF@z>z@sqtC%45VFA*hZ*9UlYTB@2!>Zik&5YX8*9iZ@6c<~9e zA0Kv4`Ge-;HZMSH6!{x$!FR}k&fU~!0N*?H0(6f&XrGKRXbl^~1dd4kiJ&nQ@EI7O zJ9I(!Y>PYmT(|1qbkH3ND0|{z>jaq@_C921*bB=u511YHK4f>;%b=ks_rjQI;)8yM zy)Pd#Li{4AH}RD{=x*kQpjV)=8*?PTfY$dz?^Xw$;o8C5aET+~!6%R#LFZ9}*4TsG z56fQ(@-SN z57;m?G~1xei9z?qgVN4pb|g0`Ga}ri&hQiLCT)hF9l;GjFQP$XZ4E)7Gg{zoGG_P* zb`vN)f!rj|06t$1biXC%1H_rMV0VGerxgaB0e1*|?+7^UfcWeOY(ee=-L(wb>yEsy z9)52HbiF>f90Zlc%p9w<1Q{lR*1Lhu5`x|32wJ}jPrsnCOHkUjXZZQbn&Btt{C&_E zAt>Lz1g)ttXZQ(9+o1gVK>2_zJbi=qqk!_P^Z{G&83Ec1KQlo4vq1Yupm&9KFhKJx zmUMn_C8*p&UbhT7!%A%B-)ixd4?y7qIx8TV8Ga64wgAJFC-M$IJ2V`Aa=c{(-wOx2 za~yO>@xye7pO3N~euB=T$^@;EXEdMq5_E@mFvHJG(EUoF_HsDG&z0#7K`%Em?92p} z#h|;Nw=?VnkG&t%oA?rR&PP1MPw;sT;*fD$(E3PTmVeV9%RBsh&F=6Md{!%{Z6l79 z79KNBd<_aaXNI3z84W?Nx*2wQf$kyeXV?i^7Y%Bs9{c=%I_Q4l_v{Wo-*G$qd@Jv; z^9|@8Bha}C&^v*^=if>*`~%$(q}$*`60;5yHk;U}?WBskAF>Q4ma$qdk)A^f2By2DS< zI&jc=|BtmDetLn^j>pRX&X9Ae;qF8(=h+?hzWmHM@j*SqUJQ4_%5G4)hnDHIaHj$; zcQP~l1(hkF@O;4R@E277Jg{f@i|)=9baLmn6`;I`6rQlU6Y0zra65q8;V0 z6G8Rk3#78+1t<+zgX=R$8_S;IC(d$2{(vpK&POUgz-662_-yD49H2BH%{EE#1|t9WAv?ogP?$etclgVo zktl~I|MLMm!(Wj82kZ`iITdy(R{97%EGL`^3fAm2!6TG~X=SQ5k z3c3RhG*-#bc)$j9t{+$}=#CZ8IS)Lb@e&R#(4FQ&{Gk08ko(IYHZx7+1DOE|cTn4p zr6Gu`k>Ml5!OmIx{{Np2G7q+=>;XS$y?Ud~-|E1XfARxX{%?lvJ48O05LBjv&Vd4* z(~We#=~q66DWG$fKx@6h?v!`<33jJb1Pu(5hQKzz`hBcL;>5*Q{jG#s=6-C@iLy1SbJ($@s-Q33gb@nGkywIF{8JN#sL z!jKQzcK`|-(3;ejpt}%3>kmQaE`iRc0i7=hxoZ%7k2WZ6y#U>vDazRmI&%dy_XfJF z`GInS?Tf>XmKux->WK9m}e6;8P|BHj} z>w%oP$vp8fnRkal zW59eXLFcSI)Mxnl2zn0`=?Ky!YN z-5GX1%y#(sDBt1dRtAPC91IK}LFc+;aWjN~&Rt|+bok3~BQcI6kzpdJKgr1I@K@yocKG=y-QnlsWTuJmy4@dIuLm>y)U0R-dbyfmC-}VC_0anKrvAj2(F{Mq^?W?! zo&ag4f8aX!g}cK}Q2qLfnNy3C^OTfkEtfR-+!j!q5;U)?4XHPufYyBSg3fYh0I%_&DjJ3dmitt?ZEXjG%EY4pGi-4n_w{(7AV@x*ybT1D)#%vKw?)Bj~KJ zY|!0xpmo%seNfObvHPI2D?odZwH}A`~;s*=_V}_p(%^7|! zVPKd7J}(-ScDNyF>yf#`Pj%4PB`6;;Fnr_!-3tgh(+p)!8F3a7sB8tf6YfuDw0Ka4 z`cs|ZC+Lhg&{=VdsvCkHGc^P$gW>@+J_0)H1r!gw4nIM84cu>h%wP#S^8uv|4eMip z$|!Y)pN~LyI)m;#1FbOz-OUcV-_)DoC#dfWPUF%HKS5;{D6NC`=79EmGB7kuLhggU zhEW*4SF^JXdDgX zM@9!r4-N)1a6JuLo1p9fzTX)meON=yL^=!a5!B49Z2zW%?ivHH0|4FUCd$>#!RoLR zls_IaGlXE6%?^)~3ml;SnK9ICq%-fBY9V=JAI!b%4nH|XIlDC!873;QI{aj0h1@Us z*x%u&_wT>c7celGf%_kb= z&Y*Sz|H{AB0xLmj|A9Q{E>+MS7V?mD1{X6=

eV#JS+%r|$uR#HH}!)2nobpD!OXO?(B~&jCG?;XmvS%jUB-FPa%AJ^-B` zV0^$9R40PhrGV;0e`wz@7~Hnoz`Kx@pOGIMCjfWjPfjC$ z`Ti^aJ7a0*Y-ZT|a67}^N4pvJKHkr;_sL;~y-$xb?0vD=ap#NE3_D*ecij2nJj2cx zs~vZ~xXiHg#d^n`FRnA}e6iVa=Zo76J6~*f-1*`@!_JrY9d^FD?XdIpb%&jAE<5ae zd){H^yVDLk9~^hs`|z;C-bec#_CDV2u=mM!hrLfXJM0CWzx6bmaqp9S#=Vb=8TURa zXWaX+nsM)gdd9u)f*E(d4QJf>CYo{Q>v+bUuaX&ezD#G_`F}CP&;QGzdvc)n0fP2` zya;#r30nUHF6%fMKAsX}2mzT78b<()>4Dn);Io|F9e%>@?Bn2M__&H6NgZ_T0F)oV zc?Gm*L?5!Jr;8W5r-zw!A_p%^H)sqx12ldEDnmeZ;cRF*0*d?j3_l-0&k1vCZwPv% z&#)5|pP;@1C_bM`GyGi63c0HWbPfh6ojlTa*!fi2;pY?3S;d?z-LF9VSwLr(O=tM| zV6wx{htnN?HZwK^&1C&I9kjOyU0)YtLr`}O*X&n|Stoiy@0kYgCF^JS`2c$6a5Gaw zP$x*gKImL?(0y1AKSB0_?$HJ9J$umX@bh82!%t9s1R56syOo>aXAQ`$><&Ml=sWy; z3QC8ddS4i#*P$|H&jWXcy|0{ECwlR+bia~k_=$d=(qZO?plnt|*$=W4=2!Tcd&Lev zAC^1(RAy-iN&wks54lJ1fxE+A&|PDSm05cjITYm>7#+alpbU%*dqHhD&^bKtJOGWq z37|Y+?eG(HW;I;Snc*iW4b+3~(uSTb4$3zmdD#B%JW!bwe8BcWaD(jwXUDw{-5vKn z@^;+&*xzw4M%%QR;UZ|94phE@>gYGj99plL7IZEV_>N?8hMk}@j6r!ACJw%fTbyC%1969)|C<@WYm)vqvtIm@FS7D)wdl$h z$t)8=?I~DW7-Z*5W)3ZI8VB9G2)b_?)D{HQ5#YKSv`3fWV-G0Zg7%Jq?i*Hj`1u-i zpV4EMiJ&uJU(aXw$?=e3;{WLkKmUXFeNG3Jbq$v|K;zxeH2uGy;phL!3_o9i?na%= z@biB=!%xs%4hpQGaW&?N53Cz(LFZ6Duy3#hr6Eun2lahkbc4)d*ucSPI1#jOZUu8g z5a_&{2iXokLH9^J0;RKVho3A<|4j$QBa1A!Ox(cX$S{#Zkfj?GX7K!#49#2V3_l+v zJNyKVoiX(`1U+VJ2s*(4I)jfx>oNsus2eaW4_kjnWUdKc3 zFb1tv1m9s14p|Ecsuv#UAFzFSm~kSwF3>(;3+f-i#>6^6=k_!jg8MDtK0Z>L0d(Iq zs6B9D$-n8Kvko~tI)Yv>E+_(>WimVH-*oVqo}vsN89;Xeh&%iQ)z6@`2TFr4q45Vw zw|}ccSN_QlS^2-26_N%HgVKQL%D>fOD_<;TnFt!khqYN>f$MGgRiHaGyd4=PzLsbB z>BZ^r^E5+4&>LoMEpOg4v$AV>W_vMmzXsh?@)C5f6{t)D-O&k356J0+k0Au)M$n#I z(D~pDj0_VP4zNvh`~QD>0|SFO=pO2iOa4v&`TxK86LW{3pnM1F1OK1T@Do%fgYKz^ zkEMaq4yc@lrmI)Vtl;zpy3_u}Y=)n(GzCsWhnXjW(hfKcIXBq8=m(7nHUxpw&}3K| zGMWfFBgq3auMRq&6Ixb)?+l;p@UwWyzv)ku@uZ(@X!^-#_z6#c6B~jSBc&f_Z0QGd zZvnJV_c|FV{iHMegr%!j(V#t{i1hTp_<${FtO=BEKxqloM~9U!@bm*}&w|DYk=wJu z4nH4fwjR2W%A-81fVt z)Z`c$)a4$|X4uQXkT#EjA${HhZ-&1wyBT(Z#`Iq?Gfnhjtlb0(D@KV1Kg9%wJco%4 zyb3V2&J2Gas2{LpxTBc&>M$c%twSS&FWf9^hQF_@9e%#9cG&rPHN#GDevW1UonQL% zl`}*=*ew!`ehdkWd5#kqc;R}r8UDWXX4nauX9e4zz>uftz>vqlpeDz_pf2~on_(~9 z9m))UL1#^Y+yNQ~wx0NB|@1QUTg*SL!QW-o}8w9Qgl_B>kfyY-sbN`@r7pQL!onH-G{BJtw z3=5S01!9bNCn!8X{q+~@4m&v+8H8TgGfjMH&twT2*Y09q*x=P`1fEv~&k+-tSJhx{ zxWw^*ym?jd7zk*N7|VQ<>S9p1B8?X_GhT$vYryV+0*z_H!u2(?1N@%I*PwOX@}Rxm z3_n5lN5c9C;4}(4zrB`oHn^WJ47vLod}cE2u4re*ix0RN_CDli*b7Q$kHs1GK9OeF z`&1rOUO4OprLjli4tpO9JM4YJ@38kNx5HlW9mn1bJD)l;?0w?Su=lYy!(Q+j4r_*; zkBk}iJ~U_8`@ouEFQ`5D)Y@S$Gl#0&18;}DPs|P?iIYFaOtO*!f7AVednAhP@B88TO*)9q2vR(6wE#a010KsIU5} znF(}W(FBf-MiXBIL;H5&3_n5h$y%Vk;(-UBKzsOKGc!%>VPKfhbI@qw8)t@}YnU5? z-ncXTd~MC}6Ex3`JU{SK9NHH}o^Mn?VEeKevR(yzHVo2yBj~;)aQzLPYXrA%aK!zx zMX>aXv_1^B&J!(PfyO>S`RXMz^F-JfBxp}JXb;D$!%%-)8czh3)u49$3(%hLV1}P? ze}^;teC>?nZ*Qo-{XyakKS66HKyzmQ?HRy*r;{*$Bh8n9%DR`ZH4(~?`Bkw0LHC(L z+vTwR8*qOML-R9IzRg$!TC*dsg}lcDlcYCk12Oaz_H z1WqTQxfk&GeuK?}=7Tn%v&%taBA_|w|43>4Z#BzGP&)&3<`npBLC}5Epz=?VVIt`M z8ql~W2dEreK3@vd#^Pk;x1f0j-w-g$-z(zytKPG0qGZLG5TzKO>XBA&8Ta;isl{Ll7q`!%ulmhM(|q9eUm% zXl?{F&iLy8|LLH6$R65*=GGx&R4YK|mWzYdQX%HtKx*%U)I!HlL1VL^@C2(B##DO= zq?VuI=K_#f{Fw5mK=RyBd2USk7s`wiVRN#ex&0HMxe(BP08sox&vtkL>gzzxe%kT? zyte_#z0C5fQ15ww&M$z*W7Qpgt^wH(ol5|n&j4x{XfQHtd7a7`mg5wi3cL8djgU-Dd zX873w@*imIp5Ngor*^|6(EW?BH59P?iflh9EI?@qR+fSKZs0Tq3U|;rBeT4g1_OiH zL(sWe;P6Md1%5_VGv~z@%q$aOV|=iC3m*qF?0gc=u=8m&!_H^%3_G8L)(wFAD!~pr zL1Ukwvob*UJiHNR{P|j(@#o8W4olGa6aTpxf4*eqnE0QW@#iaM#-A_Q8A0p0f?jen z{(Qym`12*VBWT=pLpG!N#Mkc`erB^Z1ik*u@Uxq*G3fPc#+|Q0_X@se+}X{*Fd^I1 zc;f5d3_rUW8-iZ{2c6f!`17SY2s{3S)uG^XUP1X4G{**--(%!_4Zc?p)bCVw{K-+7 z`J)rG_Yrijpfux8@H~$^RY$^ZZ2PeFJ1sXP4qf1ly!!+H7YI)C~ZCj^%HM9{8Z39V5?x*U<*1k>i>C$pL)jsr@shy*!kc* zIIWsJF?RU*|2V_X|EC##J`i^N`B2>P=cD5eKOdiV_$jsU-}D#v9e#q&3IwSGnf-r1 z!_WVq`yU^(O?6fZY#r7ig>;G-d%B*LYFSG4aJ@hMyTc&~Xh= zpR^m&2Yr#uHW4yT0hI%db%4%R0-wnbxpVG+HN(&U^$b51I1kvqU}m29z_`H{)Ng%Y z4juQfZm@k(4Q)@_OJW=@oI;b7~tK=8d)6z^oDd^dw16d5LNfr^9km$bvrxBQUxORtz2etIi1 zOw3|s_~^yR+x>=FepL@6?`tnco-R;+0*!Bg))0c~YF+5vF7R{r7#e~gX96SI(V(^f zD4l@X%b<3Xccc6d(Ab?0Bg03{gWa>T85llfGwMwQ&9AIxZ3ud8&hYb%vBS^T<_qQPoQ;YFF|XlpyQ0Mv>ASa*5iQsE1>&II7p)vl) zA|FtDAE_S&?XO^qgD0SI9MC*JBg0mZe?a%G$%E>3G6NrTR92kjqy%s3I$ zj)SeMYXjAxpt=B5b~}Uaz-9RPLfOd@bnnLs(EeL>hn=9d4k!#k=bVGuI}kR*Pc2Xz z1+|0)6@beivG|x1eOa!gB z&0uW^0bj-497O1SzwE#`xG)t!4N(9pn~Jd*+oqb3@nO zy4-`TUjw;^k&*MYxF0BNk>UfkFA_92!|w2tg%h;S0X{eQ0lt<8G~WYiPlDEzh&%jD z;%x|8%-9f=4RQ-~z7}-u5@^m6G(V0w|I>LTysdc{bT=~_%GwuD+Y#g!P`eYBcEE06 zXZQ&Y7j96Q!T@mxXpRWv4p2J<+V4HY+Yoe^2@)>p3`lo#@uP(cw0#U}tAXw^dIVjI z!~qH)&^f7`;IXD|P}}%#HPYH}(6|9V!%ol~AID$j!W?Gsy~jI2=aqxzRzd3>G=DM{ zzC1o(3N&`D$;cqY!N|$=f`P&OCBMT?4UvW*n7R`T4CX8h3?iWZIIPXd4!Vn$-(e@m zR;EJGIey6F3=f#)wP5Q0L+7}`eSU3*pRjcxpmrW;Z2@d-7IX(M=$u0>(D=L+7j$nLs1AaSyModyD4l@XuAp@^pgr-RyUal4$tn(pkSD?pKSA>qpmWSY zaSZOWJ6eIu&=sKciZs{V}VQsq? ziy0@v*3g0SCCJT>m^rodO8!j;x2Hkr6Vzq{<jz4EDE6bt!`EXXr7_SwQJ}d%&>h{N^aoCJp!O)JzoE?V6P|9MbMG9QpgXf5L zp!K=XwYOf34M7~dr)I&z5q#eZv-~RX{3IxD`5C}-0-*2$%_)KEJW#tD6vtdl3?bk# zcWsBC8VeaFDmyYxR1k%%LttWS2;ztZ?O}5G2^zx#r2$af!pfu9pthqqc&_dzD8GR8 zt03tIt;u@K%%P0H`-nrr1NneK>JjWk{N!2?jncX zN&Pw+vM%5?=JTNHkUNduPX>p#O#gA9V6 znHm=0vh0$ z>L((*8I(>zZe~Ywb1~G-NOLnzOB#Zl85@G${{1^0lrBN(T8ojR`y^{akS8Mp=zfTw zpz;kgkNq;6;V1IkAjVw~&^iEoca1T_&qwAA5WU6@KVRuPfXDDa^ZqaW9e#r1p@EUdA8- zif2%o0M!$q{wt^*18Pfx#*0Ap2Ph4k1eIa@(0B%gnK$Holc)Yj@oWus1M(cuQb;^6 z`1^PI8_@k@pt6J8;U_5lX>*>Mm0imYyR(w{A4g>nD}5h!_Stp|EJfV{XZSFw}C;B;U|dZ zbYz(Lax%kD4o3$|P&)~9f6xmC2GfVj9l-LSe$S)B+!Lpq{XhK+DDSNXt=(ao_^_Md z=Yz!@6FGRH?(Apyd7YVI3TV#r0W=9d!_GI=3_D-fGwcNI3xJ&;qzh_GG_!)!GboH<>7))6*8C1XCx81p{rP5xpU<{C z{Cv9G;pdb64nH3sb^wo)JUs32^TBzCpC6r_D?fC*S-$UgvwSz%&GPMZH_JD(-7H_v zce8wT-QnlU+YUcLV=2^f^Mln6Kfee&{QNBL@bkH}!_Q~(4nLnNJNyK#y9M|E^c{YF zOn2D%A=_c+`+SF;?}{CEzAbmy`35v+TJNy)m9xXom+qkTQw~2L9_F418e{)b&G_?k zJ>$>k&5S>vwKM*F+Rga$Nk8My$CDX^J6kw<%iQemhaE=SiZZ=WBK+vkL8=& zJeIHT^H{!`&-nA@V#c2@mNWk35P{@DP+kC?G5uh z9YN!zTS0ddzG!#+32Xa++8Lm6T#&mqg32Ri`Bnd&c_)I}a$o!%SN_RAyaF~B4r)t+ z+m4J5mY^|lP+sd`U@!%Zm&5uK;JE{KkefKWVPc?hbR@l%V7;~sLS*RO3DQf3zMoKi zTS;?k0|owUpunFEboQqM1#Si1SqdIwAT=G38z&UFbpXPZ9Xuw85;mYb^pf3SrzYot zD9u`dVA$SV21QL=d1fc5kA|M^kzB5G);faw%gU&2IM9B9^I!f> zul@3OI;g)4YI}nE%;2^Bstg|&fc9m`JN)DbWcc`ifgvOsG`^w^Ia43GU;j|r;pcyQ()(^ys`(49dUJo+OjX5L2S_e7RXqxrY*xqP=6wWg&_pg2LbH`Q8%Q~0!sI<#zqlFo>F=)=W^*g#c(0C&&c>D$V%ob31f%;pZHIlIP zfE=KEUqEZtA>*)HU;O^Rfny=xL{R6*j|1i5m!NyIL1V4@VE;kp3bh$_a!h0_^kQWQ0gYF`ad+7H znps}U<8OS2JR^5Dbd7Kac#W_;c#I2tcWDO$gBkMv$rtjFu`Wjjh7fVkUTJNIom#96 zg0I9Gz~ixAjSPhxOFN}rNHgqwA?>j9g)qddvkVL&_wAXlz7PiIuR@Ug577E&(D@6{ zu|1f(FM;|Vpz?#!Vdo3zxbJIuho3$S4MCZI<2&pbIl%7C`ODSO_5Z)=OK#Ad5=S;@ zjo3?mhMgV%*g@lxpfe3jk=+iO{{ihQbYy487VzY|NnRT3(&c%pgt=!J$1tL>@)?ZC(s@Z9d~uv%r!~y|AU_8) z`~>?MbSDaQZ9){X`@I={KJ;h!=>yXP^0PCju7;dz1zT_63)3U*@Dr3TAKEkgv}gP` z9aP?c+U^_-9Ip>BGK7Hh?prhP`so*-xkse+(>5?OKxH#@3|0>sZr-49gXYbMpMR$t zFfd#YU~>4$z$AYS%w|Jkb0M+$kk~> zL4uKi;Q#{zg9{@A!xRPvhBpih3 zFflM(VParlU}j*@VP;@hz|6q#fSG||3p)b?3kL&34F?0m0S*QR2{s0X6ix<)89WRO z415d>ESwAs4*U!ZGeCw5GBA_~GBCUlgxDp*z`&5hz`(EuYIg$z1H%Uf28IMih3uyK=A=a1RExXjgDYo zVBlb4V0giRsUDjc$czO@YC(EIVlWJH7l;iC7Z7d0$iTqB#K2&~Oj~@05n?{bewbY_ zHpu=Lj0_AKOoZ_Y2B;cr>amGI!wzH@HuGWPE1-Ha7#SE$7#J7~Bp4VXBp4V>qCcQ7z8EMa9}@L*$Lc)`KIpuxq!kipHs zaDs<{VF4clg9|?c!wY@}hBJZ;3@pM73|nLw7<3dE7+jPY7#dU<7*r$~7+5qI7+Opj z7(}cY81|?#FtFG&FdT4YU=ZFo4QuQ2qqbFbq-;V`HO1^#%h214HZUz#Vd}U+s;-K+s{mf$G|D_fPrJmLk5Nm4;k1~9xbH;B5h5{xA<_~`u7-ldrFiZRcna;p) z;y(k!0VW3KD~yZ`FPIpZzc4W}2rx4+bFeTnSTHj%PheqWh+t-5E@5M2XkcbwKElQb zYOgRmuro3oU}j)$;9z8U!OXyH!3m0G28KDDj0_ws49p4K5Pk+XBZC181M>rJMuq?u z2Ien3j0_bl49pjJ85tI^Ffd#2F)|!rVPM|E$H?%2g@HMQAEHk|fsuiMm4UfHfssLh zm4Vqn5h8v@iIKsBm4R7BnUNubm4SJVG9yC=D+BWrHAaRFAig>y!wpsj<^vjx3=C`x z%m!MF3>s_<%qz4QL3xpxL7R~wgN=b%!46{H3O7cE32Y3^cib5ncCaxpmlQHGJYZvB z<|tug;9zH97AR$8Fkok3R;XYE<$Y$6W=4hvb_V7L&5R5y*cq53S{WHGurn~%^fNO2 zU}s>~n8wJUz`?*AF_)3SgM)#&XE7r~0S5!K&T2-685|7E8#XY4+IGx4HZy|C1!j-k zj0^&t49qQi7#S=$8JHIwWn@U;WMIB=k&&T;lYx24eMW{2oD9q_9x*c9;ACJfc+AM~ zgOh=I&P#~<7rbO-P~c)r7*Fdq?SVld!lU{;V|Vu;{oU_Kzh#L&Raz}%w11ZumooH1o$Si#M} z{K1Tg;RHzD0+cct7@k-#F?`@=U>2}sVi4eAVAil=VzA(0V3x6FVo2a&VE$sw#L&UR zz`VhRiD3f|1G9rI6T<}_2IdS~CWa3@49p$25Oa9!m>2|j8JH*7LHIrnObiCR49qId zObijc49qi}nHVZ~8JI&{Ao4n{ObiQn8JGpUnHWy+GBE3eGBJGMWng|2$;2SR$G|)# znu)=IkAaydnTa8TkAXQMm5E^jh@Z#Au!E0*xg-x_jz9qu!wo(L<{br03_ti7m^+G? z7!>#!m~+aQ7(DnHm}@GT7z+3qmK&xV4hRM#BhP1f%!%)6T=67 z24<5wCI$fk2Ie<)5Oe3$Gci~QFfc1LFfl|3FfeavU}C5cU|<$$WCFFTWbM zF&q$JU_Q~p#PC9Zf!U&!iGf3qfw`lVi9thzU}7*3VPJmqfr%kNgn{|QXC{UM z5e8QQV{AOY}Ai}`x!^O<-0>tNKW)Ki%VD{l-W-t(CU_K$h%n%^Tz}zFm z%upf9z$_uk%&FCX;F)+JyF*CdnV_<&L#mpce&cNK#&CFmS&cOVno0%a(oPpV; zhnb;5oPoKdhnZo9I0N&X9%hCe;tb43dO$S`1H+phW`-N$49p_E5WY(}Y&Kzcj0!aquC37I=Uzo$pFhP=mdCFX7h7FPo%n9=# z;wkf(8E!~2Fqc62YZfvy{E%c|j#$OapdiJ-{9_d}gM$_J`z`TT?h2eq}1M?0c7KR^E49pr5EDQ?L49rg?Sr|N|8JIH^SQrYV z8JI(qSr}$WGcc#9vVbds392j%2c#L8H)yahypU#KzM>5g&(L9E5RhSDF41FQu#jP3 z?yz8CNRVM*F0f}|=#XJx-r~u^utA1_nJ0jS;f4$YvrHHZ1A{CBb3+6RgN7^vb4(Nq zLx3y;^O7VMh6-5*W`VCP3=3o#nE$A;GMtcQU^ek)W%vM+4`OAIkYixhDP?7FkYixp zQP0YdA;-Y1(!k2lAqR?IR)!6749qOESQ&1}F))kFVP#;DXJF=8&dQ)6&%i9Ok`?R^ zfpx450rCvYBAZwlD&!fM-)v@OSRl{9yk|Qr!wGo?=9(R>3?Jkfm?aLdGDs*eFfTa> z(I<0^mBB%QftlktD?@?;1M`m)tPC9r49q#FSs6AcFfboD&B|~=fq~iJEGxqg1qSAf z^Q;UCiVVyy7g-rR6d9N~uCOu`C^9hbxWdXXL6L#^!Btj<9f}OhJU3Vw9w;&}o7`e$ z;80><{%{9kpTS*L1_LDqW`TRG3=v8U%qQ-#GE^urFv~n-Wmo{BpRqEWP-0-#`N7KY zL5YERgBTlwgfauOi4_}zgE9kiN+=schB5=QKr9>B-$#9vVPl9;VPJMR#|CO=GF#kbV_2cWz|8Z3jp2d{ z1GCH*HijQ649s6d*clX58JOqjurqk5GBB%HvNIH@GBBSBV`rG5%D|kH$j)#;m4VqO zjh*3zDg(1kCOdl@Az^s2xv1f&+y}5FwkaTKH$f} z5TMP#{KAiep+K8~ImVxZVS+XTvqJy}!v<{z<|zRj3>UN+n12LtFnrKvVD1RyU=Yw@ zVCD$oU@*{OU^WQiU0~XwYR~R!HGsSOF4GE-l(l{6<=rJ%CWO6X< z&|_d$$l_qQp~t{%kJgW&;)F6Ln1FkoPQPy#VuqLhQdz<_~yLMaDBfB^%uLNy0Ng#iPzL=6YS z0+4tO2g3ma2Ih=f4u%&749rXFIT!>C8JOoZa4=XHg6d%oh6qCj<~NNT3=M`1%mpnR z3@Z#7n0Zx??gCW6$f%(ir4u%dB2Ih=K91I&w7??Sha4_63VPFi?b5?RN zXqYlE&sYNyw^+-;5Mau{T(NV_?3q9m3zSgM(p) z83S{`P7a0xW(>?SyEzzMm@zOPISi5iaF~NZz?^}3&rt~f%~1{p3v&kMg5war!wC+C z1ak)F6Q?*BI?NfEr<{R^e>ua!u)&;xx#k>%uW+7&;f6T_v(E(xzXn8GFfg-RhVWA^ zb1-OFFfhNl%E1s|!N4qWor9sm0#wd$Ff6cOU@o}H!EnNYf!X60M18?+4u%gF49qWX zb1(>4GB9ts%fZlK$-wM#4V9CJz-~k5% zhZO_!nui<=238Er6CQCeL|8E}t32jlsIX#SKJ%D^VF5_|2?xUokoYqWh7Ta|XB-R? z)(p%g&p8+ztQnYPUT`pESTitR01X;2Fff?BYX;_&R~!sCtQnX; zyygH6S~DBG<6zLRVPF<`&%qF218SFXFjUwuFhBUn!LY!Ff!XIX2g3;)2Iih`5chug z#=-ExhJpFZ4-N(iTLxyE-w^Q?e>oT&Y#Epx{&6s5*fKCP{D+9EFmN(V0Pz_)8Ftt* zF#lkL^uv9aI2j(;GB9&6L-+?+IT;x27?^W7ITKCQ%u5tG86qqh zm>ZNh87|l}FrQK8WcXmu!2Cs-lR?0Nf%$?8Cqse*Xe1sob^@G^ z0J4X{gRg-RqyWreU;vo|8lM+f3sDCfcVY103jiqt$%Dq18ldtuP<;#@d~ka}W1@GU z@+Am)6njAK0nKfctb^EtOC88Q5k>|Ep7juQpmAWZksf>nF!zAQY$BlYps`x0Jlwq@ zj0_BGpz@&c9H=}v>_Fz1FfuS)fXai$tD*7=AoD@)oWjV!Fk=(M{yShv(4ZUN1>|r8 zsoTTIz~HkPqV5Jl-2!BFAp1b`41b{NKyxBsrAXn+!o7;e>N*hWCZMYWjqlyq z1yKhY+5p>&mVQ9y9bsZ%=-3NU#{*8C3=9lDd<&S+-1mlwfgxu*|T1#F%V-v)Gb zBFqd7DF-0xKxqM+I#9TR#*PCHLezoA-@)pT(q#-Y1H%reJSYyJ@+jc}GN*-^fuZCu z#2nDLBvhRN$oU}oCCm&AOQ7=D;^zpcTXY1X-vJSx80p{*GXsOfQHVOwSS{2Zcs}9* zZR9!zkw1bk2gAK4EDQ`gjziRe#!jK;fYU!HK0tF@0w*By@bL5C`+y$5H7pDaf1v7c zrE{?VSr`~LoP?MMnrB3|4?*p!TLe|QDJ3ZxB!(0&6R@n`|uq=PB$QXd{`M6Snfg00nL?w)gk4x999Mf8>l=| zxPi+RkUc%D3=C7C@*bc#1sUMOcYpr0{wIT4bgTQ8xuqK3qT#R~~i-h6Y`TIu2NPdGKL`s|h;;LxLVeod6=9 zCZL-a!_L6qVF*zNnnwY<(1-5>Kbn7AKpQ4)AnHJK7hrWBd?@)B6n<;i85njz)q&>B z!0LSX8qn>%!p^|JVFxi!g$t|-6wViT(CqyKntS(vs9OW+QiIeT;6ziW!ok4M;RjJ? zzz#R>00){n9}WhF384^mCJ6H;aG|LKb#LZGL)0xmnD>AiP2C(01_qI2h`JWY5CX`3 z7ueC%9pPYLD9C`Q<3Pm61y(e5Z#Wnj0K(|+flYwDJ5kwtm&J^rp56t@4 zhLeHeOff{A45SGLb|1QVp!Ey~Y9Q(?Kkk-CZMMi za2i?wF~*g`>V6>nc>pW(0#OXPR} z`Ew071H+P65cA;Wxd$J--FSwZfnmjKh&*WB0oeU$Ky$iKb#QY; zco-NOpz@&gK~VV(==HY^4+BHNJBT@7z>2`_RE%;fg@=K`<~>9mQacr+ThzLGfzB%fK+_GerIdtUf`jCqVYZ@G>y?e1oV%>TiInCy+TcybKHr zpz=um#R!)rybKIHKOp8jL6n0B(96LyybKH{{zBBrAjxUdZ1_l*Th`JCQ;RXtqDSQkJ z0pbvK(4ibqxjF&aeW38&1F}~hq7JED2rl11@^|kV5 zdC>YTWc{G<7ZG4!SOS$tYG0z{e~>vg0t^gK^daV;=M#{8i~s|JhXF($ss9i6M~wgj z!yc%70@xAY@&gH*(40E9B zDiHqrfL<>x5oBO^V*xP_G=>3oI$C=KU=@eWDagDOka_VCb-2>SFvKK5%=@4PGK>M-KTt&T z2WTylN-snmXdNtAB^G;igc%qd`XK7y;|yr=0J1kkn1MlM0#qH$eQ5PCNL`IE0|UoI zh`I>~br|V(i7*30!6b+}&>B*x`@s1G6z@lb85sUR<*}7>PlOp5S|&sEgZkWH{XTpP z(Az6KA`A>SrbE;#AG80h-hB;9A8ifDAsP@xU@QN{ z7#I#HLe#kkfmJbp#{baM_Zu+=hC9X(bx7@TjP{I(I0Hk734V2;aI_I;U^oL+hg5%o z(*a06Mx23x#}r}?Hu)NH1_mFfyaCkN3?6*&dVG#J149f{9$Pzhk2nKE3Lg18;tUK^ z@W}rGxgRQz-VO%ElZ*rd!x^aj3q(4YfF7NegdaEkbI8>1A~qgL>@He4-OLO_!-DOYa|#LHbCW(%1ab`KYMdeJ(8vEl;V?y#f#CpD9yGTBwi22yK=y2rWMD{ff#^pXFG6WwfXulg$-uzl z3Q-4ITMRbGg--yKJwfLDkz`;n@qox9wX;7U_ZL9ss7Ns|>!L9v}}PjrU!VVqgf_3Q-3d%Ll9U;oE@TkN+dZz~Hb0qOJhZufpiZt4M?97a;0D zb1qQxFvd}Rq!}1w_CwUQAjZEIpxav_&A?D`6rv6^Cjm7NV;paeGy{Xp35YrYME=8= zuQ(#jzz}c>qD}#+UPBIFP&~Ym28~BR)TtoUHK6Bb5g7)C8y6tz;O!i=@nDd7HZlwh zdoDrLi6H75%=VuQ1H+0t5OpsQ;eugrj|>At#$$*&7le5Y=;Mc5WEdD)-a^zx;4$xx z3frgugAbz~V3B8Fm|_c2_XAw!ROe0_%Qo_@(c`TLLllc zAoA@2bo0*0Gcc4yK-9tKsXX{F>ZvdC3=BMx5Os49@xK8h{uLM)8WJGtkm^T_dd5Y8 zfgvUhq7JEl3a%eO;gO=iz@U*1kq7Mu1cw`zc5aUX1H*?5h&s?5F;pFjKSAkeivk0K zO*TXwdixw?-xUQ0h61QOd_D`y{Lvo;28JCu5ObhQy+QdDrJV~hPeqY|;Y1!p9lm_; zqsYKeQvgv1nv;gQA7z{w@LfPpKRikd3~MSN>h>U+hhAQqC^0ZJR72D~ z02>B&KT5j^Aapz`qXKrHTBqQt=Prw(Ec1EQYZfL?E% zQDR`Y(hN~2fanKc%%6NwVqn-a6{4<14(b6Pz6UaB<*AG^1B1jCs5)h+x&Xcp80DWb z14GGmh&lsls5&3M4{~Vc=d1I^`uRr>H@S*Te zQD$JU;P?wJcXdD;oInN!@J%p7Q};xffx*TFqV5JFTppm$EAgl>FuVzas53y6TNv}2 zCMpaJU!oxD{=niRfbW7Tn!Pb93=Ag{AnHJS$w1Cyz%oA6qQb!7kOfiq1F8QGZm2@4 zK?YDdUZcXmAW#WWcLm{(1|c+iuc$CE?CFN66F~R_qaF4~g@Iv7KSbRPSO>_5ZvlF| zsi-nAglvGQTOkhi1*n|(fSz7_R2dkq9EYgu0CjdjN`3eap!=glm4U(J3PjxsS&$;g zJee$-Kjx@1Fl_k=u!b3;ZU#af$~XzgJR3Cz1{pSpI(Yr+!-rvBiW+E-H$>eQsCOCA>S0iM z0otoLfdiuM3PK&cyjY{gz~I6Okl&loq?eRDvwl8qLhcA@XAqVV0cjk zF$ZZK0!Fw_QD>2U578*E=qn3=BI?K-7WuyF$%7fZl%0(PUuw zaT%fxGzSS)w*fg^K=Cz2lY!yL1Bg1%I2%|UwEqv1-=fLDa04p;11t%yf5H7^ko*-* z28Im}A^I;MzQ|fg#}$Zg~+c1_pu05P9@*1CV|b&{#TD9^1H7h!z6_2Ojwn zB=gbdpF!qN(PChbf$GOLF1AIBfk6i~*NWY05149ZP`4Bw@h8(Co*7(PLagL6A9j^cWaUK;@Cvv0%)b zu;?=|?DzvQrvnl1DD@D?J{^4q28sU=b?Eki(4!GQ&$ z4p(@A{Apsqz>vWTQHPX%;Nc!(z`$?-Dn9{HZ(__h))+7_XmCT!L8`|v#ut_tFfjap zs>5dA5d#K>03L`rNb8F*^3NMkV&sLWvq8i&O8*=bt|EpE3?lpxb@<$6W5~ep1gZ|3 zyJ8F(7;FR}=HPQziy;HU8>qS#JnmX!$iUzs3^8vGxR3zX`zYliD1NROGBE5Afv7`T zUjmPxFNO>ZJ)#hKeCbfeh=IXC9HI^>A7bPS7b6CS7DO-cfkO_W4qtex z7&9=`K-HngGsxX8#taNspz>J#Z_L1uA`h_#mwQ0w^caIKQh}&LN_XJ$10=u3n1SJq z0z@9ET>y?(ko*~A28Ioa5P78aP~dVM6c2BV85n**<#Q1IM2vA15fcUm8#RbI28ebv z#`vX;2?K+RCPbYE9(5@u3=Azg5Owf!3d^`;j|l_A5nYHnT=4<&#}*R?1`9oix&?@I zfRdg->h72@Fl^9=sDsaAU`a15rVI>Q3?b?)5dJ_(=OFWROc@xCm_XDa^)E2gg_trh zWLQAd!PhrnDVJ+Z85kO@A?iS9FoCl)+B^#=UYD3MFi6-!)L~0sM@$(QRzT%(g&WA6 zH>L~>K6Vgu(9;JP);p1b*zz|{&F&}At6h^$1m@zN}I6~CT z0DBr-j$xG7bIceR7B~@Bcf^c=LBJWJ4s^B?*hsW+1i9~x83V%>7l^tQuyHjXz6a>* z6h+J#7!rIT>hPIoW6r=};tx@W&%Y@k^8z92aJ4T$?&~pUU^oyAQHRgoE#?diM?xX$ zkoHeug!3J928I*i5Oq3;e1b7w&SJs9@FxPI4xjsUEEpK}L=#pQV!^;569-X;&)ymf z1_p(A!s?b-Ffgbj5LS1_f`LIJ5uy%XIr{}P>7EQxhhCn8;z7icfgu7ak1HNP`NhVP zfuUdp#2lo3NAU7C#*%^I3{)OzofJy@6J$<{B?H5j6o@%U{V{mCzQmG&VMQuL9%=ju zE`P+5fk7Y*yFAE0PeA5F<&oA4V5AowD+Y#$bci`f>M-)9i4_CGAE-K{dI-flkiTNA z7#MbBK+Hp0{|OJD8Y>0{olJ;4(z-R2_8-XoORN|e)aF(%UV2G)KsPlk@3tB%Eq|U{b zf#F31L>*FnhT)GKTLy-RMuoauh7#NOpL)3xJcm>z9XzN-* z_J!Di&KQEILmIz??=LB_V_;zDg~-Ri;uDKGbLNsHS_5eP}dJ@n&%h{}RV8dFV zaJgd7z+kW#Vy+J&e8J@|NdAjG14GObh&;CO7ZC>rh7_nglDkmqEs*f_z`)Q4=5JtxsSnS{EJ~T~HZU|YHZe6bx3El1N=`{lOV7y6%FfBn%P%M_DlRE4E3c@m0;z4-zhHmE z{0aLT`awJd{xHDcBgKFTFA!!%0?N$HCM+y0E=YDRI0OpU00zi;5DX0H;R%X=P-sEa zDZtgC^FM&i5#WcJ1JVP+2=g4BoLyYq;P)nhB(Y#va)Qw?B``iNnpkz{`eFKDG`c*o zd|K%z)?8xM;quQw>4(`1qtV@mOPpMF==xxMV(o#cN2h6}pICE=Rfq0w7=NJj!|a98 zF!#V{T;ec!7)`7?boIpQBczUyJi5IwJ|P;HxwyosWgfZaquWo&976J>nuo3)7a!eT zbUsWUOdLkT#0k-)sz)~urXNP5%cJuhoFFGW6`TUq=NlLtpc>KZUw02rFK-`TKmUNh zpx}_uu<(e;DBLY4ZGEUQ3?Dv%T6O{q2A?2w0hHbVr9VJvgU=v&cr$?k)~24@J6-tBJ z)F9?u5W&E}uoy}&htg}I^kygxYJY>6`#}T)1H(ZmeH2O`htij!^nED(7)n2d(l4R( zdno-8O8BxS{h2LLTO_tZ4RX^p|mZO_J-1dP&yh)$3p2u zD4hB~_1K9qhArC&qo&rte1l>Q5)IiVSW8%oPUX=Ny_3#E;rv?Y|bhSH8u+8as-Lg{cQ z9SNo5p>!&g&VBNN3Z>1Vv^A8rh0^X&IuuGr zLg{EI9S@~*p>!dXE{4+OP`VpR_e1IFP5EYMI+VT- zrJq9Sk5Kw6l>QB+|3YbY=s*A`l;(%hl2BS2N~=O?bttV1rR|}#Gn96P(w6K7=Bb43?r4K^s<52o6ls*rouR`gEQ2I5L z{tKo5LuqDcMZ*cDxuLWmloo~3;!s)|N~=R@O(?Aor30aKIFycs(y36o97;Dr>3%3Z z8A?xu(lep-d?>vfO0R~}YoYXJD7_y_pM=t=oghtl#;S{X`fLuq{|Z40Fxp|m@c_Jq>DP&yb&!^RKdpyeR^K5J-w13G5i zo`I2xnT3^&or4oPTExZ8!^_7nASfg(A}S^>At@y-BP%Dbps1t_QJ|u#rmmr>rLCi@ zr;ljiSXtZH7Q6zre*_p9UW4ch3?&&wsfqB*VHgP`^$Uvfvr>~w ziuL_dGV}D4^NUjTAsV2RUVchu9zzJ&jQD_}%>1Ivl1iw{A(X@wkUa_vQ13FxL;29` z$)F78H!wnzB}5Yg19;30#DNxf41W1VxrsRpKKbPg9+~MG3`M1RC7HRYgxw2O2zETw zxs?T}@t%2U`3%LGRjCY#IhpBs3~4!u>BS70DGX(aMVX0tB@7`jRq<|MDO5hlX<+;S z?0y9XaI21if#Efn|9}y4t|(Xun1DtvgL8gvL1Iy2QcfyEaAs~nPHH?vBo)a*zr@_s z6o$OS+*F37#Nt$jg6wpLocv_4Il=j*MadvdDXH;3`N@eTnfZAPX_+~x@db$`84Nj~ zQOo4~oYLGphJvE}`5C)D(u)yp+tuyu8%nVz4?G z5s;Hul9peT8}Eu;{>N2F{KCd78LvV3u=wTx^BtIB@eMN<79Ozph1tX4lUY)dlgi+f znT`}9L8W=f0pymGp9sA$3*jG7IOe3n@)OJ+gnVFWVo7RI9w@wEk_-$;b_ACcW#*+b zWERIK7ekmJWeELF`T04iiFrsm9P=uXco3CHSqY>aNj@MyGp{7Ih#@s671k(5vER2e zrzA5TrV6YXMLqx?ouCAiTg*_DT3nh_QVdD4DVfO($@zI@sd?ZO0n^UloS2i7nU@~# zj71KlDB%VqzF_^03@9I#A9JC6SU;o^%7+%04E0bxEdD#7e2}Ri^Cv<1F!QEE`7r%+ z(fEtOdKsTB;lnR)SLiJ)1B+{6kfE3-JhxFE5p zI2Ad4g7n9SfmMP61d1W4E-x)V-lZ}xF*h?AYB)kXI43h1IrD^+7UZNdlvEa^7K6(e z)clU5ucW9nxr8ASmK^B8~IjMOJt{_G6pp?xJ5AhJX{qe#1iSgbb z6Cm>F>8arsD25U9Lv3jM9x(p_3oJcAOu?*QVCl&%vm!Nx0TO1=5JigXP_RFtRRlON z;vwM!3Kxji^77;JGIJPm6DyNa8HzI!i&9g-0tkniZ7R1U(EY3(RV(nU;+|)kdzI{ zK9B@w#8AOd$p9`@Ai{1%`RNRxx~-&=A*(dEAU-2CGd-h(!8NZ0)Z#42FU|zld-+9~ zsd*)kR#8f7QD#|c3IoJQV+N!KfNy?YF{myE6<_&D`6ZxQzbZdBDKnKJAh9Sh9-PlL zGV@9_8Q>Rdg1yH8u6t8UiZYYq3-WU+bMuP|GBS%16}rNGNc_O!Llup$g~rzh^BoAb zf8pg*e!c;NTYkPFh%f>X#t?@=$wW|X6kkx3pI(%hn+u92s05S(wK+4BGfU!&Q$cws zzbHPnqM#_XxERzfa?8($DuYuu!0uCkx5sax@$Z274RCpwMp*iWweK7moEV%zp;wZb zm=j-Io>`I%zIuu{^AYw3JOG970)qCz!pnsr3GCStNIG&!tSn}5NksHfBp!myL+YQP z@ztPwSboxj@W{r5jlOgqagunwOGT z$>5t0rb0?ni$UD*)Ra63DTC64MPCvWoNbtduI_ z(=tQgB77!;F;@{|qAhs6Uoln;wP5hx$#ZfPi=4{DqigwF^oPocsX{>ByG zV7D^36{V(viFn7H9EPA&uzvzeQ;RC&-BLj@n_A2O;etzKu%^V4{GxbBnGCa(fq?tTNJ_gu)!Zj!#GCKmguNV>@kb5u~7zCbx_y?F^^#aUjLh0APv?Sg?E#4OrC(u?m zyr}>)g@FMk<5-kl3XVyH6qp5yv3S4yl6X&0)d5lgZPiO^55 zeSkdP5T8_p9H9W*gQ}Jln=R=gn?l?ln;yF z4NyKTelI}zuyrXPpnRCTz;lTEVDbh~K1@CUjb8xe!_+r{`3)?v^ak@euJi-TH?aOD zob4yFWgE3I; z48DmK@t&ZR0cuVZ#|Nb*CTFCkFgTT_rKJ|d`O!gXZfJ^YZdb;{6L!^Wxny zb5O>5Ko&SdKxrX9Eip5vv?vwSwn}Em0XNYZN{dsA;tNWOAPh){K0XsP%#)W0X}UYY z^}9j!gL}ILMX70-6%4tl#l?x~sSJ=7KSNG_d1`SK8)N>3B3=-h+T||8*2j#=cm!IJLh$wHAq4Kcu!5GSi?$ksq8 zAErJ5%%8vrlLx5*VO;qgW-fYr2i6{d#WSQc$c<20_{36&`wI`%^400KET=Etqo&X|) z2Y}i5hy`GE2z@o+3*7}6LZI{<@I8 za-{GG)_0Jx(qes3RhN=l1j*IlOp=pXqLP@GpQmfgpuk|Iz)+Bwmzm4}%N+`-;O=88 zD6^!dD3sX<}^m?VanREC%|hL}8tm?DOl5{8&EhL{Qi z1BMvbyamzmRZx_fR{}{epz+4cyb=ab=z|GR6cmA`Op^0Kt>y}bLd4t$B)>8w<>%)x zB<59u2ZA$G7>W|hLAv4?qT^!0Ge-;>nhZJ$44MoIx^@Z-%FyxXXlU+7B9PlS@O5Dr`kq+PDSpbQx-R$x$uj}FW@F<67#keQnj&7fQa9eC7W&{P1mM2a#iq8VZtxRe!2GEx{3^72bk3ldZGQY%s!GCNZ(x&k6rSvu_Izp&s6PRciU&(ofNX+{MU|y8RDyVUu;vGtR|RU} zfmv`>#zwkHnI#NnCSZyoG_Sa{pdi1fBsE1Lu_zg|J0ZCQG=~Q^8*Uny2R04t3j~o2 zvNSQLAR`ex-H@3K3gD7rhJvD0-ICPQykZ6@Sq>UaOD$$FWH4fYHJTY17((;1^YY8{ zQ0+z-4+;&?#AJ#BXm(MdD7B=tC{F=8D3)4O%#fC!Z=hfcq6{IFkpgUK8Q2sqWrfs= zf*jBg6xaxGC9RNOmRgjPpO^wFLb;SdQB|5;q5z&M;8Ioqj{`z@L77RQ&1zceo; z0Tf>#6=2tZ&4bLagC^~u1Ex?ZFvX>;tl$Jn;tG&ichuP%2Izb~4$YwPd+=Pnf@%uL z-jw{jR4xXPkr2Za0zjn#*d7?+oS2uKnvK;jKl%YmcQDL;uJ1gQ&;9R9E&Nl*%b4M}=_1D8j+nJFnb zsX7X|i6yCepyYxyAm^5!uV7^bOYYSSoT|m(bdsQ2oS?%6v{&Y#EAD6LT~QH5F_bGIJBt zA*?JoD;v&A&d z6`&(e5c?sjA)~RypmtU~I6K9|RKv!pAgV$3gLNSJQ=vSwBtsz=w0fW*ClyvCL+2M6 zz^V~LxyA7y)$uUZ@kQVQ95U?;wt`DJ*xykBGC!u^0~t{R`3r`*Kr^~knFR`oc_|7Y zc4=N!W&unV~%*=yK|A6d=H4hX(aA$_5x^jWq=CD=NEvc zS@Vk+AW9+Oq7E`oAvwP&)e1K42XO_01P{0>sFo>|XJqE2DnO@eGxO3x&GD4{T!n(7 z%-mEx*svBTQG!GRK%xqcR)~%t)X1R3Jdk`|X>L+#kpg&(5y51qK-n6CPS`~f~s;E7eg+1kjzLU*F=*c2{a~2uzjCj zte;;TpORQq4jVVlFG$T}07X$MsGLm!&FyD1WTYlS2dbbE1*Hg@4;p#{kH3KyZB#%z z5Q%yD#W|^|1w@SB<)-H9=ceXDG%_$0mlT1P9a$-4LKfD5q8hRe2I3%s?tvPh56(H6 z$)JXGBD7xv7b?k5WbjM$W6<@?OJmRm5fH-}7(f%Zpq?vez8uy#wo-sKVxck$;OP^H z7NXq))msenC`3Cp`=Bxq3hEszh0L6s)bzw0ND3?f4I`!~l;kTw#uMU`GE0gXkl7I3 zSp5@kXk>w`7R-mKC+MHjyiCw|ihgNHngy6Z^$s!Xtf1_YFNd@UAxi z72Nun`TCjp5Z4+Q5Rtw!^Yu$hGIJn0h)|!FTcV$q3r(@AiW*LiE(+nEE+HO}Rti)k zAjs9(GuYGLPm@7aQNzz)Ag(zkqTm*N{)k^zMd14y;6XK=8m zpSuD~4MLIuEDy2~CI{7zs8&=JHDLOkef)!66`X<`on67MaE%BFa#Ucj$;-^KV^CFO zC@CsUWk^fR0WCXYfPwh5+!D~Rj}@rmNJ}jOch!nY^Yj$LGgC@3zy)0)4jv8)tIp*>5`@*o|B@{Iiaf?~KdI8BFYgZiHtiFqlY4o4bjktZbUg4_V+ zG8kkq7{G=~z)pmQpQ~S}uR@rkPpB(OZpmq)en3a-RTvC)@3E?EBq{Npb7K8R&fh7y_3*yTY zGfP0-X|O;_etda;5lEh3euH%JVD^{hWkTzS_~fEg(CB+S%;ua_hNM&mXy*zX7a)S5 z`Oxl8WQDSllSTMaPznlTQ*bGuQgG_<6KtSGtI5xMfX*F*v>>TZ%*lZ( z21$W2R98|_equ^;Vlh(50G1|Po`U@Y$_SaD#k|ns6lN=ONkg7_@rfn*xv*r!z`y|E z#^-{gp)@ZiKN*&Ci8LQR-o3E`@g1K$0MBaE!zJG|&PtkRm+t zAny>4Us!mh=9Lsxf@&>jeGW35nDP{+AJmuzH|$F?^Wuy16QO~OTAn5*XG7O$LyZUJ zPDFVRng@bOKxydwE9$H)R1QRevVL)DNqkySelDm?1aDaaNkDNCcx@b-c9@~Li3Olt zGN1`wkdr}Lpx#jcb;!W$IzTh5DXA5(Mw)^zWQ+hd(HafXgoHuE<|y;6(clSJ9oW1p z+I($JYF>It26z-OH!(XEGKPU<9LRR?h7<+ptQmB$5IU!jS_BzEMCgT^4;orePAo`F z&Mc|KV}5>KYJ6f|dQoM3N_k>YnnHPEu|jfUPEKkH14yd4B(;DcDYY^`FNFcripj{uoz?jrkEiwwLBg)X@s)FuRJ5MBt9`dEk8deJ}EUPGqo%g-nRq!6Ff}` z8D9hsZG)ydK)#6w&u25FRum-Wr7#qf!U`^T$bJXV09qnw7OE(*5;WWcYAu3B*+9tv zJgg3GT!TdN)4(lm@L(AF{6>BrVgyY=H3c-b1sYnn!Vm?y6oSL^i?UOT6hab2m#=cgo9rrLuhxfl@P2^oh4O+msVk0B|shyfA;Ntx-ODOv>$@PHv`q)ii?qM&BS?ri16-WYxmO6CqpZ;o z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S|6U0no-6(5B573=H7=Okroog4_i=ClLHeXXERgsCggEHz`3t-Z42(<+42%j442(7m42)h342)3>42&5J42&fV z42(?-42+W)7#No@FfeXmU|>AOz`*#8fq_wvk%2LTk%6&~k%939BLgD~69c0S69Z!m z69Z!v69eNkCI-e$Obm>7m>3veFflOxVq##_VrF2BVrF10VP;@#VrF2Rz|6o9A0J-| z+WiRLi)w_-%}!;APXh0sjR)=2%1>s9PtM6NPGyJ(?+T31DNaqzW&j;`pIlH0rgQVl zQo)Sk)DnjHJosrY@dc3G{PBq;B}MT4@u;HdsU^jrBd)=lmKboz<>zE3SE5OR&muro zUz}Q!l3J3OoB=*;4^4e>YDs2ZMru(e#6C<}Y|elkIso$s67308w8Fx-x+w9&%Dn zJosD_hWPlBoU-_&{QQ#Qk|NMi1B~$utPITY3=*ItyBWGz($mXS7%s6eFy&^%r&gpU zmzJc)XQU>A?u#*qXD|V!MFtKPhTM{((!6AbNlfW^rSS|Km{KcBQu9(W(u&iJ7_Km- zG2CJ*WmwCco1apWY0U7DIVH1<;W;w{3nV<2Fcz027L}A1#6x#yF|;v(4l2k)66s-r z-W4>Bg@MzM;S{40!yQIrhDVGh3@;c>8Qw9PF??Y(XZXcv!O*~D$uNP1h2h6eW@ZD1 zbu5MqyI71Ejaq+U|~3O2t+m<0g+QqfygUoL1f2y5V_$3h_p^%)r1@ zoR*Ph#IS@Z1x&AEVquuEjD>-P;RooFOQsB?wD`=_)KrEOOld|L5au~17KS;iKx!7O z29XC=voJ6)fer*I$xKOOc*B%g!O+6Y!th`<3uAm~9%#>WY6`iw zGN+`KWHPj{Fff&5GAv|H$z)j0%)+o`2gt|^J3tDd0lE(yphuWl7~UX+O&G2+gF^c@ zGYi9oogh6Ec7ez-8qqULm`^YsVLidPg>eVt9hL*kTNqa`Zee7(!Q8-X zGlellr>4ZG#3#o`!^NV5aSvmGicb&Y9mX4sAvFuw=P-9LuVC^x!#Ibrhh+iN6s8Ww zC(Hpg2bgv+8kihmW?`wA!gPl*qh0orQ zxxgH7fN>6UM8yfV9gItuJ}^~8EKutZ+`=>?cnWI=(*(9JqGuR?Ff9>T!@GfR3(o@n z7VZwV3H*DQ<_PVO*du*~t%Gq556cdY4@x)0f3SBjzF^$Lc86mD;}QN7T1%KNFstay zVEV#%gK-bz1V#-78;=&of)2(WMvEJ)C3_eZRCG*Co^a0*Il#Gs`3K(>mNkMIbC_2! zUSNL0K7s8E;~M4$#yw0iI~Yv@bXpjvFeYqaF^T!WSP;;{+`;&RY74In)9gIE9Q&?L> zelXj7;J%`>foqTW2IeiyYuK*HpWu2S_C?a<2jd0C3ycC98af6V1{!-9H8e_|FovW| zU~FL2FwltUVD!<@*u&VtvVr#j%NC|7%zv0ZFs4*!Xc%Z182n+`z&L}cgLMPr1I7tV z4NNbX8klAw|RV7kFLhp}P< z;|<0ij87Od-f(PSTfye=f@u!p0_GkTg&k~b*cLDzU^~FPfpHF_K}JS~K@0N&#uemI5Ay+*2aI=^zc9XGI>46F z!g7LT4YQAr#tg;-j2U|v?=b#g4B5lTp`h`D@dMKu_6tlVcbIavFm^C*VcxZb0@(;X%@Im(>gUoYy1L0>u}9aJ844nBy#AIb-vhY#Xkfbv1---Gy|dyql;LFeFu z_@AKipmX&>e9%3}AbE}t5ci3&Li`Ile;*{T2IYg!8^paEpnL-; zUkB7yWnf@%h4Rn*gs4x0@-u!z_-#=Bhd&VhIw)V_AB2Aq%1?muUqSgg{~_|6>=64; zK>2!5{uM?>@SPmKQ2rMt2tOOj=U{>G+o1djQ2s(Fzl04UzZc3s0_ER_@*UVA^1q?{ z1`Y^ch6Car3r+~%7Rt|n^5dcWIZ%ELl%K#2Q9lvNPl58+LHQX_{wXN`0hIp?%KyRx z(J#OWvHt=ugl_@mTkt{np-}!7D8CfS58;Q%w?p|`p!}IoK7#;6ejSwW1LdED^4CE5 zpzE4I>EnbTME!rLyn+IRFUSRPUjdY_0_7VhLgX!>{4+`rzCV<&q730DL-}){{CX(= zi5f(HGL%0@9l~D*ZLOXV8YoGjT)Qt6&G=i$VD-+#q~) zDF2Q-gl`4qmlQ(yu~0ro354GShL4B_vF@*hC?H=+E9R*3v} zD8Hs3!sq9KxL0Eugs%?eN6dxr&7l0A#SnfZl&`ZI!q0>9H*A3LTcG?Mn<4z^P`<}* z2!Ah>-?9h7KL_P6I11rEfbwr#gz$eu`BUyg`24&O_r7=p;j2LT1&<;85Ga4nO9($7 z%3lEGFM{%KyoJc`g7Q87L-=>0d+!0_DGi@&zm* z@}Hr64J!!$50o!s4dJu$L;Ujv$`^+6H-N?n7#J9opnL~gh(;Y&dIB~ZQ=lrK;Kk#~UdcR=|O zP<}@dM7|Wt&nbiOCqnr(l@R_4D8B$SHpIZda16?qse#Dfh4SY>`QM@Z8?_L5VIhcn zP3j)tP<}s@-!T;;zYNOnSq9@<>x{939ljY4N$(o2ME6p%6|jp&xZ0(e1^!cf$}-NL-^aE{2#v|{G(954;M4I zyuJ$M|KNr2pF#OPd=UP3DF1{2gfA!x@qdpHgf9=}ONc`F4p4rKID{Vv`AeXDJ1GAGlphG?Pnio*pAO|G%!Bajq5Kpme=?L`0_CrU^8Y~j z$D#Zu^C9{lL-|J*K=}Wl{51<9d`St2dm~ms_zqD14=6tX$`4o#kxzi~b+$wJT~Pj< zT@e0kC|_YWgue#LuYvOSK>0VI{PR%0$sUOM$58$RDE|wT{|3qzl!Ul9WiLd%4wS!y zp9P%%oS^(2LJ)o^l&>KH;b%bkPb4Ayb|^nX0m7dJ<%cLk`0Jtk6jccS6qG*!%D)fg zZ_t3qvr9qTcSRe**MjmhbRc{yD8EDx!jFOSJ1ijlS}4E39>Sjwr|R`66>5{3pxn`5*2;_zh6L!CeS{ z5tJ`*55nIK<)47^pF;UE4FLiqx*5dK>z|40&q&!GshuOJ)3*MRcpEQj!Yq5P6v5PmL{zhobTKN-qja0J5N z2IV`PgYa)d`4)E}{NGSM&j$!!LJ4BO%ohmX3d;W?!VdOdG?YI_2f}ZF@>MJ${Mk_c znJ@@{CzPL)2;tv>@_o`EdYmM<fj6!k-G|U-5+S*FgCkUJ(8TD4)R_!hZ?nUx4yi z)gbO$-~*ADh4ME*`Fc?P4Jh9c%4hI}s1Jtnb)fuYC_e_uFNN}3p!`-Se+!g970SN@ zbK?0T8|fls^T^H-z$kK=~d}en%ig zeLR%U5d`7aLiq+z{$waW0m@$q<##~&TcG?WQ2rq(KPMPs-gzj02bBK=%6|am|A+E9 zLLll@G$8&t0_FQa`Del)^5sx|O)P}J5X!$358 z5c92|e1$9sKLpCR$cFIip!@^55dI=4zaS67-wWjj&yTUkKszYD4Tl zQ3T3*{?RL*%zY`4Tk{{&^^W0+jz6%Fn2U z$n)wz+_R(}!Z(HT=QKe0{!qS1BZQv~<-dXQd!hV-7Kr?MD4(Yl!oLdT+d%p6q5K>u zpHmlNKSvuxy$Y272g-MX@_9NS@~Ke14wT;t<)47^*F*U(-4OMcq5LmU{tqa>pcf)9 ztOv0_pbx^=hw@kSL-^iMe!~O^KNrfEnF!&xL-|vn{MAst%Or^WaVTGAGKBvK$`_de z;s1v6e?a+s`VjXdOohlBL-}WBLimYL{+~Gzem|72vH-$g3gxFj`NyFAGYcW|Z=n2) zMG(G#0mMFzB@n(LlrORj!gq)AO`!ZzC_iTzD8B{DUjya8f$}dw`7&D}>c2zz z3${V{f<_ScIBbXTb)ftkP`(e8U$6rrp9SUbfbv_R{D7Sh`Gruv%x(yO50ro8FogdC z%Krf6vlv6{-*XfquLR}4f%4s<{DR{U`9vsR-~@zU59K>R`75FP6Q>~ZN1^;FXCVC7 zQ2r4ppVI_l{}(7<56Z7O2T|_<IvEtFparA(@*hC?2cUd`+YtGC zP`(3{{|Cx1fbzx6AnthqC?m_qkQ2q%hzYod}xDSzE1?As>@~=So zPoVsNQ2qxfU&93mDPk033--hy49z*y)q5LyYzNiJn z{0UDW@?KEB$}2LHRbnA^bEb|HU5&zZJ?~@fX711m!#Y zgYX|g`3(Ode9+ob(0ptLl&@d|u}_786Wso{g7O&{A^Z?1{|A&m3(EIlg2>;7@;R6x z{QpqC0F0hM{AwsahZiEh5X%1o;pMmmop?nr;i2j98z5|qh z70R!H@;MzL=52xUZK3=(P<|nluOS05Zz+_Y0Oj9;@@GK#{7w+_u0Z)NP(F_=M1Lie z?*iqogYtWz{KruK2`FE}8Dbub97Mk_lei&zXQrY1m&NA@~=VpH=z7iP`2@Q{7Vq`NV`Ma`vb~1h4L9L zL*)ITd;usw7s^k7@+U$08BqRuDF4D+i2nO9{yPX?z=MH-kAs2X0xuW1{Ir4cUqJcE zAU)f{ze>7L>mM%CCX)cR=}bp!@?+{w65@1eAXf%D({RgVu}lGcqt7 zfUZ9iV_;wa@qgTbtjAJ>@=c)ilP;8B0xdr+q5KsJknnVc@>?E2^anusJ`W*$(ET?c z^BJJ){nDWFB2OXmg;4&LXApi3l;80j!f%K24WR1-Cqelx(Du|^D1Q!=zY@xCfVzJx zlz#x~{)13H1GKz33+2Cnn*R{Wzaq;BP9N`}d=WVa{|A(RKor7fXM}`b090NG#+QM} zD?s@sP`)0N{{X7r8p@ZDgs2aM@)tnm6QO(=D8CTO_kp^v8p{760@2?Ijmup^B_Jq1H%Vs`nd+>8+?MK&%0250hIp)%HIIx zzlQQZK>44be1p#r{Xao`b_RxmSCI6?z{J474=TT3L-_0rfnh%r1H%C(28M%7 z3=D^u7#I#SF)$oqVqiGR#K166_9}pOcB!Cm#)*%QR{?L`F$7CPmgV45MA<_M+*f@uk6LUsi~?1Qi&mO$7LTOe$RHRwBy;^RTLXM*?9fEA=< zmVq|S#K(hfSA}n3ijR*^%d7xz$AK`xJ9JVqK~6}^tN`;$AUyakACN*A2eHW~K0Y3_ zMGC%E2+D`=B8rcX2RjDra`2|A6!5mA`1p7*53(5vwEGTn`)Nrg*x98BcbCHTV{X}s z2W{svU;tBw5XuNb8AB)&2xSVP%pjCGgtB0W2X6`kS&n<_AKHep(XD`xjePL?hX?Ui zz<3o{?kK4&NR7|TOUq|~ZOPMv++7-%>w zN)r?TP!>lK0OfNO0Z^7f5dh^36ai52f+7GaWKaY^MGcAosK7xH02MnZ0*07QHAI9F zJS5{m7v*6S2i;7G5RZ>X=*Uk)h{G<@%*jtrPb~t66{cizeqKpxMF~P89(+?MD9AzL zy2j>a2sxOE@JsdLp*PB67@m__k_x-K7M>m;+7QMSB<5u%Bem9%6O`Ve`&aca6%~QDIOCEAxdGt-RL$w2J<-@Tg11X! zmjYisjT9Wv>p9~=ZU)%~%e2^ar)6RfbdYY)HJfNbiQ!;yfK=l05$JMr{3=q55<&aL zVUA16FU?CSjt6g0hWiPeO(2OdGd~Ya5~>4yy<j6G7LgXXfV_nIe@4g{ArNIHdB6VH?I_krIz7l$w{EpOOl4 zYbwGiko!X+wFkOrQe_E-N{AsTSWPJ^&BIV%YG#6NY$m2qGU(3OqWGNrY2&liY_xx4^;dX<>!DdpDhQ~eVKWB zpn5O`T%g7mrIwTy<;8;!Do8C!ErRJvttiOJOwI)D<+|;}hsItslsOccbrB;;0 z7grXSq~=0pp^hoaOpY(e&#BDKFDl5$EQZNKS}q_{Q!5g43vysKB^DJWR)Rd0UX+-d zi*O{UcmRbY)Nr`f#i==|$tC$k@t~BRT3if{0I;_T5{pVQ6LaE=%QH)oGobolDH_$% zq|B0d&`run7Nn%6r4|*XLc$jka*4&o`N^5!IEIC9QED2zW>;T1mPH}2{enDyx_zrQ1>+*|WoiiyunEXhdCO)Np=w_NaD*IB@3YT200x z4i?a3UxrfK?=e`&ppNj=?&h3Xnum zb;f5F$LD~2UYVL$1XT>y7@wE~GabYPMNleK9(o)I*gB-6S8`Kx_3|=vK$ovNMz8(@OFa89=oZ zSTrraC^xYr9&&*+LbwQ=gNidim(mxPAjC6^VVA1M=cT5D6CXkn(s+zd$}A~H2x8F@ z4=&PS?n2UqRU!@4r)P*SElIP`gVa^fstRgAd`fC^W^Q7RUP)1AF5F(YXkszwv=2=2 z;*89+lK7&`^bCae;F=(kIjL#5LK0kakCEA|wF7s!Q@AEr=p?Rj^b6Rt3(2@sM@_q|E@$mS8bR zJc1QM390Ic;9^6Dh@IcjdX1-ote0dQl{Xtv?u@{oY zVC^Bemek_p#DY`|VW_uZ)~Dr`=#_vQGdXz-@gQDt5(>8*3oi|#64X*D28{xgK>3M9 z>G64`xk;%-5P{6R5=c-c7NtW((sE1UlM++n%TkMykVNwHa}Yd;uL=@VAgvpan?Mc& zjw(f$pLQsnY{Vf!qPk!XVlB0#L~fVu7TfnH9!G4i=C!w50*D z7bE~}`9lO!^Gb8$!L=+X-qH1fWFhK`OY%XD5Rd?F<|Tq`K2B(*3vGY?XyWq>MHy~@ngoD{g`g8cj(@Gu3c z2)d16WvJGIg;4AQi-3BlC5gq^sOA;q7l6+y0~a??r-7BHK zdZ%k>VQC3B7Suv3D$zBxG%!GjL4yJ$YKRa8IT9pfgb;%I4x=Vyaz2$(LAArMzU8j_jC@dcnh475QBQsS%ce_~33D)X_z-wj(qPg0fs< zQgMC`=)kd}#Bzkr%wlkhkT6}39xKR%t zt4)aq^(i6!KB)cR!4#0X%-r14643BoJh)?mVpL)-nvYV8@)ALryd)l!IYBL;)D$Eg z;Nccz72x(CE(OJIGqBS z;=!f~6ul5xY|)DdZqPw{;GPpKT_U7%^KnK&Zhi`WV~Y!m@Mup@#%nU9L5`eK5sm_7 z)xy%mB5+p}n&ePYM^1h^w(tN4d^`?GP+%40gNJ0W83`?ku^9`}iJ4^)&INa?aQGyz zEVZaO6*QYynv;*qaP*uGI*Ji%Dgn6!T`@sJi&IN5b1+J9q7@}5a^NBXmmT2h9=p#A z^2<|;;`7tuOUiNjyEp@10xHhHnI(!dum%sVG7u3}5EVJaNw|E3Q6$0x0~`>bGLJyn zNJs;EK?zrnrBKBvc;SjcDFIYOW0bpa70Eex3gCjG%-mGaKtW1oS!Qu2czyC@ z%LkCgvcwW_ z?*|mlNNz%xiZ98}2M?Iy&>EkeSd>^&T$+@K&ybAFbnx&eE<-@_@yYqQ_)SSl%t_2k zM)oj@Yl{nu2)hQP2%ncyGRxwPad`zKS)7~!?(o558SVyOl(hM-AC*`R^z(gK1C zi&INLEo)3KrxbyllbfGXno|lMQpJ``aAa2`cjKs#aHxpSPeHE6;i_`-)8laz@o+Vu zh$zm;iO)$zuC39ei_oM&ns79t(DEQiB}TIeR7_!OwZx|n0k;WTQWlA6;@!;MDrVO|zgCd+*lAno`7m5;7GArVXGeHB*aCPyS zAXAGH%j45Zb8;Bsi!1Yz_2Sb?OHwPqeOg^3b3+SEVaU7zXk<6Pv;?Ha5>*YT5uKQ$ zYh-R@fGUwxl%JTAoLCIfWMl}HOD-)c0@VhPE^$0)x(w`&T(C1h1JzK45P{M>459SW z#G(|aBG7<0*zL%Ch=ZUa#i_Z8@df$d;a-q`!Tj>XOwbr8h>!3-R0Bi+#SDlL+&fT( zi6!~DnaS}GcOtnGMI6QbP#JVbBMYP03zYyn8OaOC!bm=e#|TSa=uAvcltPJL`+{Eluv=u=) zsd@3qAeF|(<^=6AHZee2w*wkD&r69<%}LGGH8eIcL2^QVQA#Rkh_)ydbkzVz)*ML| z>nPO+|`iGewCqYK{D2USJ|iOJdV;O>pCp^1?pQm`T0U}9v96zNcx zLTxuOvM@oagD_0jH8e2>B}{mQgrNd%zp)Wg?nSZR7&%7J>^BCLcDPN~H8e3XGD5@* z*j%(kXKG-E6tOd&ItAQfQm!(>og4(jwnQogRCsWEaKL*oV%FS>@N z=Ah~kmY&g*nW?!Yl9M34NEAou8k$-dAg7Z2f=bAg3M9Yk8k(6KA<1L<8?@{Pl3~nE z%#lJK8op?@nVXp)IS90Nt*8tw2kIJ{n!pnp)t@rJ%7G@I*dBwV4q~ zszKoknpX$SwL{aUk&%HZC_TeEDIl}qL#^qlCAvmN2B54B3qEkbq68i&0qGhU8G(EU zQw1sOQA=i!8gon35I_vBK&&zXO@ShEaZY}^k*<-E3CIBm(LB(~Gw5J2W|$b6f{JwF zRU?-QNO{)C*w6x}V=-+tF|b4`8^M8;n3I{Fmztt$WMYY&GNEY;B?xtmObrat^`omW zG)Bsupt1)=0i+BvGBq(qYIlIsov8_O(uN8lFXM#@St4aVoW`4i0tG3SQ!%r@k*OI* zi3H6_rYLnFtn>g?oJOW*W=QtOgRiCmtp6As4-(|jvO;EZN>SCx<;lJ$kiYyJV146T7G^>Y7u(6HnlK8ayyz8mWD_X0yYQH zQZh2NG)5}cU=BcuSY0DCW8~r#IgOebBeyot4L3J5KuR%SXQ7x3%DCW?-^d)L^aHDe zr(Sbo3#60@vIEr+&`K>`BXbj!2uLi46fe+JX>NjC$>H#(xrqrE}0jOVxoHCJe4fy^gT_X!a z_d1HKr5Tcw(DhmxBFlo46j-yak);uGf&$CHqtg=H!~?Ct1FbtOfh~pA%g;-VPs~d% zs*F!5Pb^9U?d`x+l$2Pc3!Ym;TSyDmU0jk{plbxGeb8l-QY-WGQgp!;DS`F2dTIIj z25`&qt;_|fG=#f`kV+%C%iv2SL48BWf>flXyn3Ly&&<4%Vz?WKP!C?gQVe$s5jr4a z+{JK5L8j$F{Zl6obMAt`okz7q%W0va(pOJR`9rJ~2KG zw5%g3H77H*EEVBn91D*1z^hLnt7qUA5Th36P-4`=(ho6eVd)8%+QgI;U2vBvGfxkn z8gSzbkD8SH(xjYJ&{C_!++tmD3looOaCU=aM003nz-c*T3@23=wptyR!qkd_#Jm(; zaBB&V)di&`x}cp-;EapQEYQ9YT~JeqpsIM#!lw#dP_c+tEod7LXupcCA)y#a%g@(^ z^ilEnBDXY07t}HU+X)%SL|Wdimy($hpO{=&npupju1rm7O zF+3xJM@K+Hux0al$wm3ah`fO*pOllB0k?v{YInW-f>iLfIk4XdDF!WiE-gxh8;-Kf z9pbKdqZD``V3RgZ!J!)z6R^C7su5Ji!{U*YMecgwgr8d(4_-oFl3xUO7-^;;82~Fd zFqfd~LHCLn!Y#qA#t0q+xYZcL695)9Y5Do_hVa@8hXNybQA1!|JhT{1%1qD9D*-tl z`$~8{XpIdT7tK#5LLF!j735O_#zFdxAn!ugLhGR{=LRjc1+Ah5r+DltKs6*pi6PS3 zS>&~@dXQ=2Jn+&ZkkdgcC*u)IQ$eM1aVnAkObuwwC3F!c$P6emJ|#0PEfqYkk(!s1 znV1J!cUF*-SORi6vR3dKOvv(J&=S*>)D-AiSWHD}X+??2px^>I4P-4uZyG305DNgo zYY#!==aBubppp<$i0C0NHq?uc&&kXyt$;4eglwAwl_B70gRN#Gw0KSrx`_?sR+9CA z`VY{BbVS<&YFd)22h;^5RS&3-K&l?l_$aA*KpjL<^?*8#r0M~UI+3ae)N>(K52z+5 zJt2^j5DS_Iot zm6BLl9G{d5+6D;Tb^_kH6rW~j23`k^EM#niA!KHPCInuLPz>Esl$e~HT2KO-yG;k} z?E~*Jf{KCG1R!mIaq)Eb3<-|+@eg+m(lrE+5@zP>p^BP=_Nszvq4;=Y3CJ!1xL9aF zfNKya46v;#DN4{081NydpS_uzK#*`o*}M5jv=1@e!=lUj(#rwzVQJ; zp1!U~b_6-Pct*sBI6Cswyri0&N{E13L&j3kKd_7!TQvh$?9SifmX`fXp9(Hju$~Wb5i7 zrz2fMBU2-!asrQfa1*;2qyc##Gd(9iDKRG=$NW5KSP?0BkrM%O;s_0PbwSMP5jIk# zB&Q5~$Ow^UBdL#%R{>{u(4i*a0W$D`B?uu9s~DREX!HlGM1ERYacT)xDe$lfR+*B- zbeK3SsuGLRi{s-#J_2=Ii$F8F;L;N$0?kvQ!LISXo<2UVLGeM3PM&`8{(e4@&|F+v zoLU6hZk(G~0^3v$)dfnHn5h=L90VHFAhs@eY8!l57Xt&suX{WP7#PGv8NkPQfkj1r z-Q!_mU=U+uU;%aj8CI%iTA3w#}0F!4-NzKjI11$(` zeSEV)epaiM&+&w^%YQdAo%;RdH^0xuruN(Yi&+>Re0^8Qa3=WcteQ=_yc*3et8-`l zoK$BL$n`;R{~a+CUhSm}B5Y@DI;DKO%)jjLT#@muVbVm`*VU~jWG%{1E?4!4x4t;v z_ul*DA07=%B9|xbeCK*R)Lr0BbW3{B()HOq&Ou9GnckV5+!?Va$mOW`Vy+F`Q|Fpb z4S8FADdme*jkvc4-?M-nN~iLYihsE-~N`5|6FBnz?E~4!pk@1Fob*B1;lFjo=e@Q{3fhxo;`bK zhP#8{9D_YFV$V4nUf6WpxV~+hIZqUmyZl7M{gq3mObrcFxp(CE@rnQDN7T)q*M4)( zfki>*4xjS3KRzLIn{qy$ zHQUYD@+oEJ3K{XOHak-0M_=08@8YX5t@2V!n`+vR88^E3AE{vaF<1? zW(zC)s7p5XJhIpEOybF}tKCFjtlv=6W?Fc5+TOh{s}CII-fDZ$WAT$;7E$Lt7MGgz zO?+IwA-h%JyY;Iq!9M9Cx&5b;OvRZTb77>wfnd^UuD%FVqn{_VYv?`v zRb`z2G+1i+Z3d;=c>zM=$1m=86?+(M|Jr7OgJ*z^!Ry=g^SS4q`7&4Qd1CR-Nwb5$ z?`^p-o5Q_YMgEl0jIu9}oYVVc_TB2*)b{?sPt)6{>>ar*9jBF1cQHLbB$y0_U!(lyWYu&sC|@`wknbu5l6S+vCQOa_e=KhVYkN**@BH_C58p zt-jo7q4em{W=Geq$tjzIg^f1qwD<*Gyb;jrnjF5lOJDa|pGC>rSNoecHLkk7c!7u9 z&gA+y-Ft5C!&W;zwPy__X*zRU%#|O_V6-|9My8@Auu(TzdHxU&Ynzhc8as zrwNG%uz&M7+sG}~-#7D0|FL^~w|XZSc{*Pz`>2ANK8xgcZ07q!#WmV2bJOM9kL3$rl?dmoKVxc;zCrGbmE6LA9x)L%BLDJdwk>O( zmSOnn-McBDT$bm~d4BDu`r(bjA*+9{zBu7v;6F9PTjpU!OTSMmk7734Hbv#NW`pX7 zj*SaKS!}P*%!r-dsI>n}3`3UOH;zwcUYaS7e|PQIT=e=tnEWjJ(&uY8R5p~v#Bb=j z@#tKR$|S$l&LL;C-OJ40O`0IIgu}(4o&EjmgdcxpG#*X*QYqbH&+vZpE_a`jcQ0qE zGrZJvauQ`{b6mGct?Sx+XUkU~UzslQS87&wRo)n+_(gkb!4dJ@x>iRy<;3=1npN~l zgJr(XUVY6kVeO00ig9N*Sv1x!v~y?r?ELCZl%%wS{t-84l@k*utp2{dg=?quql#r5 zyHgf^J7_ItrY5w^WJatiN3KG&8ROHf>m_cgu_tZ*f2U(|(sq{n0vio;H>~}3hWE8$ z(e2IO+g_DtA6UHJW07*d>VJbpT&eS=C!b+$@h&V~V6t4b%63uywBi<}z=E~971uw{ zeSahERR64}ya&PsX9P`LDDa0{QGnsfVxz;4Kepa+XFrm&v+?)7jgB{_Bp>JoNy&&|Jo~E-`0d}+I@8$_tV+wGn{fWdBb0wD&xAHA-;Ua(~aSA z8BtA}_wvl(u}IweC;O7cU(01@w;rGR{RjJvtOcje@RdbOEEUP9n0sG%&y@Sct5^g+ z1bQ;{?zva8cAwP;Z6y!Us&xmaXl<-?U#j*mJMsOiEq=W#$~b>d{mC));gk<278o8n z9g&ikUE%apen*Sf>%dbNPTKLmFWg+5_5JD9pmk=3TR(o0%UH_E-nVkyv9jL7Y;(5g zZMnN+)}x%BhZ*y-EV>naYm3il#1!FE-b>tj=!O@6?=&(faU9;KGzbCRCb?UG6S-9(BlXc!c zhBI^hL=unMt@*ZepZ2@|@4jXBX75k=+Osi=`Tdpl524Mc5_`XSm}Z>H-1I5+o}v1G(5kAr;Z~om>KJG1q*(vD zF>}Sv#OM<}8a11e8T3}1?fiYL^7oFym!0dUW?pbPFwreTa_)Aa(|_57v;5^A%RcuE zUKzr-;x~_m&G-4YrNXDX@;X0AjazM?|5fOMo<`wDuSIKSl<6<6IX>6<=$U=%(xVLg z8YCY63kfMce`@F6;__?THwa9A+PGVB{<~MrZ=Sx$Oxf}$Bx2nhrtVYbZnKv3e0wRV z_4#U2=N)D-hWFp>Vw((tKRx+->$sLM}>? z7AgyK7XCLoU=en;?fz-byT`DZHksXtYUKhG4kW0|9E#!P`d^V)ui&N|+cae&t~P(<^$rbFAk)r!1- zECV+@zJ5z}vCGMybLMWdJ)gQHVf(t^OzG`ixp$7eTkD}ZJ^#bk?ce4J&RHMe)S;u` zn!R4CnoWAkA8#q1yOVux>^{M){pyfM!4lJnUvvc5|C_-$!|ch0<(~u@FQnXRxRw^K zdyMJeJMPZ?j3=XfvM+sAes${I9q%W{*QY%@UVm|u%K4%ip`0Ms{m+k|oAcax*Zuw1 zX6TpMZ}gmft)Sh4(Pd3d-9^76H|8k$S)Ol>_x^ZnT7<&Jx{KRY?Y?*3@s3UuRD5B* zCYD2G|K2>qs|kGkJ0+QJeymS=!l~8h@9}+0oc;O!1F!k_?%BHjiDOBh&IGRb%-K66 zyk4zYexUNIOP66e!`kEg^MWLWl$ILKo;#Uy`k50_yxt+18El81bako!`rPb==4nkmAs zJn_Q1Emxm59J*WP^(BJO_P_hQyyC6SmA;a8mWS3X3hoeoSi6Vo3QJJU^$kZ3O`MW1 zboEN^Zq>CHwHrFZWHUT$6C&MsF==$ma6fE|qqxPf1N) z+wZ56WVwIl%SGmlQ}P|8DovBD#s8eJX%I7 zBj2>dRja#a%3im$7w23raPf=GYr6T_Z|6EbudRD0-Yh>J?`*HA^^ueP)|n?F&WkpO zrQJ>t&Yknd!FB)3?5xC@f^lqbHZ5W}rKj&*HG_WswYy9H4%eU^E3by$g4z~LOf5wDQ_$t2M zEIQt`a_2hsKSpixM-o@eJi?u(+;C#)nR)*iT~GBLoT#*#v-tM(%qx4|Bxz?aOAwpz z$o7leh4kh3{t9e1GCyjU@Mz1S2Nv7k-M`lK_UMsAKVEUZ`+Im!?4zl%pHIc!TvED3 zZl0$1zp`9A$Ji(t2g~)V(|-N__iod8NNRqvk4vDRdq}5Jnhjlg|0?dbFLQwTO-A0yFDnsTx@u=j^)-p z*Ll~D&bgHGIOfV7i4E-1yX@s8%nG*OGW_T?i>0XAefH|#Sru~Me=B4OyB^uJd#Qi- zvI_T-YrM^M=^I&f+wS&vmA$-WpDiysb;I|>)93E`zB;Q}sTM!!${w3mHz$M6$_tX4 z8ZRAiKY29e>SQm$-QM*NqOMCyJ`_mT%XQ+p*B{WB{Z?73A*a{!$L|@RJi8Yhn&$B| z@|b?LMZxa4+44TmZ;LGQ_?^}6BE>DWRnf{}YX32@#L@?CXXUdpDwldj_-#Jae&EIZ z(%SiR&)hHHeChM|sL*-xix+7X#XdE16FM1jY0nK``?dYjXERdG9v$*&{rUg=?>YXP z&5K&&ysoBq1S?+Zue!me%E@~F0r%D0ooi<{t$MfX=BItPbf>KM-MqM2RrSktr#p`y znqAu}Qr^5t{8H(KpX)lp77B~Zdi1w>kMnH-CgG#r79zfX3jeGV$Pi(_UDHkrL+>>XYYeVb zxX!un%|89g)p<;s%mqcIQMsFx{M`@D47Ar!acZ9Qb#ceLkMlP&YIw0N&SgK}vG(N7 zH;Y!?&U?s^KX=D@#Tt&|-N_4V)k`OI;Z?){f$I+E@ zT|S=qDgQy(%*#_Ya&p+tUClQvJ{!hg+qtCsYk-T1#KXDrH~v(#n6GJg!X)B(JBRl0ESYGf&uKGXtewND7(rW~lMHRoS{ z(fF3sYK6~NkNsObb+VkY+Y;@B69Rj6Ev>q@y1fp#s~mCbQh5L;N7=^A-GbGOh7-K6 zOg2I~Sn~3l%z>v@w_n$po%XaglWF?J1O0qT zK3fcxFUlX;c=pQk!`J41FfHL;7`<(++ZMjxzpFeigld1XJhAY4&u81jy=#RN-RtBI zeft(7_Puz<=SvbtC+8#e=r9-TVN zDV4XZSvTY2;*94}e-*O7%6lc&s@;!R*KtUu$jKprk^7Uw{X53Y7d^LYF1eY%d*;&H zwnYoF%Wg5$t(~EG{>YX8bys%C&su$W?NlR`qUW{~HTHj&5Z_i6Bss(0dhy5ksXiAq zt6s<7FXnhA$g5Y;{US$>o&tBaF$PHIF-Ep_Fkp$&k~D++q&*A(>)wfdRP7U=Ofcs zi3Q$n(aD*isC8xf|K+^p^K{ycHD9`$-`W0(&&ORX@aYL@QI<`NzhuOO-`?n(crowh z+v22Ig6z-JG@nV%J>akMmjA^sx2-#@mKX?hDA!p^J`rl~ShxDM#-$~h;>Ut6wN6c_ znU$Ky!Rgwwc+Ts!W*lp*SXMnu-OJy??VP++q(4e$zLZah>zrSqnGaMG?%sU8q97n> zJ>X!V=ibF)e0`}gkaysl9j+g6^+ji1}TRaj-uLB_b>eE*nbOIQD1 z-+kxndFlA9GVNQJ8IuoXCf*a}T$mRj9#PI6#rZ5{PN7Dfd*9>OyAPgkQA$=>xk}hb QO=srBZEM{+UrsXw00uvViU0rr literal 0 HcmV?d00001 From 7bc21c6691266426824d7a6033c6b8768a93ce70 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 13 May 2022 14:19:04 +0200 Subject: [PATCH 210/245] Allow CSV/TSV reader to read multi-line fields. --- .gitignore | 2 + core/encoding/csv/reader.odin | 86 +++++++++++++++++++++++++--------- demo.bin | Bin 710357 -> 0 bytes 3 files changed, 67 insertions(+), 21 deletions(-) delete mode 100755 demo.bin diff --git a/.gitignore b/.gitignore index e8b3d3050..4c69a3f43 100644 --- a/.gitignore +++ b/.gitignore @@ -269,6 +269,8 @@ bin/ # - Linux/MacOS odin odin.dSYM +*.bin +demo.bin # shared collection shared/ diff --git a/core/encoding/csv/reader.odin b/core/encoding/csv/reader.odin index aecb73d7b..f8f1d4051 100644 --- a/core/encoding/csv/reader.odin +++ b/core/encoding/csv/reader.odin @@ -34,6 +34,10 @@ Reader :: struct { // If lazy_quotes is true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field lazy_quotes: bool, + // multiline_fields, when set to true, will treat a field starting with a " as a multiline string + // therefore, instead of reading until the next \n, it'll read until the next " + multiline_fields: bool, + // reuse_record controls whether calls to 'read' may return a slice using the backing buffer // for performance // By default, each call to 'read' returns a newly allocated slice @@ -194,32 +198,72 @@ is_valid_delim :: proc(r: rune) -> bool { @private _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.allocator) -> ([]string, Error) { read_line :: proc(r: ^Reader) -> ([]byte, io.Error) { - line, err := bufio.reader_read_slice(&r.r, '\n') - if err == .Buffer_Full { - clear(&r.raw_buffer) - append(&r.raw_buffer, ..line) - for err == .Buffer_Full { - line, err = bufio.reader_read_slice(&r.r, '\n') + if !r.multiline_fields { + line, err := bufio.reader_read_slice(&r.r, '\n') + if err == .Buffer_Full { + clear(&r.raw_buffer) append(&r.raw_buffer, ..line) + for err == .Buffer_Full { + line, err = bufio.reader_read_slice(&r.r, '\n') + append(&r.raw_buffer, ..line) + } + line = r.raw_buffer[:] } - line = r.raw_buffer[:] - } - if len(line) > 0 && err == .EOF { - err = nil - if line[len(line)-1] == '\r' { - line = line[:len(line)-1] + if len(line) > 0 && err == .EOF { + err = nil + if line[len(line)-1] == '\r' { + line = line[:len(line)-1] + } } - } - r.line_count += 1 + r.line_count += 1 - // normalize \r\n to \n - n := len(line) - for n >= 2 && string(line[n-2:]) == "\r\n" { - line[n-2] = '\n' - line = line[:n-1] - } + // normalize \r\n to \n + n := len(line) + for n >= 2 && string(line[n-2:]) == "\r\n" { + line[n-2] = '\n' + line = line[:n-1] + } + return line, err - return line, err + } else { + // Reading a "line" that can possibly contain multiline fields. + // Unfortunately, this means we need to read a character at a time. + + err: io.Error + cur: rune + is_quoted: bool + + field_length := 0 + + clear(&r.raw_buffer) + + read_loop: for err == .None { + cur, _, err = bufio.reader_read_rune(&r.r) + + if err != .None { break read_loop } + + switch cur { + case '"': + is_quoted = field_length == 0 + field_length += 1 + + case '\n', '\r': + if !is_quoted { break read_loop } + + case r.comma: + field_length = 0 + + case: + field_length += 1 + } + + rune_buf, rune_len := utf8.encode_rune(cur) + append(&r.raw_buffer, ..rune_buf[:rune_len]) + } + + return r.raw_buffer[:], err + } + unreachable() } length_newline :: proc(b: []byte) -> int { diff --git a/demo.bin b/demo.bin deleted file mode 100755 index 5f8c90ed9a208aabdfee04741d4f2304c9c4a40b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 710357 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

aXk2E4CZqJkm!Fw_X0kQ}z5LGf6Lc;+ ze9gprrl0V0)yqL=!HZ3Nkl$$g;xTlM6==T@(wXa=pmQ-n>)b$b1v)GJI@8Zbmz{n- zzV7t%NhZUTm+=liUnE1$y99;XD`v5Ypt+0(>5bsKhQN0wv4i$qF#XhKYzTVI&G7T} zX(q@S5!MWlw)k$Qpa1tW{d~2X=_i*cbPS81;pZ#RdFx1btGcMiQoTL(BdlVQq(W`6J)7vO#NptExXp!@8V z8GZ&{fZkW2?C>)KG)D~DD+Idt1~jJsoAKv=&{#h+)6Wy2HD=(kG^U>~pz{f!b#UPI z_@MQ2pmS59a}uDteL!;+;JwJk4B$IUU&u541f3`T0<_j2dQR(uW>DLj;iuLG#wo8r zXKNsZ4d~7t(0szH*Ni{8B%pBtx})bYWs|KB0{lA;>=l_1jpZ_N_ z{(L>1@h50sJE(05ni~L}q5U5^p8&h3=l^a-@H!z_d-6rS;qt0dlVcv`zW2*zxD1a?sjz zu8Ht6%$?!q%XsM8bkJJfWX7K-uYt~IhOSMY&#?35dGOlw4Vnj~C%y!&SIcJnsR_!9 zpml5ckagtUhyPE11=`<@9QL67rJysj!x?{Sfx@2Q(Wh59*4u;jor2D+0i8pNYrXxS z3(V_C}oGA4?z2}%o%=8gxd99-QnjuZHJ$)qaAj>ig(xvvKzEl z3A8@{t-Hg|H=uSV)D6$l9e%#w&+zlzWrm;ct~306cbnnoyZa13L2b=Ppm~GW3_l-% z_M?7g`1uHQKkaXZpHH1xC%#?H@be95Z&xzo&R6M-J6~>R`1xWtXwN;UO(R&&b$;8=@bk@NhM#AyHw3-WX59H& zpK&Lsu6_wUyO|FZ=b(LA$Z-y;f4doezG`Rq=>>}O2M<4i<^f>!^(%D-$R3Mk=7|ri z8*E=e?=yH%@9^^>=T$KObc~{Cu46@UuPxw8sl|zd7pKXzq(I7PEry1%TZd z3|kWhx>Jf1bQV~n4CGEJP?`np9mxi_`yg#YN6Vg8Ok zUobO3+@uV36KEf{vg1$CS%yt_8iJS^8-ip`{GSfmI|EuD#97NR+p|(*2WWlU^Z)_FIDXV?Jo+n79L^ zp4r3l1ZW*TNDXK$z-PyuFE_JKeD$7jCu~jH%l8aFPck)t@0NRsv?h%KbY{(Awuuk& zL3gP!`~?+~McL*Wh*dkTwX~9kMUd8K&HZ`3tawwB++T}XC;kWZvvxE5 z1lj6q&R6R} z`xsd#zVK(<`GT2s;www|CNoV0t@Ay>)NqLdbT=aCj#khe%GL}& zA2c7gf!`Tr4s}0B+}zjR%iGLyECdVongu?@VY^6l=d!s-C(oPMetc= zpnI&RGyHrq9eTz*X#Kmh5wzVYH}R!6+s{nUoksp_KVLYrfzlSV+yI?1&-U}bHQUes z_G~{NC?B?c(QG*JfpoL&3u~}CaNpwvNY2{r=RBr4x*!#elXYZ@S1{1wO_j)=r{Cq9V_Vbl68)6O*bS98E+t2^pY(M|=v;BO) zec1LDv%$m%%+0p1xY>Tb0E@Z(e8}(i^W|^WpD+Hi{(SV?_2=XNu0Lhd8K%6_N4ocB zI;j84`t$#H)}OCFv;OpwX@J~a3|i~+o%QGc*Q`JPzi0jV;P)ZhSIqhoAAD}Ief664 z=L?Y7YuBF--@E>Nd7Jg;i~FoUAKiBS`S`x;PZn%;TxR|G|2pf>SC?54_cUvR##LB< z{y)w7^Z$9)pATMx?9iL|;Bk}ftJADMUx36;yZ(H5-u36p-K;-f>}UP?Xt(Rn$NOD> zzD{G9@*3SAn^}MU-_H8;RkH5H*Xvn-zS_+C^A+d}Ux$aEUWtR|Jz0PLU(WjT|7zBs z4{n3j@##!_aK6d*)pFLKFF<0;U4K4Y?fUcOWY(WArnCNhG}-m%(BqqtUv#^v;KT=9OM@5i4XQS*}iIK{rLhU*6jN8VY}V5)}ODkS$}qc;%~vjPp^y_e!j|Q{rNwc_2>U| z)}IfygY3|n_+WjL?W<(gpD#dS$*w;irn~-p8O-|gML6rvN5QT?ABVgCoRY>c9e%z5-G4RR;pfBu4trlKYfXF&%G>U&KmU8P{`~LH`twmY*Iv+G zchK1O!^vEGvmF^GzE%dU@!;C~nptb&8)w#^udP{szOrZi`QMoJ=YMn7pAY7P=D#&3 zKA7HQ`^uR0=L?XSvFp!==B__qDzpB4q0ajAk+SR0$Lg*>^FV$F-P?=gme+?hCjOUZ z{rQGjUhBo$zD6(m~-uXGuvzD8*8qe|Akq9{ugKc`C6Fu z=PPm6pZ~d8fBxrZ{rR99l&wREI%JqgUnW+_@Ee+ zZy;+29=vw>`S88V&zHAZe!jTR^7GMcm!FUCyZkf*nGM>Tk8U<}t-$MKwTW-ev;2I0 zndRrJ>yUNN|4+00e2@)_TgckySH~giq#qo2`T6j)%g>i+>zrlN7^XZnci0OX+XtoV zNAn%_!tcSF?(p-$Z->30IDXvEwRaIK!`?<#hP@B^x%R$xR-Fi5HxSLa^IgB!&Ue9_ zJJ+&0?0g%}xwD7WVdtA@&YiGz1g{sf{Cu^X<>&v|EIj^;X2VONR zPkdnAWc#X`<>!lfP<*)jd|2=D^JO;6&lmYDKObeg{Cu46^7DEs!xT{6@jsd6=l^t; zpAVB=em+Wf`T00m3DgFJ?5_fy4d>4Sxpx9|Uso{8&lOJ_f?llV*a;r9`pmHN#d?mN z;P%-;fr+5|`Cddr*FS^yM#e+dmw@&N8XovR9W)2^+8DZT3OOygL)Ia@acBAY8nhn4 z9A@`u|E9e@8SN1GFUpTY;d|>bL^Pw~5+JnWQFhoyB$}B(stF!!krOfj46sVkV zc=YL&I?K=h(kws!%d`A^APkBlg^3Tin`~c6v;2Gk5|eiM`B2{F=SyyupD*}Xem>%M z`T3aNKQ?&D&sypKrn)e!hbCAwc2y`m@7MP(1wyt(}Iht$y^Ieec8n?0X+D zbL{;OU2_0hfAHur``(AI+4ny9%)a-%viwBQ`hx$jnScI&54{I)I;c$|Z~0D;VPXep zU&U-wPVs0k3s_-e~*&F!RrM$C-b=IL!=Miw@ckcb@qtXnnwoW;t-% z1iW71Ib^-Ui~G($LFY_?$K;^*hCkfx{PWR%=bw+2WhcG`t&v{M{8Q&uL(rRO_MNZe z*>}F$%>47^c4qKC!UOyNPk#+s+dCPpJ_W6zUd;US^?c@^ujLvpaXUQv^cr;jGHBg3 zXx+eU=ARCdpt(euiQu)=)0uz1K)Pf7Wi#sC>ISI{Q$Y8$f&07noqxWpX8sAjQ@z^x z=fisEpGmJ8f|QvWf6f@bkg)M%xFg8*QI~ z+zGlP-JSX8183)-58a)AE&{oeu_5U3cZQwEkN%&Io^D|E3n=Y?%zQAr(e}aoM%#Cn zoqwKVWta$BQ}FJ(^Urgf3=`j(Gyi;d+xh1?L57L%plcUEYYM>jgVt@YZnS+7?)(#U zA1ye3wV8kZ*Ju9uP}}+EBYo$ej~7c!d@IiU^Nlp~&oiL-wPxG-+MaFaD`n=NFV!LO z>#_g;^f#dS+sO_;UuUDmF+cOq|H8~a-|#d4d@aoU^FL^90XOqchl`+bDDjC8>KkoA z_p!g=2JIPe{`rvG`6p=X6Li1&qt8x1AAfiHxhsWX%EQSHJ0C0tjZHHAxzTV9AGy8Qz(Ccj0 zov-p)cf$5;vdw3l0@@D>I@=jJJ%ZL6{9n!V^YwD3pV{)zyn%FPs>58+xfGBw&{y-B zej=Zh`V#Go)T|VSDIoLF+b5v4=CC{2UxUtF0o^GHI$x!p>E{DyP#G#b@qu-t?JMXS z@dwpTKOfdR{e;~k`6%1z=i_{*pFz0HZ)BMGAG#hKw%!1AKO}fPxG~6l$eIMud8sdu z*MXzm!ETkpFy$3mx_a~237nr^9~PYWK)%uTfpVkm+v`q0-&%v#?mPW_YtQua?R}@8 zur&&>wF$3{A@{Ar##%w^z+W*7PJAHTX!{B_zN+o?^P#@e&zI6nKVQf*{d^?t^z*U2 z(@zPIJMvM}H)stx4-3PDo<_NeZ-kkCo?&VTdLz#C^EEfq&sU(m(9pF957`&zG?A($@{Ppu0O>Co}K-pUw=q*JCx~&zI{#`=BA~4PL%?{Q2s-<4xV8 zE;rb|1g`~$tdV`$?eOzOKXm^f=)OHh&ex}S7((8F?gyIg@bl$lho3K$c_xC-NqNjY z5p?(Ae`e;LuV*{{%&yGY0XkRw^?WG%Khw_Fi=k|0=AEGR1fcs8UzIcd%u)dL(;j^S z-IWMCQyg?hB7A%SG*%2<>kYZ9o(sIz8@z`Ubk}-1^sf4B#-FhD-r#l%XnX-Q#{=7Y z2|CBdpYbPb?Lluc1N{7LP#FZ8>jK@Q;={??{c67BPj3*t*zu z#G~-y6X^U@(D~w^dlErw6S`r0JdoBXfYv2w@j}lYGDqB(_+T-pY~Yv(+A9fK#{k-g z`C#?|ThKc5SK5p}vp{DPBj2G29rFdsnH8JEm30>ve0OdT{ge463s|MQ?T zf*5|TRA{)w$?)hC=nQh$`C*{FmM0V%E^#nC`UE;(@IQ1+3$&ITG!FG3xWN{5uls}W z2HOY82W%fiH`s#4l)>%O{R}@J>~{DGI_Ci%*R!ExG4mOIK7yVdD3T1Cvp2#%-r}r& z@dfDIa?tr3)(k&8Kx0w|c_(r(GJ@MzPpln&zF<}djk`?HWR#!y@-YkK{Eg=3?`8~r?qVah8|dlz(0 z9_Wl_&^gGDRVRYhLciY5@)Lg6nlQu9*PwO3pf%5%S$;aOg8FBw6G8huLF=GjY-aiS zV7<%Fhnrn~zJ&Hu9?f?7`FOs|&vQu(Q(g-@{6x3s&0>{_;5$F3v;2J1&+_y2WXSsF z|J^J<9X^7}N9BnR?3-*seUlg6EI%K#yZn6E?egvJIm^!%)}TG2E<|bRv9?ciREI%LcyZn48?DF&FZ|0vb{xko4^xOI8sNeCN`6sA<;jj=CH;}!YpmobHUNirE@Z9<5!`IF~UtVVZ3EI2)=(6+A z$Jd>I`h(2J<^E#1i4W$p?|pNe`RD7?%s>Bw)+Qfj{^`&QiU-+=4{kTwzS__H^TlE2 zpAYss|9p7Z`RB{k%s*eOXa4zUwe!!%>z#j^gW?{vRvbC~GRsbU!_4rZrxvnq8?;{& zyk1%s*eF@7FvJiVtX?Vlwm37t@)4KA7zM^Wk*opXhxGXCuF9~L|RMDHW8;4*u$)WlwfhM>3V z3_st7Gyi^S1LG6Bd$hu<(TTpyJ)*Qc*Xa4y@nfd1f zdFP)Gl`+>EUruD0@)k4}1DeCYh!=^8Z<(2YzF`OL4`%xL3V9uIJtz*uCq5_#?FVN1 z32N`d*AG7i-Oa-E^U-6cpO2qA{oDoe1E~K9I)fT1-v8fb`uYDp)6dtpnSQ=P+N%lP zo9Qez5wwQk6?DzRgUe1oA6|F*`SLK+&lks;em*+v^z-p?r=N@Qx&N@}#J9Vde!kfc zX}`bP&h!)1CjY;l>F0xJP&|uHd=T7d3p!Wv1xReQ)6a+NoqoQAp40MZw$snY^PPTn zf!vR^JQSJuVmjnbchJ7f|Dg7FH`7mtkD$I0be#g|?t*TnpAXudem?95oz=qh^F=w+ z&qu{hKOdJn{Vc|1cCzq9&|U9u(wTm~2CWN@hukORa2M1zfVR6q_Y)*D{d^Gb^z&h| z(@*p@z%jVYRu-E0!ky{o8+)doubr8Gg4Xl`^uc@=L>75pAXEP zz~>R6ulseyW%gr%iM&h=L7=@DZ{?YOg4@!dbrPVqv@p|82hiQ}%#d@1K<#VLS_;^i zLNC$I64JpJx6S+$-+pHN`Q|(5+#SZBpnaCGbAw1(BO#2-AIW?ZL3j9o&K?BaMGiXy z#i17z{=DF|y|4B&{sf)<{b0Z2&xeN{!S{+Iuj&1hfFtiJ^G*bvZSrP5<4@3f3eZ|z z&>CKcN>KPi&O!mL(S0$S@#ll-jz1sHcKivuf9FxN!Sfnmy9eutmf z+W=e>--a{(eB;mf^EK#RanKnh-i$vT0zqjWa{lfs=-oUI+#P>D^mhFD61x5tcGm7T zkomaE9B0mnZ?zfWdniF??1JWQ|I0Ii_fx)VhO~=8dnZBba34U=B!R7afVF|=CSYkN z*>gL2GfLXZAaYg5ra1B53{XtMia^`5&Bj`1$a% z!%y^ew^^X@vUk`C-p_6B@DqH;F0}3UWusTD06H*&;)7)(=&W4O zI@%YjL1R`9KOe3J_01T5zL*ZW!_ML7xxdwPXw(!2cN$JIztn5cOwJntfB{>Kx-Ue{Wws+>;>q~ zi`fmfpnEOA^Y);#d7$U;ykus;dJfO8c!nweL1*yPvs7k))|&n1umtP<&tdtZ-lg)z ze3r`p-#IM*m$Ov9u=lj&U}Y#=$iNWt!rIgF#cQbA_Z*fl-g{VbFftT^?lpf2x?=@& zU$!`OEfi?Ig1F<)N79bqFd7SltFh=fz|>uYn`8L-|316rf6#gdP~HKVCl56bw5H%Qv>&#Z-SUaL z!_SwW9e%!8>~8t$F*|sV=ga?~d#czcz6ABnLFPc$Ccm)eocQ83!%q&yhD#g?&pv_H z$Nz_}L4Lu^Iq}6~hMyTQInerJP+q&w@Dtn@g|0sa^-)1*VT0Bndw|B*L1(pq)ZBLX z`S3odKgV!^12irGI@{$i)SaMvhmSM-gq?5S9?vl4m9WE4&>1YC^R+;Jfb~t^eCL?> znwe)6=uB&P*|MMECun^IXkEtZWY&qWeCiDKT5%uIHHex|-pq zHgm%z?gtM(z2*mrF~IjTgYq>fUxL<65W5E6A)aB%J7$NUZ`mDwzTtNG`I_J1Cq`I7 z^Ygo4P}`W{Cv5G-8*hf6ul*T*{s*n40FAF}gTjGv;sfah+Xw0gY(eL3gZ7w%$KIVC zem(^4cL(*Y^%>xI7Ab)8Su^VS+St|$gVz$WDuCAuzXY9^NWpqxc%BEPSAN8qnSbL@ z*9-r5X1(|)UwGx;YLS%>oS7$r?i~TIOJ!%+$pO79{t-9B&()yyD*O&VFYow2{UN)< zPS6>g4-PYe?{`@OTA#!2@N*|b4tzf61Ad2}GmbJ&c>=mmpqUZ0PV$0gqrybc8Fwo| zdkZKy&mUaIfW{#}`2^`a|6_3sQ$Y5v{QrOY-|CQ+fAWJ@{&!}bcmU-LP>zeR^=+WD z@WJ84s5lW+cB}-gPXXOK%MC7DAmb#+dt}-{XRon?$C5y03%INVO)DV~^D9*-VwMw>yCLHCFxyt;+)K zrJ2w0^OYiKPVDg~@ER`Ax~$n?zd+VELeJR;os9s#+YYq;0d%$?Xl@bd&T;oRXjud5 z%ZWSu1ebxJ{d2RMDzh1Rx?y4WdVW*ot7=G@@}}D1=c{JsiEoM-e!d3nb%36Y@G6@D zvCbBBCNOk87wBC5SBIG7#TitFm}#*I=`tBbXUex(0!)f4nM*7FETSg?s<2Ho;3$5Z=hw$ zqQ4D6%*+izZ2SIC$0)z#9e#q&o%|2l6K2ow6Lf#+E6|!SV}_sqLF0t-pf(EQ#0TOH zwxD$>;IsUV9ezFpwb{_tdwq=strO+IG4{xP5p!VmSGBLoieCQg3Zr$9ATUSYIlR$E-xOlgYWtVo$Z$a3O~>tj?9eUHO-(l z0(i|kH}w83=y~1Xd*49$9CRO-GUr6l9X6o-N1!(LgJkxJ4?yKNGs6XrPQ{6!`W$@T z@n_JwVEI+Wn;56O(02FX{D1hl{D=x)$m(F~Y(elkPv;xY!E zf$H!R)K7T9>}jdNz+nC#)HVQ}3#iOC5p;(M=ngBme@;WzXumkm@DuEx%g{Txpyzsn z{d1q;C#bFQ0^}diT^7*%`(QEaL{NG60_LCX3_rpC0k3nGUu6&Sk35oplpVn5dV|Kf zLF3e*_Qgbye?WKrq2I^l484yFw6_LyKN{#xu;-w>$MExovpeLjE@_9KpmndHb3MUr zOmT*v;PeAJyCxXuL1@Es}4cP~@Yy1D{|Dorqz|K>70a};H%J31~eg(||!S3Tp zX0d#c>|*J`z+eWtiw3qA3PXJ}wB4o5VhOsd@&%~wQFej&5j3a4&+rrON6_6}pgaP) zrwrytX!{1VSL#tc==^tPgdfwPe#~b0d6J+_**KFnkZTDt(c*XzY$Cy1LtYns_1ZsxFT2m;+h1dbPW zho2mZ?2vc?wR?gYz<2n7%eBMcdK?lj)=)RwGyL>qYz%tY40UrmlAGP3ZuW+_IRxZp zXVi71|CyOC{;g(5?3;qM6cz+ahPo)=uBeJzN!bz3?CR4m`~(j0Ig%TzxE&-veyc9=I{$= zaZsP(f|sMx#8h_dlC(@)U-s*g@P{d|1h>1P+n56Pf23czKP*2Dcs_i%?Z{IomFI0ba( z{KNeYJ0CQQOteDgFBYC?hRi=KG|>o||5$LM9x@+vPY5z!Szw~tVa6#BKxYK)ci8zn z-Qg!_Km1b$ho8?_9DZ_eGz2|l=FnndXqW_A7jvDDamoW`rk@L#8MZtD)tAW*KmSAb zGreFInE2v11`&|k!0H>7C%(AN_>+UFAqceB{=sd>pAYXl{(O`yI?o3~u;5?{&z1prHFj6>33elk-hf zC1f4zng0&$CbXM_$-HtyW?uXp_`S`r!PyHB%DUZ?}em(%j zr#(16S3P8B`1xZx;}lSMy=dkIpNk6H*VM@1@Uw{pbjB+WXnh={-2j>^o)6uV04kpr zGyXgw+!*x2n|Y@OXs?7nGiYtx1&)I%6G3J2i`9%jUx4mh1+`(r_U@f5p@3a8_-$?(D}#Bj6Yx3GyZ(7 z)NqNL;nAnp$aj~3=G>JUE^#$H`vh9gjdR`|R8}C(y}x+Q4n0ekYodZB=#CZ09ViO6 z4Yse+p={9o#p#TYHEY%kKSAdygX7Fm6}+cJ1GLu;>AtQ<>5e}iXFL8p6b+3tdk65D zyrA^{P@duE8j%0d`y0c50@u!w(W6-N;rk$ri z_bJ6Q?Szd{zBtS=5jNfkYWG|O#f`kf&nNDnJpm3sLHn~nd$AZ457;soHrPJ2cKrFs z-tnjOOvWkiKxZv#JN$&LcYJB?@DqGLE_C1B17XlzCyYNo2s{3KFYfsBLqFrs_ncvU9QU#0TyS zKOY_zn)uM4;pf|8#wm~7!Q+%WUo3}|e~|Ww`b5zF@lMu;pqEJJF(cct8f1sR!%q}_ zjT#d{w@KbF%BmDlu2g%Ifd(n~G@Y4@M?m`EZc`uViC%(*Q`1!I~ zWFq*^fW^WSUzUT`7zj-Soptx}vEW3|-t?Eug5Wz4Un&bsd_1=ZX8*}4u_NeZJO55jtsOxxoB4NgimV8FxtU?-%Xt!|MY#v!^QB&FXaD(PGyBg+ z+ueUY-0c1{15_t~_5-hny2()ve9zm9)$EY6u$*D%3xEEd8d9J-gnwrSDE>j`elKSK zc>=Zv4m8F+pZ(|K$2Jr1Z23R^b-Ke(lr?qr4nJSDv;Tb6%>I*yV@1%L-3&Y5F!S$x z!_U9-!QsQU4^B7RzN}~e`G%QcLXV~3#5ddwKi^cd|9o@Udg7a6_MflI*?+#uXaD&s zoBikOW}Atxv)O-UD}&ZtJcf)7g5=WKf4)j)|M_6|VcQ3*n{6L#KWzJ8eY5SWW~+%H zaq!rMKEuve`3yf_rL+HhnC|}bL9+YLm;UTOUwE_seC+T3^O3jvPqQe7DX*&?e!eqy z*!h09!_K#$GCSMh=PTs3dG!uI-?+2?eB;di^L;bl&iDO%JKz1cw0xlKzxQFY-(FBy zzZ0J?1r}5H-}|r~BKBTD*lTdFznojLo@cZ)42zSC#_`PP{I=NoPIpKsLJf4=>1Iq|JJ`%hiwhD*E;9(;NW z5?5yb`9_}oX9DX1+XwB)&iYUw>!&`T8^4&kxM1)c+ZlF#e9pU5fMG?@hy4sYKRo8$`T8~6&)3h{ ze!hOp_LD(kMbLxe3_BlO=iT}7GVjh0=XrO&Kh3-I-ErQXZx8eCe0iVk=UZlm32O}n zC%(PS_Vevwvx#pnv;BN?o$crA^K3s~pJw~{rrCVro6~GRdz2e4@i;vG^adn;obBi9 z!)!kvWFNMD5Z!G1ApNlIgZO6K*UhFALE^8Dv;BN{-0kOs!)`xcu4nuCVl~^($LrmG zK3eVeb3-Hpl0<2xd=%x@`+NL-7Cs@#*sJbP2_ zDCRZGEb(h);o(cYqRO{eW~pBbi%49uhKk(d)jWHd?jCU0C6l50qDY5YIFgXZ!ik-0kNBW4E6#<=K9|kY@Y&Sl;dD zBWbsv7nB&LeC&7F`EIkr&iC6Lc77m`z8^6&ta`BDVdo=ZhM$j^8CN|NcKG>7obBgB zVK(r3VbJ{F1NLTH&>p}C|C?+d{BE*+E6=m@qcqRX2jV~b6Y z7$&s)FA!++PY`JFR}g6OfBl^G=j+F;KSBEk*Mimn$us{Qdztm;o9nDUU!Q0F`T8_yUzh&GH>X*Do`I!bkoa-dpRW(I{siq8d~mzT_QCT* zwh!(%*}iVpod^F3f&)Vyg9B3@g9AfeQ%19&YDSx%ssn4@QU|8Ir4Fol z?G?>_$}$W64!g+YB|EU^B|9+ZDOR-kIXST8DLOFaDLOFb5fx6$S%1D>%=+`eP&^VdsbS zTsz;d=Gw_Gvm)sIdWN0vmvilWx0q|^Yk$_C@8)yud^?+K=cDz9Y#**ZWUC<2U|@8E;QO|~!1q2VN{HSw)6>(95%niJn@ zv;KUe&-(MVI_uBZ%AjrWn)hD$sP9)5ZQ5|?NF`C6Lw=Y#2oY#+2Y**=(j z$o4^ZlkIC~jfo)fSMsbsAIiJ_d?4-m^Cdgv9O1|8u0J0!yZ-c!V3_hz-(lx_V~3sZ z%pG=u_S1bR$5TH+_XajFGz2|(&$;vCYtEe?o^$Se|Cn>p+D=`4`^tf)2dZ8C_hJn?Nb%g;CQkh67P2ebTq z)2ue}O)$$(9Z)=g>PB^jpKrn;XYGRax`FQ#k#DjEowp0RU*z>+#fc#CSN<$NANsre zeBkZ!^Cf7lsWHpX$Dn&ej9q@d2#1`z4muML)Mf(h)j@9`ywhialfP7c>6^-8b^!bfYcku8;@k8*N`V%S?O?y;tPn za_6597CZlZ+0Xp*MK|-$$NkPfA9XwbtRcod?NIkLYE69C3}VYnd{@o<^KCuz&)1-} zsm07c-!`jEd|S-?^9_if&;0XsHfVkALE8uG8*Lx#K4|-3bEEC+!%`DL;-EFF5A&UW zg7&q&3}^oNBAEH-<8bGnkAj_lMu6O-?C=wB`tb+3fnmeBnOYOyc{Bff=PWhxoip># zx9-e8U)wYPd~FR1AC-x3t(kwm0rAb5f4(+m{)v8<$ZKZFi6HS;=FC4Inmhk|VC?+! zC1@?GH1p5L^3FdWNjv{E35To)!j+cKfzJYky62$Q#CO7=^dm9x9XIpOx1jxKpmnLt zpzu*ftW*8Z^z-#^(0a>*;InN(=iNT2ZnOp8A@UothV|ipr=JggJNLE|>%4m)4kJN$eBI+sTMfbBZJM4U$?eG)Se*~Rv3)(OC zaXstK535;szF*F|^W9?Boe#nrZ9!{GLFZe6&$(Lcy7z%H>)r>;UH3jvXWjc?wd>vo z#;kiEtash}z?^mOJ8#yV@8Vf^KJY$h`_TWO?W5p>wvWRP+CENiw0)G^X!|g}(H4A0 zZnx`RMgcv!hv5w1J`kwC`L>_w=i6?kpO5+>YfRs?GyMeb2m8;m(@Uc<=+$qQo#1;y z%9(yXUMxJ(XXF3r55pbyzQN*Gn7Xr`Z!4+~8++4z6@%WQ|AFNz^y^fH_Ye0TS&X0eH{f|-7LsWe>Ta(E6I zUj)hdGlAExJ^KZCaN=8Srk`*0nSQ=jXZi`cGvrOP=)^b5 zOh0qLW%ctsGyMeLEyCVt`#|`hE$F=3*UkbHLE^9EnSMT$cl!B2+Ue&@ zcBY>%n3;Y)W_SAeh}r399mqZU4nJ|FYtX$RpmS*-B)jf?@R)h;gLK!u51upceNgPW z_rYuCy${M=_da;fyqAx$A?V$EMo{@V;hd-T#CNY5f4+0(pZM-Ev#o4<0wzK6no~U+Xn9-$ao3tLuzEA6|F-`QWnS z&zGR}tGgM0J_e1C?{@qd0CG2;Gy%FtcZ2O?dFGuTq?vbq5NF=`L6~{x z2Y%+AkGPq4eqd+b`GJ{v=fnR@J3stp+WFu+)6S2dnRb47&$RRXYo?v=o-^%y`LLqJ8N6;|)xY=RnhwYHD z8G>!%;|@C?v^Us3Xl}55B+s<-p)}LZ2jWaSKMFJL{J_t&^F24y&UfrgJKr)h?R?OD z!1iJL0o#Y5Jz~`jwxIKo&N4GxSgU9;@$GAdpKqPnC%%0Qx<3MPRxN0~>>Fl|iJ-G< z&w%{u@ch%8`wTx{gVxeshMX-5T0aZghX%e+gqdyPYv>ua53f7?1f63G8smMjn*n@& z?W5feKc|P{E-PMcXZQ(rkEX@Mx1cj?n~}~gTh8$F^*F`3^rHfY#H1##5Uaem-t@`1z>W z;b(Cu!<7Bb3>W`aJFfhbe`p104b}f<5T9`+=niVo+^I3>yiIn8pLJ0B(YgQALE^3F zA@orw-F^YWce)Iri=p&+D9v~SB7XWNgbuq6p>6I$=-Kxmbo6})ZTk>HcR}g%k0Jcq z&mgqND+n$98bVt`=_79-{KHV%;u?g1_AP`~{{*3>zy6& zGIMHi$T~~{&AoGoGJHJ2%@6`wFPX*6@WIPbaUur;gMeq{>Kz=6oZSqJ^4A_KJN$eo z?(p*gXuZK>#)FQY0t>;)1DP_&MUfl&^js)CWfsjb~iIl{107Q1X^c|LZgS+yFBt+0pVr z^AQ_t=78MP!N9QPrL@D(4CaO)4Mqk_&^c@Jj0`{JSs8xHqxl(hHz!^{ay$IQrT4!x z!$l4Th6x-8r9pEcKmW5c{CvRd@be+N187YsG|r*ptKHz8A`H-98=OccGpO1wZem()kDZj(cm!Nq=&>lU|8It~>bw3P- zFWBcx{fEZ$LuZGd;CZKH=vs_M?TMgsWj)y%g1~Dl^%{a+W-~zU;LZoH#h9R(r~|$O zcqKza&`W#BT8xkD{!f454_b%BuoV{m57ZrgKGb&j`M26@<^RKw^zy*l0lfahzMFB% zL(mu)zr)T){tiErcZ25h!FP~uRAgib`7aM$Yog5X^MSm>Pf$8THs=L1WE~Lb&i4o6 z4nH4CquK+@H|XK=g5O~$C~V;2;>_^#r8`o%K-av1&M*Vd+bJ_b*42Q*MV;X%I9#+D zetH^!?k0zZOFT4ODs{kXOgcf~Vh#zH)$9IGe*j%`$As)>cZZ)MMEMz!*RcB;A^+bQ zlomKJ(gMuS9IVi|C(@6dhFJXAi|NNAkRSOSc0S~G`1y$6;pb}5+81U*ap|%0zcVCF zVD}e79=@hWonhxgaRzXnf1vKL^C7eRs)x*wbOJhW^uYiB(?R6{cpaU(!_F6=aaCr} zxqb{kL2DF2>jyw(BWO)LNd1=o|EE7wW$=gU)eg1=n$){P_ZOt~fV1 zpL~3AeZJIxWrm-i`~phfpfj)^Co>?@8$UF?2{ZiU^lJ!usSQnU`q1>YPzQXzttV(r zlRPB7@vj4~rv}Y020dWr(6ZmfIOT7(>&pMljHqP`Xn#CA1GwA)l|Ln5b;$J&v)KeY~%L2FM>fac4$I{pOJTMt0zgM;p8hSh1# z3>QIlJ}4|W9cBi37B4S)&CIFA$$NSh7w_p=UbWn_IT*QKD=;R_V`NO4m%+^NfhpGg zuc8F#&b&mq|IV;incW!%q!PhM(Gu4nMV69iVK4I7)argWSNf z5~~~J8Gc4GFiZit31t6&VTPaoLH9LDGyLQuXg9KbE-U{#L*vhx;o=KshM%DDgPl{) zWzZF*#jv30H8YnM7bhb8Kz`sl)ELCUduo;jBg0RwTCUj|oS?MF^%^AC#ohpsW5txi z<#%}4BgG-8yn6+Xzf-d`Yq@4~Fmk@;1eJm83_DLSF>D3Jb0<$j5V{&rJiKIP*qOly zQNwA3sfL3QatqV$U}xC*fZbsyid&dLYXw02co=?y?1QB%4&IZq zUY5si;#8RVNi%x!Ck95&ZiGHac?nt{3ra5!!x?ry0_FK|hn=rL>sHkresUXh1!*%Z zDAMFSJxe>RJ;eqLD{vuvwLcJXKOO@yzaR=F$g5SmecojA5TNj zxmw=Y*^GSMF!?px8o=^>3|QoJA#xzS*^In!Jul@MexAABJLyd9zE3&d?|%ZVJ@;m0 z`02^Z@bd&CgZT@2ho3K%9e(OCI{egTb@-{p>F`s7m*J-lBg0Q^R)(KioD5+8-)cm8 z`Vdr>f&3@$@RO4hRBkx@?D_wHx&sS?*$ZWdpB$W!HMbmZ89uH7?az{S_z7Y&FfxR& zf!cVW{Zb$?R)&wDbR@#SAR-JE2bHa$Gc#5&gW{4y3uHgcZ5q5F_d(o)&wU{OfYRwJ zW<>gAVP%;3grDK(3DEdRBhy6CdRcH8!ze%T1!#>GXdRqA=pI6cpAYRFejd_j2vTNl z2wK6|5cHIpL(6B=|LL#z9e#rEgI9L=sad&d$4hYruwOyxm79?v$;tpOzr-0BL_p!f!s_tz2{V!#*um@z93VG<);)mS09qdpT?^l&*$|YBgx~+ept753C3=~-=->b8 z91N9mp!~zgm@LO&ktmnR%y2<5*8ML7N1_}jL&dz8?4UK_4278t3?ZOA_G0j~CL`wuP@5c7euK&l1|hn1bpmP#Y={q=y}(2Pu3B=n2H42ewY>e={HW zPR)nW3_l;lGyHvYoMGo<&|MDM3_qXdgVrZH`~;mt_6l_7-)Y95FV8cA&!`9G_ZQg? zKRFs1K0W~D4-lJ?@#6s|h7izM!4Kjc{+?uJn4sCnJdxo*vK$A4njD9%!{wL$pfV+W z-h*IQ4miOV0qU``gU;^8`yn(2Hzl$XSm0%satq z3=P2RW;;M@mG(3Kys;Y6Z+Q^x@E25$@UlAm39*645S+AMpS7|ab ze&jIho(0MWp#IZ~dWM}4`7^URp>m-53{=N?DxRISmXYzJreXIiO;*tU9L}y6&I~`j z6wl1+VPyR1W!OCnw7<`rmEj{7L)ttqM((ax-k^NP`MLpA-a0${Ji*4W#ROFDcsu<3 zznt+W=pKR>3=CVqen>R{@2dx&0koPC)Rqu=QSY$x1p|W_SiTe@4?bIQHRDfEnGF{2 zL=}H<+VSVZ^Nv3sEqDC+c(vnClL?Gdo-i}4dScG-^XYjktf4~-Wj?;^7$Dg46=`Z>nf4%_ibz96j5q4KX zBFOIJ4m&wy8H6}Q84DSh8A4vb_>yRRS;oQ!WcjI#g$@*C46k1GyIz9?Tr8Kzpt;7#OyK*HnVa z-+YIkpmO&isITM9HZc#R5427l)TaUMHwCpVo!P+aJHhc>4~l0NNIZ8V#j`!^tarzs zp!42A?sx%OONtcF&$mI=se;1rdA`HXXU83Og7WUmaEF~wg&lsv@}v?YgAg+#gV2-3 ztP|N87^XZZX88FKw5Jd)Pr=K0X8wyW4)aa~+c%lv=R?rB2gZy$ADc7od@`Tm=hMXu zKcD$C?tBiqSK8lk=gWSFpRcAn{Co{M3-dPP&sX;ufBrwr_)|d;GS&t3x7vQI+bKBbO6O0j4#Vrm|%+}Kb5i2K@y2Sld@O+pF-Ro_FH^dS1(y^}LoZ zHbeJCY-jul+c)sQnQx-X2F58b<~#i4;C1-4nIL< z%FFqTKVK|n{P}Rcm^F81+I-3!EhvB2y5Od$IXPok)8k~P8z5tp1|GzjWPlL^Z z-e>c|o@e5Jd#G9VJeDuIq2bie`14`6CHU0v0&V4p0E;wIju``5#@+>GmKyk#y$l3i0boUdp{3_6yeVUA1uU{Nz*xAF( z5CXpYX}-fxE>PLe)(`}f1K*_q+Lt!p;U^~}s13vLlNC80i=pvY&iL~|vE$E&<&Hm{ z1RH`5Gc^Qxtp7h9Y;H8j@0{Hnj1HC{`#@m`Duez*?{|D*&pq+KJ-6jcdu~h6J`S+I z^BI3W%y#_wC?67ro$DE=faifhbq6cML{Q%WwC?;xIm6Eb|No0WT&>1%KxhDRf&t>^?K9}W-aA>?n zGlKWMg3h)9#RbSNaM*G>`~;_`)eJi`m>9Nz#K2({j22ej(6I7n{0X~fI0 z#D75JyTPEaa4Kxi=)AgW{HhmEj}oZq0|v zjz1r%L)^s<@*l`9&>n2iehkpqGRTe24nINnXn^`aIj}r0&G-|v=lI2bj*0*Gb3pR^ zehy2}d?h&SPMS3A!5zYz}BI4nN3m5OeN<%mL*WUT_=iBdD+c(wgBXs6GVedr)5*+~#5c z-|Gfy2fR#Y*a;dxeZ{~K0zQ)mlt&pkU#|p}2T(b%ThbkNz5ulaL31ylbB5R%f4=z7 zKJov5cFULl*)8E`9I!L~e8}wh^AS75O*=tu(suaCp~>)ZHK=|7u_rQqT+PG~0vcBU znGM<_&3TYP5Vo)S#ccM8|Iag5a-*bwB!c~;7+mRDMnkt-YGhBLD?Yk45!XCS|V?lFA~Ix~rF;{R;s%Kx|7EMH${ zvwU@(&GO}KHp>_HLGjiQ1lp$!I@jgVV~AT)*D+3kl{xO~7^ghA%<%Ie=qyrZv@&P0 z1GruSwW(h!L-UL}!%tsOTM{G(I`3(|!%r_zS^<^E>I^@#LGc3`|50c7`NG(7=S$Gp zHu4~MFqoYH?VXWl_z5awUV_G@KR-?}3oFCN7t#zrIRqItg5wx;Cz&v)JmGwO z8q}5r**71OmqG0_aQ@|I_?Zi`545+KpW)~8)eb+O%y;++Dl1)<%84Neuke9cRT!iv>y_;511K#zFi9$Qvk*B zc@TR&!_SAHGqKR@fwv8t1us6xXZZQBnBnK6a)zIes~LVi0p0Hfs+SoUw!X-B_$hyo z;phKmLDV{_+~McTYDk=b%019ISD-R1mx&?dWx2!8SJe(bU*|jg%sA@sGy9;!Pi{u; z*BzP-K^(Q*v%NrL=ZsvhLHR%vIwlN?cXT@*D05GIkj(It1KNiZ*aA5#9ki$YWiezQ zBu6dhY*63&Wje!8MplN8591kru3=-C@}eBHzt!ODU_EZ{rtVE(zYnQ;neeCCHuNICWk<^@&~B?C-?yyaAfC1eMpCj0_)NiqDsN zIUO`7#IXuArt$)G7ht}_&sU&2DA?iW3w?&4pmRDj4?@D{lnA68e--Wc6W-PeXV}>V zx|<9%Hhh?6A_pT&_X~CC_$Fu!0JL8ZGzKu8;pc4aU0n*L}^^u@=Vm(rT+RhMmkHH-N$eWG5&rKz1&N+9}Mi^M$a(PLR1T z#2t3Nlm@K)@G$`tKJpIWG0X-~{}jY-WcauMRL_9ejEo-_urP$^g61qh z^M0UtOIZeC@R@VV=SykII!xALWcaALwDT4y9$$j)p%!P@X^E`f7D>G=cJ(OcgVyJO z%&x_*Rtajh257!(`FtrZMus9yR#f}J?H6TmKlK8~L4%2)F+~kf9~tRfpGV1zps~;k z9F2zHb8Nu(x*9Y5%m9ytGVBD83Fb3^#zHS}G#Y{DPBK8}7uYlWoVx7)bnt!7pmYNo z`%q^9uOE4#?ywUyHvhtz(GoPa23gaASa*P^XZSC|>e@$_8Gb&#&hYcecE+7g?=$>- z_L$-4bI^G%%mJ1!t~2g@!S3|)#e0UIFRnZMeEA%7ubRWp*XJF6zB%pi^UZ6 z86o%Eo`$NM4ILAn4;~Y~z_HPIBIpbT@cz~7j6Z{yf$n|gnFtyi)PUWkyPM%>-6l|5 z%HijW?T$Mi-FNs2aswkHgHRY~O~7u4pAV`*{b9zRFRC4XzIyC!`Kq3ACur|B=v?=g z*BySoI_&WC#c_w9FE)ejE`#)g7qc;hyx8vWlZBPxi^T< zE_V3&dbz{TH>(|fzPb)_yTi|y>m7cA<|wln9W1*U87w(CPtAh)^BCwHewcsyk^Iw* z;&zp2ZcSTUWr}(e>%($p!ydy_VMVy z!%nb&+8KUg_y;s50_rEnGyZ%K?fCOyyyH($pWho~PBUo#u*1*SpnDyzL&m|p7TvG?S zD*_yspncu2xJ*X!doa}BNM}_gu{Q)YGc^Rk{HwV7|MXYM4nIL{7Z09>AP+_c@Hv{G z_ScL13_F8CW10QXGy}Sa3T96%os{4|seR<{waf0JFy%$sTK{JxJ$}K0>qS zGRPj#J-(oIXjtrF1(mU&yF5VkEa=SE`wTn5<2Ls}bu)Aw7&C(zXfFgf4ncdN~>hl18#i8fq8lY-H#;$cxbI3IW*# zIvWhMrh%m)2xiw4(D}iTd3s3Pf$BAGsCl3>ZTJ~~KHzrz`H}Dh zjGN)-Q)aeR0-$^XnhyY-1t`xm5p?bzXny`B=sZ|<#-E_|-rze-UOWDL_}=m7BVos% zkHsB-Zs=f~0$OJXx})T&xZ}^K;tW5Zy?6Zi@;Adz&>3+LeuM8`{OQEi5R?oZXZyP9 z|8&qC%gfh}KVfH@JoxMYJ`3)DGiv`Gw%!l4E&{aX6Es)zP@3T<=zO+E?hHFY=TLy! zu%LCVpf=NM(D{YTT&v!&GyL>%WB{Ly0A5Q1TIaye06wn_B(~ zHvTf$4YkDSH;3wfBk%ANv{s|zZ~bLZnM{oPHK2N5OFR68>Cb@bC**ff-ha#wZs%+O zxA&|WeuCS3p!1yU9ezFll`o*Sn>jSEFq(kRPy)B{;u&_H;B5$c5zVj@+y+E0FTnTl zGES6S@_#xgPX8jU4T87j4hvp<_M747lm84qU-&!y1dZLj@OA>9ll+*Q@#iCc#-9&` z8Gk+yXZ-mf9JD_Obly{tSpVfbPV$ciIVBGYC3E`Q>-+i3%V4Z9w;7J^0;V``~+n z?Ss#t{YDM84_-IeK6u^$-hTv|Gkv+6@#o9!j6Yv)X8g$nTCdj3J5e0eHvI1ZJ_qN) zX2+i|4*OcZ*w46A<8S?B*cs~`f(=2Sam5FqF~!f2^J745;unt{e!hC`@bkfYho28Y zWdP{>pVJIKLFcG*FmSwnp*~+qlY#T~OLb7+uTv_6gTWjWpD)gX&P)5T9mIb8+~Mb= z#|}Rq9tX`WI{XC5f$Ng(3_qXjX87s8_WyK{97qjF?F-PF?9&cEL37!eYyVGwvfbh5 z!@~?eAMA&wF;LhoXZQ&^>kFK&7Bl<=t+{x(-tp&y)s8s4nPu^cnQx+JrnUug_-zEWLC-_$6i_>k znPnB|9QYH=43IhiH1;(cS_gpIpYtK}b`NGF+z*;3dc@8MZins#x&JgI4B_FV?er5g z*ZM-=2|T~}bt>kw zCW6X34>Wr~Yk$CfL1uX^Se${%1@QRKbBCP|Kx-zQ8Gd>&L(`c(G%i8w7(s4AZui3a zZ0U^PzS@Iigqt3L+{D-r^lAD3>7cu(Ky}kgkek>Vf;2Lx8cv{j)p$p6e-9QP zi-aL<;IqsBPk*frnfC$3JGlJ|Dl_yMeuC=u7ht;tQ0)S(=Lh*8xy_5zcLSX<{2&;~ z|4_R&f$Wk8-3bVZ`%Kn`AaMDl&+t-fnGIGBL-Rt)f)CU6H*|)gCmXQ^7 zcBupSoaIN(jz2%NLidmHJN$g=?)dYmFvHJh=1xCf>NEa)q0I=Ma|O-49s>CX+Ws|N z@qap~4f@j9=_hQC^?|bE&xh)cKmQ*_9iv1(^B%Of;sHOy-$&{UJCXOtJq4Xe=7;(WKev7TKOMH0;{j+-oH}UjrQ6E?hoNikn;9=Y5NFs4 z8c+Qn&#;r@FJoZ_XpB+ZVdsltM#~rR4m)3XL&k|;XfynTjgi6jT!8d({FN{C0F6b8 zJM84DWfOkM-XNsO$ffnNn9-6`ltJhPe}fPQBd6Aja;SOM3_HPd1xWj!P|S05DRhFm zfsT^K% zV8Pr7+83f#Dho29H9e%>> z`Ogg6f58me^Yrrt=zQdZ4&XK09E=Pfb3x<1pf%sz4nI}E>o8fmLGyaxHKqqm!E4A@ zfaWwn`46;*P~72X6B}d=0BrtY-?IPHLFq9sWG87&J%@6TA{L}!=rGVDIA7uFX z2-Mzy+6|sZ=Xdxie-w1?uk*_P%&;`Xa`8{Tz{HTW6Etq|n4uvEWIw3g*0k*ZbkG`jP2;7{VpgW61$ew3>ZaQuKifm*4MF8IXs!&j2MRO>51QwF!TMu6XuSdpD4alZ zNsu`ih&$LBeuCzxz-|GRL!kN`ddH0uXG72b85@FNaS#g|mj>-GlXut&KL4JX zd7>91OZO{bhM%DI9-y@z51@MsL2K?|{_z9FALvdqafhFvb1p#f2ZmVk`evi?4jp z&hYbLH^a|Ipz%&-`BmUHT0O&0(Aumwpf+B;!%xt?xS;y?RWZX)57jf^HN~K{z@Rn7 zuR!ahsu_N+;DF4Hq1kL1*uR!UQxg47xAC z7&QORFtIyR%fgG5Vd5)ukU5}vc<^2It@^}0koEbk>R5!Xubkerh@X6x5Ll3-3~vsRnN|P!z{lFwB|kAuxA$N zt{+WCt}f6z4h}}PkEcNM%8+pkNVrahhAGlqvJyXJJvl7hBrJu@MS<38g35KxgA5Zr zGc_zg=>xR?jT6+C0_~$=Wcb(#DwEqCzOpEi`?NuOLqO>bl)gdxeO^d2 z{5%E96#=fiM@pO2zJWfx>D zTY)ioo+mTI2gO9l{uxGrJUIpp=sp_Io?=j41XoKVik0ExD^Q$( z#+X6t#H<~DzJi{^11jf1^Yx%L1sxnewu9Pn@I2QI4LhVcb5MT(G+zS?J3&wy0j-%2 zcKG=Q)ZYQE$uf5M>6Mvn;dPMVBWNE2X#EN(zkv24fW|XHVWiD@YSwFIhM%DQm!LJ4 zpgBKqxu^}At77{IULT;1ls}rGZb6z`XA(w@$9GHqPk*8A@DqF&8fg9CL57K-{s5?7 z0ul%ByAMXh-AirA9xPD32C^GDjJAW)sIdb$9mDqAg4W-|)*6AvKS6b)Co4k;xD6=| zDcivQVn^~9H+aAIN6^}FQ2GS>3pss)%3@Hvpq}C91Lz%Zpf)jRzXL3ccYyrG?eG)4 zrwrX++zvm{{RK*sps`SxyD$C!Fa9Lj;U~zQAUD6*K40p8F~iUQ<)C#s4nH52gU(`S znh4%sbI^3+%Xo&LD?w*DCo}x)6m1B4c^bMG_&mc-u$rA_6G8Jsptb<0o&lW`z%&2< z^p~J>06_H_sD6!xtaSp{YmA)TTm}t6+>C4=IW~69;yA$Ylj8_zjRj{nsLosU7nC1@ zSN_QlTKS(Da_7;1=w8KPptu0}Tery+ou|Z?*AUE+d{N(t^@Da4u?2){~PtYEI(0SdUGtZU&|DO&DFOWQFo&1;o z|HVOSz)@3WJ3^gn@0hZzCdLYqk|>K zRffVwHii(8eIR>5WgyJngV40j;p%3&f`P$IfuSJ?*$trkp*R>oYfV7=Xc=~%1+|HV zA@{mrZ4)a)-3IDwL;FHbQVl_eL3=R`AoI&V7em7mD;P?W~-LNCIs~8wU{#GOQ*TMGQf%=8b|Nl=vz`$UJ zEXK*eFaj@BAGspV zCBU-35o9khaR)9JK;si2`wuYuto{QkyAW~vA8|&?&xfG%c0p%IfbOUO^$9?E!5cKk z!2sI7G4TaE!_O6zbjAR~Ptdv%(7HO%p0bZC8K;2G*Les!r-t3(=VMTL$nEemtC10Ww;X6J0=5V2 z@k-EH4T!T+K<6WY_W6VQpRhfwD?xW}Zgl(!YFmNoFU+$QK;;z+{JaT}`JgoY7IfAH z=v)M8hM%B2C0-;mOaz_T0NXdq$q2dY4%D~)Ta8ryHABv70F{xTJ<6c9i8$?srGL;_ z4Dt-%vyDOSdkpGZ%RB7kV1ewG>ASX^oSpF9u6oBK4Z3{o51cag}4d4UPztcXFkYHpuNt_ptKDd0|U7UQ4hfDO;EUi?oL#P zj!}Wqgu25{aQa1xo5#%Zt3((XrZg}xn1aUIL1_}S9|}}Qf!H9wpu~|gXl#Lh<=<+7 zl@F{Lem=Bk`1z=vVdrCaa9WoDmFH`q^*cmk!Fcxd_o_0^I=`5VXD*w8n*z6RaO(K4=UE)aQZe2gPd=$R1`;dSvMSTOF|S zPrm=k|IX0y3sAm>?o|hsFQBtTU}X%>{C$|=A~^j)(=k{d?0hNEIE*;MPtZDTPDchy z&>nmS#s*tZ`xfLbP%m7;RzVjtN!_E^73|qkGGcY^+)Bvw7=jsNXqXIfl z2^3zSvA7r63_Bk{&wD^Vp9*yT7zaax5NQ4#*2Y7Thqa~o8Q^siD6By1MPPjdP%gQhj6t)Zu4MNE45x{Y&3mMbxV1k4L=Y26WC;u*1$5+zdNkaD(^o<90tc zs{7&RVnOpU=w98&pt}Nv8Nh3eo{Brb&Vl<08Vh;F?(p+9v%}BV#tc6}V??ksu3+i+ z5$GODeTSd2{}J;cp!EO38?=rbv=5JACoDanoN;v+G)^MA@^7`+$_L({`~4VxK3dMO z^Km%C&nKYq63|>IsB8tT6#%Ur0IdUXXZU#nlvmvyesUOs&L4*6U1x`%kE0!aK3eXu z6E@Zcj^Eh~KOfEqjf+9g^Rjl_`2utv9cX@En-Q{>4zza-G>;A%Q^|MO$-&5A3fi9m z&c~p$EsRm~F(~bT;^l93*vdcop)3C%hV*km_b72NG8KBUGK7Ho=peU%>t0Zw2s-`; zs-v|*b(p%t&j-Pv_56_Y`9S*~K=Gczz+eWhyFqLAf*p2(_RWFv)JxDEL(+^pUx3DF zL3LI?Xs(dq=ZkQ#d(BYXD~;w}&^ZS3pt&hj_k!x22g@CHzAy&guk`ajKjY5epZ}+W z?jm~F%<%I`v%}9PpfUH~4m)4)GwuYpVGdeM1no}+ubT$lTU74w^I^5aPbJF+@Sac5 z8Y0kqfYCz4nKe&AYehllg%l&kK|y=+AA`<6W|m*o{}0h-0IgjG*CUr5cD|5j*a;fH zcyX9vCuqzW)TamCEeRU00qu{#h$ql_I7sC!sO=1DL!-yje`n^4f2(=m=iEFJ2AvJZ z@bd}uY)nu&06Gs2bUq}gTm`M&dIcJ5j%NVhvGLNGX(ITZ4ebV7P+0|h?4`<7v|J@$;>d(9@M{KW%z0L1+T5wz9@A#{37UTdjd{I@cGwBpg9n;N zM9e|@to-lH3?Ac$w`&RHb$+Nw;6td_5i$C@3`~j zWrv@y&V$bLVEXyeoayI(eejwrvnTf*em*dE`uWh@=_jb|@;F&=VlXH@O=kq{k1=^M z-ErqjeW#x<)tP?22xi&&Lfz>n=uX)epmjLM8GgRF?eG(v&u=^Ye5LP%QeT7CH$6D) zfH8mkVm0_2gF?`K)Et2fA2~D_LSFB8`02&WaKWolc_R9GsZWvIxB_&(U8eQK7xGNt zyZT-zGyQxd@AUJrveVBe$$}GSg4{07^z)%K)6W;iE<0b8GlI@SGkH-C^#?!G&lk!p zJ74fSf%gNv5O(_c0(6%yK7VX?`1xQnraxXWGKgTft<-wr3wEg6xS4)FVt4xam>c4@ zB9PnugZAKp&hvKJ`63?bws@%9zBB%O@tJw&i|>vF7w;J%;r5yF=cD(IKOcW~1c#e9$ZgLVe?EN8`18eO=bbOyp>A`By6ryW&liW8 zcfPpq`11v5FT`U<@LDyz@ee(d7=8V~9BgjuwVwFmI@E2q8Gk;y?)dZZZHU`cKyEwF z`19dq&^k5eoiFsEZqtXl?Ko(i7xT^+#~mSS!$4=^fa)iF;WpXf=YxLCa4W^;wwczT z_5~!|4m19IwBPaP<4;hX^kTN-PtaX@c;mF%;pc;LOt-0Hx@`l;M(c?$ z`k`?;nGt;U#pB74a9a;@8)$7>H{;J2!p=KEYuZjQF_^q~4s}~S=uT7SoiFMge}d*# zUo<=Zd;zKh@r7Hy!_NoVm~Lah=C-}o6G8iVz~NTS`14V@5e~NfaZC#9e;xE6UG~Epu1P&G2M0(G?or34;vW@ zPl+*vpp_>ZIPO|cd=U=~!(_&vkK!GFK2C7ygdmdH)x|jz3?3`po#kFdWpb!gS}0`wl-}t#;h`GMa1Re|^@=}Q)WaiRRs&$wQTF(Sp*VM(#@SziQwj5IZ4Z7F+F*BzYs9lb$9`^yA+ieUwN1pNL z1L)eO7w(QfL34Ngubk5qp#u{8vN>e#A3;C3RUj;)8<3pz_en`!3@VMoZhx#EsLL1&}kO;@1( z%jTH&g7!5crzOz3u*dEY|6c&v&CU4pAwT2K7t&5UU!+6*pAK~gXnzGa)6N&njz2-` zs$Q@=g7-4xb%(wKcuobqtXG8k|Iup4ov?NW$p05XZurgc^C4)R`)|jcFZ`iy@Q1qL zGsDjpuNil~`0Vf#yuRf-w7rfm4xsIHbT@$7KPQ+Ou(ow1K<+RH?*%pi^((<`o!6jt z4dc!iuR-&K3_oAIhn~TO&u-{>?ihB1)+s+``1$`d<4(}Ja?rTKi{}nML1V~x!xMU* zF1mT}_8zm;#RuJtKOgop{(Pj)yz{X(^Uf#w%sZdXX8ieVKI6|0&{+CIu8E+tkzVLK z?|j+s`12L$zGiFYpD*p1fBrXT{^=piVD>`Yc_+tAhQbG+^=lyZM}|W1S$H7!PliH8 zA%>7A^FeDBoqs;GcLt9!K3*(2@f2vBlAjrpe)*kuzBG6K`BIvoiFsAe}c{` zdSUGR^F=e`Pf)!AZX?ci{Q1h<8MTer?D+FRz2ndS%u*<4ARybhh_4|CWanCto!^-t zc7At)*r^V>gNSYC3w3AkUdMr-CH0b7UdyYIp^(F{Q;L%pbY?E6 z7E7(e46#yz|e8%FaI*i8cf=&jp={1gb+Ee}eoC z9w)Vigg40F`5=Fvhx+?G)ZgOFKVKNL?R+8b{1bE*(FM?3y} z5RMtvFR~p$=YxC%?L$2Xn(H@r{`rER`R9LSww*8doqxUn)g!{rKVJkBh|6HdpAY=8 zn6K`<^QE@)PS9REc-kstEPTj`J#86-{5u`$-|0~QvNQjDAc_?Fx>+R<45YwJ0Bp0u^7nCdZ?ZCP&@yF+UaaNU;KCa2|5?)1+z2wOeDN% z3v^bJIi{U2KwF58?tUF(Pcl!APv=;Zb)6W;i1pHv^`1652rg@D%YJa!kHj_qHw4`pELb@ahY}J zi|0;1Unn#FeDT`p=L=BXh%YUvJN^W%4@S>JV1M3c`uYDb>&_SVoqoOm)uoS}e!h?= z;7`zbOVXJB1m!;tSbAp7KOgOP`uX@U#BI-if%+9p zKOgR9`uU>Rb>|CysN49VZd=dv^F=c2&KK*QeuDNizSs=iD~2!5m>qvU`0s#G*3Q7@ zHc(%2In-^dnSMT6?)3BVYKYqofZR5p>F2}6Og~>ZyY77P9opyl?g%N9r-S<5tUF&! zcl!APRFBVg`UyHC3U9c5clZg~Z;2jmh1lE%>MQm`-8LC=FWKYC5Vy?)xvib)=fiHM zpD%=6cfPm}b=!TY+v-7insw)kdZ(W+K<6SfJN*RhVZ!S+&|a|TnBnGy&26B*VmZ`p z)l5Ghl{@`>Tn%ws5y)-%Og|qMgYu!v&KJj_ZaWTjTRJEovg~}3?)3A;ZP59^PCr3s zP2qJLsBL*0({0Mw+y?3^#zWnf%=Gh7ywlIe$q=`BgWML*^z&gf)6W;1U3R`$4|N-8 z>m0hfo3427U|PhhsAOQDu1L&#!KI~yrXL36>N zwnGBQed*A#ymY9W#6kI!W#Dq$WCXF zo&HceL1&(V;s|-%Z9c+l%f*gAyFlZGv5r4qO=tM2 z3OdJKmO%(*&Kk7d6;ua++FtBTkhT{$)6WO&PCp-VJN;CWgq$t9c-H^vFF|JlOb4BF z=J*r6{lyRRk2%yo=Fl+w4;r6f+4^vqdi=)OdJ{^@u4`Jfv!3^DxE4Dk=V9SNH6 zt_RP*ZveL=zcWJo@|*GJgYS+%AO3dy=>+vl0mv`lvrn=6<<5`)(;x6d{lX9R%X`o` z2lLJs@1f&BpP}PG`21209S1_oKdjI+%IWA(2pZD??JZ_uU=RWCg?Y}f6SO|D0h(4p zV?CgAHDKunmS#7D-1r#UCwmM!!^-(5=scPimzj6Ic<%TUbe`#p*Pu2!fqazh@bf`B zW_Tl~SyU-r*-`&H+8mg8LSru@}%9c+kE^ zP~QS{{sm~S;$m>$;sUsD;mtsN-vYAE1d=AML({}<#-9(aJN|rl+wo_TR7234ng6H1 z1f6~1jXga?fc!ll>hJkbf1d}98!_*Eao!Ppe&&nI&~Xra{s!G+YL6M#FFpAWV>{(QLG@u!k>Lr^{_&OvK^LG#e_G0U^t-$7@` zL;Vdpa}5;M$m7(Yb-kc*YS8`zeEx=wQJ|Fpp!q)zP@F3>`~<~0xK98&OFx)-=Zocz zKSAqKUaWTf30hNux6WaA0N>Guo|oWbAkM-UA22iie8|rD^AR`W&&T|XKcA>G?R+ZE z`16@GcnstM2WSjLp7AH>tbs@BPCH-lJN|sh?fCN*yW`K-pz{&-GyZ&a7;=8V3(#Gq z&Abyq=UqS8@A&iKVaJ~nKwW`i{+dX89tu3d2qSG792L8L2LdQKI-~1ggpHW zS)UKOPwD}vt-9FpC+N&kaNhw`r_F}O|9sGRsU!FdY|vWL$BdBkvfs}5KOHpY1Ul0I zwEv2Wk*V+{Xl&~~<4$c2h7eF43bOO%b;h5dv%Fqjcl`O{w&Ty2$xJ_AfZC#xr@z|o@Dp?vKIp72(78}g zn7Oo`oMwR3^Nws2LFX^L^k(|`!k_8q18=9F5B;5f9^!$nzf}Ou3v*~~nDKx5OVBwA zptBeD8bYB5HEcKz`Xw3BU zfxgqvhsI7nn|K?7oI!WpFhKlY01C(Tpfju-cY?<3y%-%TU)|@Ze83EzGuPr^)O-zE zrw^`=y`k>ZX8QROG_R|TaOX;pJ3(=|94%}>?O9ORC^P+hAn)|^p|aCY&>ksJJc9iE zgqcIj9~3^z!D})>=Vb4ExjWDjH1@L?v|lLPap#Nu5I$%hE!Z8}P6XM)(dGC$o^enrk^iC zbG*U`Kb3&Y0{IDaER*$WNei?KvGRL35*^bt+*0 zxI6BAA>I%K@*mtkznLNN&&>4mC8&MKjBo?^3^AC0co_;0g7yM~%mAIuaT;{yFN2V` zEQ1heA28fssZzllhTK}9^ab`WXutAn=vjKd8GpV6%@_Z6gy%)@SqdP3PDhJ7P&*Ig z&(DlMAG~+``S7#j&qMqWe}e8b0r~U6^#9XA=T~s>I)Kgs-wF4pITnAOhWhh09W-LO$qz^A!o^@Z`|~?L*E6-N7M==Fi>Ckh2pXGyZ%D zntOhX@F(bOKhPLD=-wRAIf5@|JMRRwRbF;8?|cEePX{y~eA@Bn%gK;CoL?wA?|eDk z@h7Yd1dZ>%1dR*GgVr%Y%DG0+y$SM;@HMuKk_;iBx&u}pfZM3eyc4;;{h$6o8d@(% zL+b_5T&6VhPVjvrpgCU9eIuZCNBHW6ZpePP|IVoO0lfpmpxCjz2-?=!4fig4Q8}>YZqY zpHG)NLdr-`-2-X|S3~QcWCrkfKj`ca(7gnQWE+AWooCpo%mS&0yr=)4{tC2)33O*b zvcu0u=N)!F%?9lebFlQTWeJ9_>CI>O`4TkeigeB*Xnfsz`v2)KLFcA|);mc<+cVJm z`EfJv#O0uHc@J&Rymx@q(V%k`Z!_%#jctSWJio|?&VAww7uehU5 zSvU6r6fVYS;R0%(CPTvov@QPxor<>yMV^d)=OcN?ov=It8heJVpAPx?e>&(KsR!PSKOe%*M4auk^HDSJ#G{}* zmoX?o)OE-&Ko|hbBAxe74;2=QC+=n|T7b z?`#c?8>I6LL3?KeOJN^Xi(FC742O6h`ow;$j!FKB3|KgxL z3Tjir{0&NrETAyghx$n$nijP|?M0@YFSH#Y^M3k{Kf!D9@c9XJCk^QCPP8xwuOCrn z{Q2LTY3B=NXd7A`a^L3*eCBaG`~>Y^Ko2AM9v$e~a^$squ=T{Cy_T=JL3^vAd%K}) zzaJzsP6X|f0q?tk-sL1bmvIWn9?*W93 zho4Wh9ezI5clZg~e+Dy48srw}J|2{HxXAmJVdiKv{Cup>@bd|%d@yJD`3zJRn1j~P zg4W47`~>eMS9kdNR@vbvA49{Wcft%m-*z+neACbH^K~=B&sXiB_3)r_mEq@uWTuG^ zKoP#*yP-`K>#8;rRG~5r^Dl|6PfcD&j*1Uq|%|UDT!Tm8-$o@;v z`Q}=ny^EkdTZ{}Jdl?x*o`UwKgZ5-4Gfh-+WSsaQ8FW6i!_P<64nH5)JN!KI<^S{t z?hHR4dNce4?PUYsr^C+h6Li+r3edffj#d*v>&?M)o6ZbBL1(T%1l?~f-4F!YAANc% zWZ&WwYX|UpXbwTnZbn8(x&Zm@FkeHEgA4J2E`rXqexS|#^PxWT&qv10KOdVj|9oQ2 z{PU?j^Ur6_%s)@?H3YrrXWRM0-udTCYiIC0^=o72pKtV?f4+_37*3^<;7{YpD#f3(y%irq8mX*Y*)%0qVN zpO3hmfBsiCw*0SdZ24c?*z&)=vE_ebW6S^M#+LuBjV=G%8(aR*X8ZX+pY7-WVz!_E z7aN1muYIxH*z*5sW6S^RjV=FgHn#k~-PrQ~Zez>;`;9ICSF`>6U(fdQe>2<9|Ltr) z|97+f{NK;^^F_K5xL>N!&}0Mh;|u0e%NL7{Ek!~81I;<}Gyi-EnsW!u4>L3W1g9&| zIS!yX(&KJFU;JnK`Si3KsJ$?O1C&1E*&t(<$!tF##Jl}`nC$jbNv?f-OIud@|4;6=MzwPHJeO)@t)}?$3ljQFFrHIx)U@*# zSolJGzSN85tUEne8O%WTg3>)Gy`KV|1qAcQc{G2>L;a!5_Va)J37*S7%mhxKT}uib|dlwXCp%)Xs;lLtiz-i`7FL=>zVkyMHAOdDLn^^wuH?aiW83^Wgn^=PGNCdMdn^ z7GBKI@M35C`GDE&=R6RN5ULbv|5#hzLlA&-R8$-xrP+WuN@Ha! zB?l9OIjCHC(QGo21yo<2cl-J9GPL~tX*Kc1d)A+zJDFd6X8rl-z3b1%pIv{R1GUMX zv;KVen)T<4>25z?%m<|lhL2o~3?VP)gVqzsuLAk|#dJ3C880uO@$+K2)6Z9noqmGu z;&?Tg>E}y*)}1eAGl9?91N&#Q)6WOT-F`j*iT`i2{``NR_2>V`tUs@FFid%o z@4EBVZP%YK@4Nnd+0FFxC3C*zOL^9vucov8d^z335_BKo3whU_9t;d-|Jh9~L2Ddd zbvylh3DSpT-)nW}pRXo^&b4#h`2w`YpqT0B%l9lhUsW^x^ah=iSI_kGB|GcR7wt?x zR|ztNJgJ7J^?bCryUYryo369|d~n(I=fmr+Kb_PeaW`l3|LL#uoqoQ2@3Qk1NPn@@ z&um7n?rcT}%j}&Dg|Cq8XyjuEdGX$5=gVp*@IBTqvq5vlP(Nft%0N(fYH=}yJjsT- zB^}Kzr=e~+&-(MhY1f|*&%6G7qz-9ERZjjt{Uu0WI$AnnX9xkO^=zk~4~v~p)B0oG ziU0Srg4W~w{C}Jk++I1(!7v3JPy1bezBud(DKF!Z(p|Ie#Q&RFfBxUj`t$#8)}MBu zbhp{{=Zo#GKVN{xh7adjzMReW^Tliv%NMiVeuB;($zos#`9GWO=YOzRiKPZKJ;KUd zdH{MP^ zU->)zd}Yn_^MySq|8c(VW?~2dU4K4qcl~+m`(^)y|&j-b>KOdI6{#4R#2wDv7 z2XCDGfBGwX(E2o|pD&NQf!e9v;C^s6>(3YYtUq67yZ(HU@A~uQbGDx^UbFpt`P}X2 zi`Q;HUlz0fd{GX-W_A^VBw_y(_eztX(&5E+B5zvkTw8p?!ez= zCkG>R?m(Vp=L?W~xtV@GEq6z_IT-5RaQ2@Mg57^U40lJFJLs77fBFkJ77i%OM9rhoY{Xquy_CY z(Agbh?jR8qj-at>ei!gs8t~kKye#&)gKVfft=WIRGBF?Zkq3ZLJOKRH+(EMNR*-ucqH3Nd%^-+AW?dk7ys*6s~;hc^4q zm+J06UuYxT0iHYHcY(wqZ0_K{^G;A4W1Ty&=7Y=~D6{{3DewOCg)+h{@Z15&PoL5J zBo6hHH2cp7;_g2mO1u9=pF7|N`RTLcPY%%B!Fy)JnEHFrej&8E18Jy#gxP<-2i$y+^Fz7Wf4*dQ|M`L&VF!5b0OZftX#V`q z2FZua>^~p;cl-H}*&So<;Nryp(?RPpz;g%pk^Ffdi$7oULelwfwx2J*yZwCe+YMeG zfaebGJMVmr>^E}e4sP>8<_WdJN*Qmg$_DL{MCK7pD!M>{d~3C zcjt@8Za-hG=H2O%XAGD{3K?GD@zdY>r^W|+u zaGM--W*?}2!&Ux+*YzK?p7UKa zHkp{N!!QLD9+3VUbWZ8M<4@T9&PrAWkr&HdcfJ&M{t4zAN)9ETZydPy)K`kK2L!DA9|_ZmapYtH)ffwAk)hvu$7opd4XKDmki zr@z__nk$0zue=yJ!FLsTePt|!nVletWcGG6v$dgS>$CoRpzZqep+3ZH(D@?lAhWk) zG5aM0-0TJ+Xy4#9QXA*7#>D^ftUv!Nv;O?A&ia!DbQhz%EBGFO7s{?bL3eV$P|gJP zkIX=85qj#0CFHF07t=v?3OITP zm!DaF{(sK$^Z#p>pD&)Xfcj9EI1W7c^x`$k&xg-lem;8b0&b6k#y?kRGfV-kg#oQo z0_FV&h`6}G;b=GU#eJ~;pcju>em=VI^7HXym!EO(q2VR${PV$emY)xAv;2g`^Gnb= zo7Ij#VQKYMzuQhwf9WM?T@z?cQ#Iqym-UQ4wL$$PcIKTg+Zlg??kZmu#}M)awC55O zcjahdeI6Pfmsx&3IPdcF;boVfkD%cZG~xgB*X52sLH4`^>92PDna#)v=_kEpD13!v zM`JWY2xwm?IG-0YLefvM<4@536HxyMJT3v6uLHRu9nB5Lp>8jb(D2&M^7FxFm!A)}yZk(41SylB_Cxm_g(JcXG%j%vHZBnj+TRLwJ813>HZGy8 zI`RKkevYZKZY@*x=F*Xqm+SBIv^Cd_hl6|1O_R8Mz=gW4do!~vJ@{B)Ux-;#3rOpT$ zo6u(b`7)kqCusitGszSZf2IBZr@xkV{Q1(| zY3D1DetA%yLmHbvvI9Ie;qJ8arMe?zY(gB|{(y|Hh&zJwASmyF$0k7gPC;%FMsrIw z)GhTaKOa=P{CrsN@{`F7GKL=nN=qPp!l-F!A#7|y-0|l_d9?JNtUU35KFiPl#VkMn zmxKIgGI0S5bZjEu<>!lH7f}CkB53aod`yg4dE)#Ylm!FU0U4Alw(qu5p&xheGKSApVUvWdz*?)$g zFWH%PzF=oWj7^9;BF4a!l_vgoXZiWxo8{+!f0mzOEDTdXaRypf@W$Qc=PPfQpRbdX z5MvWa=Dh;n<>a&zvEA%g;x~EOt2aTUQ`~}LP@qM!Ze%Wn6dFZ$hozP!)=^TlHjb_cJcL>Ze{ z&A;>iZT6opue<+zaoZifmI}PC@iE9QcksGKupdEV6NedozJQHQfYvqQ7@O$n!@aIC z3p6ec8k;x|THk?xY@(_UG}iC%6LgOhc&>%ey2ktNKVN{>H9iK9Ok=XZt zI_OT+SLHa?HO}UT^w}=6|9pAg{pX9zh;RarO%Pbum;v6Cj9AwQ4@)A(Cagf=2wT_q z7`#TN@|C_k_OXd(s5_6d|9pAa{pXA02zP?VCO}~WTGxmiHbjg~NP@x#d0k_4oh4}9 zA9x)gXkBAGgbyE^D2BRYKl{&@yFuv(;STWF1Z*83Y-|GGy2fOF$k@bo_Ma~|gW?up z7IpV-w5Sf4*Go{`19hgdO0q36MWQ>l%^$NyOO1Dv&>?JNyKXO_(zx#$e2`tZOue z`g1<}&zG~^f4-QHa07U3f*R`@mH8oK6Vus$zMSm-^Tl+89iVdZ_gD?a5oSawcpl~3fOn0=M_=1}SGTy+?^79e5%g@LB zEy0oNSS_=kwN51KeSA5Mk>>PL-)S_Xa4!%xAV`3|DAs>vT6uA z3@y_|LHQeWCR?)u>Ui^K=ASRVGyi<~8B`xR|9ttK{pX9{>_1=EH~m4QLz#d`vg>yi9fkHw$dP=9iB{Cvso@$&^Y!VTcEz20HxYh=HXGw%EwTDCKD{CxS}{pSm2 zgdH#Y9e%#5cKG?C-r?t~_v}Akd}jao>bC#R7oXjKzBkAaXZXqSm9Y@K)&(@?%*s8?e?B}9v4e;)=?fg7G3mq1kTL1w%s(F;cK-SJxbx42F!OdZ|9rR~ zVjg%*x*M`y^95*3S{qspIa*D8u^C$LY-j%YV6*ejhufWhGTA`-&r7@iPk#YAdsW>L zGA7;afH5Y0NR43%sEz}VRT)F>@&TRs{1UV`5qXaRXwT$j#-A@idnPYC!q*ZpfBP>E zKAQ!!o|U=Oa)ls+Iq3cs(3n3cY_$X-bG;l44U<53hn?sj41e0_?8Ap~^p^UH4Mp9+;PY#tnLv<0mX;Dyd< zKM{5S-xr58zPW+J)NbO7YG%m!diBgdA5}a5d|dDRQ|;CN=?{vTe?BZ{{`sQW`RB`a z=btax89?V)ZvmZwt--{w6*RVl#moyFCv7Lb$Y%bzf}tVkMLzS-N7>FlALl#&6a<-> z%>46VI`dD^9q8cote`Z*%mD5ugWCe2bQ28?r+DU{52BraK8$z%$z%sfH{#vUbIq9@ zeuBn-(dRKhcx*SA88kK=^dg-3=c8cfpO3?xe?EWt zfBFM&=ARG!nSVZVcK-PQx}GNhB);42=YMvGiT|6KQ1%kS&Lsw=qX+T~KS67zAA!=H zy2DS^$_f&z-fd{3_GoUeiVTYffvy4IM9kf@o z1GJYO6gHrHR6zGKAl;+F~LH8X-;pYR;{XpRkKb71Xf)=wh z1T}!d4`ep@&K2ld*j&cK1&})@e}c}eeI@VklZ%nzCnqZd_$+s1_TOs6*|nfG?4WoD zt)J6qWUzb|@9^^(JCZxRq3-Z!fS=9&$gLr$8QLZ{=>9()bbk~muRQ|oQ;Bu}*Fm6g zeF@tG;Oy`de22ke#)<#U8Gin^X88Hvp5f=mF2*UKJ8(dE(t`H3fX_X9>}aXQ$N&z1 z4Q2*2(E4spMu(rEv)@7IJcH6*4rqTLv%^o&xy>N{D@KM8kU609vq5Dw=qzC_My_sf z+%Yr+Va6rG{~+^0VFd~^(Ef!t(hfi8w=!6Q`bWrNhRj9|KhT=-ztx;8L2J@s_mn<@ zuImSfi@L+l*UBLG%ddJ34UgCE4nJQDGl2867bEv;P=0!0&aktKnIQxeA5TH)0d#*H za(b|a#slb1U~7k;pfix0JQ{*P`=|bN{+|wVKj_SK&>7~SvW9^XvOfQ&A;T2ddB-n7 z_uDRZw1n9Q((?*bhMPO=e8JAJ^A$S-`0f($+B$7eo`>uQc){+l6I70a_C|ohR+|wy zUwEzrl`#jH`#bzx|Kk62&{^`JwDp+V;pY>1$lXYw`-&gBBg{Dd0IUf%m$eOvJZ4FHB2w78N(Ei7)TD} zACOvDn8MU7Vs8lI1DVecaVO~RDn=Q|{smB3FDSq;MG!Qv3cB+aROYio`~uSt4hK+u z1S&T{^^rcqPuQ97xi1iBzJu%rxdY@LkXvB-l~@~s-aQB1t%J1x#Tk0v3}|17GQ&>T z{kt#J9d>eDWQ3mK=dhFGCS#!@=;RqJ2|Amco8c$uPB^eQ zquoSMeF>^#LHQMQR}|>pSJ0g=;5r?2?+2(}k#_hAy5}pIuOWz+6M8=r=pI_gJ-sdV~?B}em?GJ*!cw9w`BPFESTZv^KgcrkHZ~)g3|Jf ze$ZXs&^yQd9e%#DX8ifmp7AFmBZJVoJD~L#pz|moXPUlT>}mNjpJ6A5r~_z?t2wA# z;k7D&^)jj2?JK7@ZfZ?)BxR60q(ald<55f zAhsgIM+Zrq5J)}veo|ft z8&s}&@I%<3dz?6+>=*9fyOzM?GoUqFPe6BdT0_bUP&*h@W;_;0)Ip##d;6aKpAO2S zpmGaTZ-MSN0O^C3Ep5;KPY0zrP+kG&6M2T6pnUSM7;>lNCnkm|pgR{pW?;)J@Uo|w z>mu?!)sI1Y?&dS>d>YK~^I15<&*z|Xh>}5be+)mL#5??a9PIG(<$Q;opf=b8P`d&& z)(5(C!R|`127n zQaCb0!;ziwr$=-{&-aO|MUmUEEBmpED4Du7KjLL`9x!^J?pJ69R{mXoZoi9P<8K{iPhL%6+&@w6;swUe3bk_)^ zj6x~LKBz0PO)| zcKFE!n(J27!dPqdgx}#OxV^>>DSttJfw}R-)Bn?9_gsO-YC!E!@I5QS4m&|@JD57T zCy+bsG&DhNCx&hfO@^PKb+}JK?R9a7ouK{bFNGa;g7&8|);dgn!7Q)E#K<7T0lKG- znL`V5#}=X;2*2|MwkKX4dT*dP!_KFmyMxRfc5;L=7J}NK98(!Sc8D;9fcj5hKPGBp z`0+WYUjXWhA>BEc#mulF6Vw)0iAQQ)!`@T4&g_jGo=|Bgkt~xpFW9!L4;_% z44`%hrxxhUU%$Wqr#F+Jmy;2p*Z%MS>7Y3WqU}Y}Yw-8~^i&e;?L^Y6`1k+xFcS2F z?h}B8mC)b+)7=T_P2`^FnhObMWWCIP|4+AIU=RV{QD^S36LfDTs1E|V583_y|LKOH zHY`8*{>+^n3_r|4{bdeEmqO6FhM+#sL#Q5$KmVsILi>QAJHJ5b6VxAurO^)1KKYNJ zx(+nP-VpQxsSo(($^Yq~ehVnfUxLm-0QDh3=OBRYdk39;q0aCVlvXl8<8O)F6IF8^ zf3ktb!YmF(;9GVp=XFzOb1S`uG2I zYfzq1cli0p-C-wai~!Uw2IZNmfB&bOfb0N`bMb@P3O~$2_XEQ7j5>I{5UeNr_y6fC zpgaQ_pXP^@|5)>kF*MJZGyDXNLxRrdkbm-jIw-Ay(j6$CUV-urD8GR6jWFomdj|0Q z6)63I@{VRA_e8f`$Dg3P#6bBUbQcNe%zor_DF65Wba4Jba--94Q2udW`Jb5ydLJ13 z#XtG7EB{u@t$a|<@bh6c!_Px1{^ zHbc(R0G+AvvK-T|uOEZfyE6QII2&}%N!-dm`LQeiA7%&J2{ZF`xx-J;IB7Pk1Gq2t zYB|Htm#Z0mzFO|^^W|!XpRXP>{CxQwgdKjq%x3ucl9^)_=uY|ddby4Lc4`b&^L(6|6-oIjcYvgepUvn{`P!bj^7UhfpP;d27gmOePwXM_^Kw4} z_zt!Q`yGBhJnZmukp|@c@Ip|W*n`fd0=0u6a|bW_8Fs#`b_1_x0IyR6&2861_)QE9 zA>ektKEux-P@V<#PdFJqg6Eb&_qu8`{PY5egWUDl;V0;xJQhxdiQu{dIh}y+PXqaL zH^a{d+Z}#B-0kpFNfUA|qYubU@}Rq0klf@C8XI9M1iJ^+wuPRb2X~J&!%r=cy&(7S zBDqJL;V0-`8_*qwFG23%XZXp&%PHd{IbgqPzVInN;%Y)JosEkMl!?#1QfV#Fk_%nGkg^L17M3 zw~(>WAs#AsldT`dx6Db(rDj18dod4^A`u z^e|`$0@Xnek2Cy?>0+Gn>^QV61NApS8+1k?()@Q*7Np+^$_t<~5W)8*GPA8J zX!$?=!E1-Vj}JTid;(fW4Z4HqG<5EyoB5}PK||1se&(MKx}ASM>~{w5C$_xvfBMto z4nINnExx!8y2p+A=fig9pAQZnw0&^C(e{5e^UweF%s*evcm4^^)1bA##mqlnlr#T) zQ0)BkVY&0qMOlzC)(})KoOS@;+Xyr731~fFHuKL{`OH5bY(HrGV1J|St7_+;ukJJa zd|L1P^JOyg≪;KOZDJ|9qJ4{PR#&Ll84#Lr@lIocBJ+?GBb4YZ(d~K=D)U3|`X= z(g!YoLE#jQIqwZJ19XlPEPTR2X6=WXwUq%pzwoTy`RB9U(DDytPB7G*aOR&6f}MXp z40rzdD61hznXw@VW)5iVQ5;m3?{@h4vf3F|SA2Zw&HVF)Kl9HA%OU;)oe%N?MW47J0Z`R4;?=bsPVoqsB2Hv}DKfSfz1+x&m}%k2(7L3gccFfv$z)>VSWP+zbx zn1R`#F&!2LbFkT)(ag4nnr+Yg^8xgpn5OK8Akevcpz#SYP#A0mm1&UhbcBWHdNgy4 zq2`z~|9oKV{PUr?^Up;{Ze#(ualOM&P+t`6#(HP)nf#!2jAz*xLY}U6_z8C3a-^`; zhMK9*{PTgf^UsI+&Oe!QAax2XY~O*#(V%OUIV>3w@x2($eacX?)R})iPA-E2GQ{z`{O* z2^#jGb<6e6pf>7=iOpKd9Zt{PP7n^Unv&&Obrt zektWP1TnKB;sca#Je&Vdf7K6(gBKusr#t+7`rYB@>uTqp*{lo`y;vDOzW&Yh^VNSQ z_Og|rfX9CatJ%+mLVYTzmNA=D>-T(fd4q8(Mc27N0n7oGG zq41vR=Y!WyKOeq#`gtg~0eo*UEZu?JrUc3xpfg6FJNyKhjgq$?GyQz=oayJo$4);V zJ$L%4^Y{PsAD}w}o+Fj@)o5isXx%Po&0I9Y&j-H+CW6N5;AMS0!_S8uj8i~s8^CK( zL1hnU?JhUet)M$2`I&w`;CA}?kl*PiQ$AW*UksT8`3f2@1(o&DNM(I8D9tlWe8J2F zDeKvpem-D!`uUI@a(4B;TmPp&1=aVUwk7E9$={4WAO2_j`QZNn+Xvi@w*Nmf{`~)) z@#iaXCrDYJ&hYak=zi7rj6WZ|cKrG9z2i@%d`MZpt?B>t*P!-kI;iaqX{$decKG@F zG2_oy&l!I{_WhHRP=J^9pgSEv?fdVJhhnRs}*53h{1#087I#_bR%KGn) z;CWDZc%O!vbDr_%gVT;bAD(yonUs%N*3SXuThM&PXGcU?f0*&-i{p$xA3TQm4_wxR z-0BbUBixSNP&@WB{(P|8@#n++jz1UWBg*11{@9=D4G|aW&MO^^89stakkQaJ}PCr2>Q-J3(#) z-MbDdTS4^^=-g&!$hpJdvK};l12WehDbFp2nz@|u=Yz$LKOZi4{Ml51TGkhX+y@%R z1;r7ptOuC`T1$)UPb}xfgUmuM>k~j`f#z&MW)UjuKRf<>{N3@V&4d5bA53Qa`EWWT z{<0o)*Rnao&!^%}h&0#@^xkq#sq|4)AfI-3+!)@!4c z_4FKCPeX0JZ9 ztpDtYDC>(Ef4(YbM3nW#jz1rlJN~?S|Nry{*^ECQ<};#}^`9MoKKkzX^UQB(Sr2lL zI8vCv&M-zgzu2h=5--SQ{c=$JfX+{amG#JZ8+0FGJm`K}NASJ18-M?w4!Zy2;d6(d z50W`2!p<^nXlI-PYD<9b*|ZmAumr8~1D#u-#miu6&&puQ;mGij0n|5t@9>kOk>O(l zjLpdSk%5UJ1XN~#+UX1jlI1uU)Z{p99WFC4rq6pI%+KxXTHFHdamq)_T^a9#PThb8p!kB3% zculT3cs_0dM<~NY(4BW+F=fV|GS&a5gX(9HKOYD?{C&XB@E5)91a8;Xg4Sh$_U1MO zfz~ZN;&%M`nBVbd@_o?$NynYA`z|;ZG8QT_GK6F@Gfc<;jV&v3Pt;5W?bUVwuaO0< z-vOPM2bWLeo~W6ND*yaDq^^6w@9-DYE&JN#s1NSnuj zHr8wkx)6pgCL~1~bt7C3r0uXwBw)(D(|ZT*zf-2m#A6Lgsy+`aApt&vh+i0H1*i8@GQn z+u`Tq`3^ssLHTGh!_SA)8Ng$3;ITDOS)$JX)(2h>s1M593_o9~GyK$K1&skh`uL!= zNnD`yph$Lr+J`VZm{=Nu%I^K2{!$&JAJXOkpQ8yi{{?8=0OTi#Tg?f%^~Syb(;sv* z{CwEY@KYW%j$-fd^NF#;&!?br6f|cjkCe}wq4Tiq3_l+spZd zY=)l?^BI07GBAid^LP09*xlhLXr31qAF7Uw6JhqafY!)9`#&Aj1_aI5hJe-xgT}m= z0e-516&QM*X!&5Pk#xXb8-NmrTiRp?{#LT1!!#JX|%&nP+J#0KZ4eC zfyOTUzk$vdbNC6;4@yJeu~%p~>;t7E(AXAe?wFIo5}a549ezHX4q3z2{uMOV9lG*Q ze#pxI&8*^KDJ7Z_~`3N)y&+hQ^p)|u! z&^l2T^!0$vptXyvD<7bl37T&P=W}+3pB$YGA5RFv=T$Fw85&{cbI|&6LGao!Gq7IJ zT1U`615kW}){LX&WpMf0$uJRgClh!*syf5ZN6HRAAFDh3%&**{3ikZAiEziBj)X3`X7A#KRpyQk4Zp3D6X;Tzwq_{bXOwu zdw}O%G3`I__5XBJBJ_jSm|(Mi!`J`QRnhc&GBbSe0PXuGBK#J7{Xbol0{s)dLg#Nl z;Rjla%I)y;(ic#gc3t_unGu?vnJ@mW=D}Fg4VpuG30lhyT3-cQx2D}-`ykxm=lTG~ zDG$OKe)?7XpU%<1FcCEF%VF#AlOq(`E|GTt?J4~!4_%LsyoUUtw8PH_j~OR&K+nf_ zZDpJSTKfySBkp0m!_PW3hA9us8Gb$l%@LS8`~>YgcyZX#l7oZ6>;*_)BEv**{Uyxs zQ-hIVD`>5@JtMWDimw?*>jGV8#SRiZZLF>FI%rHBWS=6##Fx&HHUujxxV(a#$)L{w*|T8G@biJb!_SAt4nLb3A!i{4 z*ZrRkHWRe&S>E9%L**+Q1;z$jP&*ObeW3OQXnpn#P+5d0+(7k>JR<|vF#YcgYCj0C z{97%u61G0%ku<~4$My_6pMcu$pf)Pmfa>e%pgl*>eM6HSey#xR8v@0(Fy=g5 z1~UU>?@%`bWbaTv!_P^++d<>xAuIpn2e16^3@Il;<>9e% zX!-!nn?uvb0S1N;P#N>k-eKnhVTYf3U;a8BqRz`eS>Colih_(1FTmVemf5pD#dlZo0$IN7)WPIVBmUfaZBX?tCyATpxhW zd7b#*pW)~KV1}Rn!x?@W{r^Ax#bPJR2hAsK!1Wy?gBi$7ke?n#L)PAb)`NHc{Xg9Z zG^dLczM!>0pt}DFJED&SZbu(vnE1k-;im`a+&OOs&|LD*$KDPV)(Q18e_J z2b&4Hb3>azIRLUpp5Z5`9IynnQInY_a=^+uerQ>z?eLReS;x%)ZtH-`6;N9Tye11) z)`9#8ny*9mBS;KnAIy);XnwSZmUT#XSvYk;{3rqPBS=4J-i?qSLF%|6egy4Z!d0Fj z=GcTTJ_W7+1l?Dt%=q)MI^)kr+KfLR>NEai1ci~h3K{HA`hiO_ux4Gd@1bs6V!fIWIbT}@Nt9fgZmA(p#5MPA8RkaU}pTO`LSm5 zOVC+Jpn1mM3_n5l?3}1&obvKNXdQ&(&j60!OWn=Y3ncvwEhETPau+6nv4!RU!G>%`SLvD&J!@RPD9Lkah`D}$eb7F zLFRC1y@a$q;cl`=GDm^Y;pc<<3_l+{X7~v==f1;F2Hpd=Kw=ffiJSAgn@?Tp|tTF_W6_zdjzjF9ofnT!)(tY(DljrM2WsWAz(-kf!reEBsq$Ew$hL2HE=z-xw9FfeQdmAf!KZOD3<bzQfNqptVo!3_o9YGyHtj52<4oF+=x0Hyn1psAt*vqTXdEI6qah?0i`bI;Wd68x}t>H-gTq zfa?=vn5ZepFcEgX4BXyo&^({R&zH#zKVPLY{CovklLeZOV&Z_Ru8B9U^ zr=W728+6uzBX}%GQ4-R|VrF&t$;9aJ)9lv&=?^C}{(R8S_!D%G2l&1;e$c&cjz5_l z87DGII{ai1b@+KmongwuZpNPv+9CBENFC^GJceGUAIu9GCO%|lUiHu!niky|!1voE z@izpmy!n4R=&sn8&D;}TdV}QUSG{az{K@cyA^*Yt2HOX_8*Din87962?Qh=RVEbTm zgYAR$4Yn^2b4`53%(?1SFvCyHg$xs4hBN%+@P+i}4l+X1E%=^pho7(f9ez4693JXww>Lq9|LO5uRtApjMc!r&@x=mBi;U_1OK5*H| z%(3bf2!qBY%|UMGSoIRr2egO8<15fy?r(>mpuP8?_Tw9Cho5il9e%!*XZZO>8FW4$ z!_ODmpuEQY`i1#?DNWFs$L65D?wwK{f(+(hHys9*YlyqXvKW~@zEYnr)x*f}@eQ-Q zmM>$E6lk2?OY!uqY{sfjZJsdlwU&{g&`YpqR<>ZzEKNr4E)GVnE>N8c zDmOr8KLFjiC(ZB^T%Rd}`gHx#s5o>5#htA@L8||F(i1S|2uZgWH9mJ|nn|+YD+qfYx6@!U^2Q2krZ1 zWta#KPf*_r)c#|IxCOiq8q~K1kMkkgx{53i`6nQ`a>zY;PpiRo4P=kLGjx34o$=>G zcgLR(oE?8In%WQqI#+ml6;glK9drf+=w3U=pB#c*-HNOZpnCl$EDw}|(kQqO!T9rm zHRDePR)&e7a|OgeWgN(EafYAg|Nj>Ug(-5lf!%%B@uw0aS2yTBCvX^o*9LQFDct%$ z9dz!-L-3v}gqa{SK>g-dpnd7ukTK6}R)&qBc=clB*#&AJ!|%U?rnNMv-Jm=N+WYqc zDb5!0Hw0a{@qaqV-2cu(C~G+2`#*#kem(?^FT(CRgN?C*#viyHeuC}}e8tQFzUy0) z7gW}9z6OtlgZk&t{x|X%s}f^F(B>PUwkv210%`py)ZAD9QTOcrZ)UmpCtqOY-)g~? zuyK?}_6$ECJ2U)z0-B$l&am^DKf_P(n65dbzyCs?0kUVt7||b1;%*3<3bGeG&d%_0 z4QMYhXe=7EuU_8)ye<;&~GU+6>jti6&)*yqI95L9{N|8(&A2=Wd;J$XTOJ!sy5VWKB5v^)Tv-JuPcUjU6y zf#w)M_xyp!pBOn`XR$JbJoIpuNz0L?Gt|yyQkoqfqyQ{0lZ4N80&)9W(9x$=|i|S32X$AMs2pzlAfe{Nm5D z@^3Zk%KzM;y9+rlzF>El$l+)(@x_0ZpD&tqC%yokch1iG^C36u&qw^MKOd`e?R+B6 z`V+K=5PV;}H0#e7{H{M=a=ZR~sV(^Pg}&g=7utb8UobFidBF`bixb?(fAO2;=L`M7 zpB~H%Tc3)%{(Q;q3f?yl8m~bL&kf-7bd&`lV`A!pKOZRv{(P(+_|p~?p3;IpAIb~< z{Lc+KlZJER-)h&DU;JHGehYVA`6J$G<*#(dm4EV&tpJ@P@dC7m<)OpR7vEWap5SEI z@`By^fuAp#7(QrT zWS#i(yTDIQmWH60zXg7R_Ab5rFYptzPvI4_;Ln%rfGhHy!h?%^D)S;pz*NxEy_#=cD%lKi$j!Pk;5_ z<>!OXEI&CI7(TvWpD(4!&=ADQ$jRlIC;{5LZ}#G|%TI8dR#@=o3*o?@pflY)m?8d= z?_{ui@!I9*6VRFY>Rvm+=iF-t{(Ph#_>+Or{@Mcu26NDP`VXOUpm9=;4hBp0_y4C8 z6^87tKS6dp&=35%vgrTx2lrWig8TT7Ss-IdtPCGP=go6uGJNDnW(s-z+y%7%Zh}{$ z3C0|XfG~r|i~lY^Up{vE`RcyQPY2EewhXC_whF8VY#A~eZ8?M)L>@kN`T2m`VIqSA z>qHK&h9J<`|KxhcDWG)o;x^0APNs%SoDR=Ef%+ogx%t~JKQ(y}VhkP(Aun#b{Nx0Q zDZBxzJHW{hatAaPpdAP?djSi4e5sj{L=C7I6FW$#oX^7~Z4l0Y4wl z4){6uI%w~o>(3XLU4A~k4hi!I{Q^H9P8NWxWnygzl0#DWo!A?KIIsVo{`kBLIM0CWhns7UFt-4kS@i-xA2uV* z0-f*i?HZAB4~i@8Ku90zFblY?%V5}O%V64QtHH?d@x}7_QZM>BcfLH$@^b|PgW1c& zF5vlUP~5yY&GPfbX_ucb_OtxtbeI|BS-iXmB+euWp0|Xwdy)kp&pJO5aM`ad<5Gl}D zFetBKFIO&bTxFd2B3j@lxL%1D`1vS0;OFD`fS>Bu|4)AqEb#MTxBzkG%6^xhoE{xP zFBunr{gliMIR^sN)_$>>1vEYY@t-%;fBphLA9x4+eCQwWQ)wmS>?%;%37SKN`A@du z|Mb_O@ZRk5^M$nQ&r`e&L0Of;mM^!n{Cu&S<);G!gNQlb)&w(&j;E8KOgD`{8U6a}}EZ zUu<{z`DC}t&nL|+KVP&X+0o7N^Mx|ho_>~}FVqEoK2Q$$`A|LJXVNOjI4UfRpH61^ zSq=(=W|yCj_PhLi+z!dZFS#8iYC1Acd^sI-p0~iy7xDr>A4muMd?+9AGrW><%FAw- zpD+4dem-sS$?)d z!}UqH%g>k5EOcxYR z;gE28nGOx7*ZeNM=8H%>VP@bN-)C9{c}%lFjn- z)pP%!uZmfIzP!!<^TmDspAT;P|9p7g|EJPwNEiu$@^-q*&zISdx)O92|EtUVKVM$w z|Jlh7I?s($>s3C>PfpHLvoveDW-~EzzJ74o|L4Q&{y&RBc0h2i6aV3wbpYz!eUyrKTpM)I#ZNDWK(3vnd>g3hqt z4E3)(%g-0v`F}px?EmxOcK@GFYanZd;r>--`T3>n|8&rq&#*J^pDMfje4_30lM9qr zLH=FM|MSIq{+|z4`~Q5n-v4J3$PA{2pjqXh^+ql~Uue7heB=-D^UKBjKVK~8|M_6C z|IdfZ{eLoo@<1@l&lkZiKVQ_d{CrXG^7F-FmY*;BJ$Jrb?DF#^Kg-XT!Yn_*XSwl1 z{RcWH8k%1?7+Jbsu!H>uxdVDO)L--Ye?FM)|MTH||DR54A$1GPPY25WPk+Vk^793^ z%g>dp4MCoub+W=NKVPuB{(K_r^7F}WX2_a-W+ZbbL(QGe|MS6Q|DO-1`~PeLnakP` z1Tq&?);{~s3_k0oy8Qq2H@}^KzWNV3OVah{3uZ`L;5E0y#B4|AiP^9_mAmw~Mgh$=}KOgt||7^Glng{0p`LLb;Co%1{hvKf_wl}!FSkM3SLB0P^aC^SddgA|L z{-6KL`G5Ye=Kra6`2TdU+G78oFHVE@1o{7b0Xj3a+W+T^>&ys!iq;eVr}O{(pUwaC ze?I?DTadof&fxo$K<(NW>Ha@o+-CmyBHRDx3(&c)`Tjp&JZJv-qTU}~@4sT^)Z*kl zHS2YG{3dRNnV+hsiwDZfpf&+W4#ozZK?^!B4AkzMS`KNOf!em0bc-|S@)&{kKL3KRHj7P7Te>RshPI3NQ-#}AKPhgcheYC(G5Bm4te8wv^!2PAz@zB_~4rm!>zZd<%%ocJQ1|0k%8 z`XZVC=c9Q4pO2IMf8M+DfBJ)P{+|z{iA#qsHV6ECv7Z^VhIZnM!_45m!i(d~KRJ9E zJ}v<5!#nN_o(EhI%@Fby)HXj1N>dIK84g%X1f87(a_iI@#wjn|K}ra|DTWf{eMmdg%vaZ&xh>9g%!+QpuQ0YqZjB- zwL(xo@I^X1`0NqT8N8rA@{{$LZmqcTfBK7b_ni-Z^Zk7IpAWomF@w7y=!HK!_*|C^ z&^c88?BKKy%15B{dta<}{`tt?9o`@LbQx3*y8iSKbg+D3&%P5pKD3w_yl(eHD` z1f3D|P@jD#tZ%1O!#L%kzWdG>{{E1(GMgEq_JIj}&9)>c9n5wHryvLhoy$ivyt z^a4@`?I&{9faYsmz~^CVJY=;5hv!3A%NN@0pmSL!GB}t`e8}!FQ4vYcpK8V_FSOmk z^Ozv@FWDU?YCbiXsPOT;4MS;zEvQWoUf&5ihj=pRJYwgcFD5(xe9_MQ^Cjqf;$VO9 zItM2W&>CO&ogJWkX6>MR?-@R7g2s)+U4K5o5^msiYM^nW>3op%Gn?<{qv?J>AJ6vt z$qY(A{d_+kPUidh!rpx+c<&msyp{%N-!38Z+M(uk^Zk6(?)UR?x8KkAm;XI@9Inn_}mmua*6OCRDz$anNnB1&#H+%m$s)&0zi_8xqFgu{lCv z5)BQLc)p*HqWyk8j`#by3KS;6d_NzCL&6xe-xpLLg6fWxU;n3r@+5LN!P5JqWWS$} z)BS$Vx(qENRy%{^7o`4yH{Z{P{)q4aml3K=6JI#t?r|kGH$+1eyCv+W+UPcxJGea9isoJKxWT%zi%~vHSgGU}O+FyrUuL2~$H5D^tTI)`Ul&j6RDc6i~hd#SLhE2m^0}?F(VQpD(oeem+q4`w2R?nuEasyoWbXfnkaRo;(7M4^yUz zFMjhv#uoqc{(SV?_vhpPzCYDK>ESc)&xhZ6e`))1s#@_+iT(rrT^1kc7w`4XK)!0&Xdrxap%AP;-E4ETK<0o zmH(R<7(_sGY5!02{``NQ7qfgYhn5f4%s*e)Gyi;P?)>wGwe!zc_Rc?F=`(}vcwr1F zA6^MV%Ljc(8hm4nR6cOFK*|SgX!)RxT0VfvF_7C}`50dQ?uLfXe%_ytcKiN(yx;dH zXfN0zP#A6I{rPY^FSrawE+1lk;wc{v`~G}<-1p}sP&l!>g6m6AIRY*pR`dRRxSkhY zeuCo&R6Z=`g_IA=d4E1y?ECZaa^Ig#Ap2+Y{(Lx}_vaI1=bta6{eQkthU91PoC9d@ z>11fSo6h_5!DQc`52yS7e6$;~PPVi7|MZt2eV~2T;;ug#Dl>mPP-p(xAx~r;>4xT! ze%_ytx_y5>?)Uu}3vyF4@6U(rygxx}ufgsD%-c|;m5k5oh5TF?9QLACGChxNWc zo%S>YIkPnc#TA3jBys-vO4|A7OL^y?FVqov!>cm;2Y4>2nD^)Za^9aWi=laNz3>k~R+HCs}I*0Jz zoA>8`f8L*uy?uW^@%Q}++IPSQDjz{*1awZ}zccU8|L&l03;g-QnfE8C?a#prT7$#; z^P#iv&qwaQKa+p{pDw`5AOdzfR3FR^7Cwe4oM>_{?z{ZtaCE4A@!O;lrtTLn!<7F# z*v=Dgs!FHT0#T*X81yu?D#yf0`x5ENev8798c4g~Gz2lsJd z<&>B_!;}a5ygwfr^Zo?iC#UYU^CfIdo|*Y4$3e!z1E6xz-1ldPFvFG?pg3iA{`p^; z_ve3k-k&d}d4Ik%_x%Z)4}U4o`;%eoVOxfs&9)EBeSbd5{y+V}f2N-Y1R1ux`0oT> zm-6B_(@zdd=)T9_PT)IiL2YhM(Asbi-gH4$$}vhbm}Zj|o&ie0&AkQveOe z7vG&gViPq~8NhRkuy8yCK7Ubu)%FXZeMDa1JOpa%JyiDn`AFUO=k6bn_MC<)xbN~2 zq@S4a7VvsTV*Snx^*cN7&qvI@KOeLE{^S7p{Ws6ghyQs<^ZREke*cW>cjUDWApck3 z@OurJeg}>JJW}`C`H&e>UN8Ohf4Vp*&4beDeV3o0wMZ|&^ZbOT*Y`|_^!nWgkzU_B z{rvx!=jZ?DJU?GP=K1;ZyALG2KIi$#F!Qi2!`x=u2j6{uT7c5)YiN3X4Nb4lk<#mP zwDbz%Bd1poAC_LlG@p+%0F(AJm=K1;XIEjA0kHzoz z@%#PEd9=I=_4@_T-gZ!#Nn&1wr`PvR;PK0!AOBC!=4KE9jWL1eq(S|f`!0}vO=Ghy z=sfC|yLo(8gi zb>nWIpO3fu{Cu(5=O+uV!_Nob{!h2(W`N9*gT_-7R3>t;L*~d&l`~EOmy4h^L86dx zn5UqzV9;9P^Gx8f@WpW^$e7n@#5pbCwxlo9#258EkbXil&(BBoK0hBf`}}-(9x^WU z;=I$(2jx6JA6D}~)(%}}f{zV>$40I*{d{qo>F3MqPCsAVcKZ2ZKhw{bhnar9oa_Vc z*K6@X!;9VZXYaTF(;w}3f{fF4`}}-3-3Ky0{ZMJ*|9GCC|C4!s{!i!m>H7Kqba36O zt_;2p?-jelM6aiE6CFODw^4{~wgufE0B%d1cKZ3^xD$9@9A4J5HU!z8hm_|axhJQc zz~de;`A6A4KOg7&{9Jh+G^WY(^ID*6+m^X&^JUJJU;CN?(4$b1X|a2<=p@26QFHL zPT>F3MsPCsAlcKZ2Z zG1JeN%Td$ai^ZUI-_SK&;Bg|SpD$KJ`~q`}2WTH2Xe>@18a~QAKOf2a{CuqJ^HTv7 zKH@w-A4>Cp)9j!-ajAR_WsEVO1H~Fafg)dpz#Vyci^;!=CG(obU7#wC)wO z2659_9Od_J?w=3$bN^&uJ#5Rs*=+mpu=meL$Gv~1zlZE42Gt{=_BbOWLkOs@0p)=g z^PPS&GCKTZ;%f+s{qTP}Xl?p4q;eiE&+72=@p|EC|}g!FYlar6ST zW(rzAf!5f*nal*Kr~WoU#@{w`L(2GWXuj!3F3MM-r(}Oi3911q8mrPSL&~=4+&>>q z_Wt>3y7$i-E`}*D+d=L`N+VD|fYvjE(+C##9b#_?+I{x_^df9&0g2I#86`l{^b$m7V&xiHgKN+4LvSoPLWc#q$`{$!}@1OVH;YlO)h%|EL zJ(e^AlLw`de(#?zKQH+|VK>6D5EOG98Q4MbIPkfQi1er5BAOV?Qy3Vo_Hiy_%$~fgg zzV}bfjQ`UgUU%6EUb~nNQ!h4=Ljcl#Y5;{-z7u4Q$(P|Hc#bI_)J}Am$Z$XmJ||gF z$~XnIhVtcdiHRD2?Jb|@JNd0E`Z0ngPDH5yvzj|?+ypGkGOt5 zyzKS!(RDBIm^btFh9DLW#F+OocF35wtSjRb@O&A_KcM+4B>MwO8K=AqcKZ1u-0A24 z(_BCQpXd7dO4|G9t7xX5PvyOTzC6tJ^TlzlpAQau{d{=b>!;Fn$QT>Q&7k#W&3T|Z znw@?!usZyFlKy}CgLo#$dd_5~pZ_;={rtb3>*xR7T##^ZWcUaw%fMp_@lHP#K*u5O5dSM*ZwNZVhVXwI z8^r&2T^Of;?0h)gWhX=9AzOytCR=cLBnZRfL8O#%3P}FNX)nmUp+7WE69nOL$_r~)pgm;5V83DbNge7ZZLXgW)xCZ`(uVlS z`FcZ;3p2t`usB`e0*%uIVaOaLlKr zcKZ3s-3h$U?}a(2?G4%6;3dcq^1>XgoW_!;JV5K9!R;F^NI9*{_4ARu*U!hwUO!)) z`9J-EIM>gI(p*1Znmhe`W$*M8oUb??e!|+GpnZklH6)3`;5m>N(o8>J)_eVY$<73x z2LYD@pz&yVrk^kPxgc{P%1l3B2y^{>!0+|*p|ICaryC7HptIjV>oP#;@L?{fodc>1 zoPL7(SsaX<-7mzUamc_w@c}mzXbrU%?A)$L{7gTmmoQFw$nEs=5x*07jSfTOAsdB; zCL3_tSin2+fiTn0juOTx4}_h5z7U7BH~+8a{P}+~=g$}GIe)%Lht@5dIe$J}@A>o5 zW>4^Z%Hw#JosT&frhv+#C*_dx2vqjL+8W@ot4OAaFP3wH=eS<1=KT3+x#!Qvt37|t zI0HJT&FSY$d8eN*l%0M)n9uq1;bP98uj{>jzE)@Y=?XdzbUNqH7qdBkKA7(L^WkjI zpO0=p&e#O4y#$5DJWyDuL&D+#yX()#@h;%;DbSc5C|v&cbN>84ne*q1e$JmSvY~#M z%=z?`#m)9A8ayB|zzP!x5le5*)^5u2rot&MHmM?EJ@8s-tw0wD=c_-&YN6VLwnRjwd zb+ml>oOvhbOh?O?ubFpp&ULhW`JQVowm%kZ*a#%Y2d;vNS6Vxwm-~!hJusVPf zlqRk_{(QdOdFQj;&O4v(ci#Eru=CEx$DMaRI_i^UgQVop-)|?Y#5Vd*_`me>?ts@!#?1KW3+&|AIMx{t4&&`8%5P=dXCqpFfj1 zfBs14{P{hb^XIpG&Yxe4Ie&gB=luEQIQPWK|LiS4pXQ#J4x-ORm$@gVg6Qkq z6H`F+ZSIN5Ao@P{#3T^?n0sR4KYPmu^_)LHv-3H3qC7qSepbe&3kF|@u(=K$9?FVZ={;q;=K8M00V zWIw3h2bm4k69h85+8MG=1vJJFTBoAQ3|Xggw9yt^J~whro2xD{(QL^bhfPXPA^`D!k3d7f4-Q``12slO}q>rpY%iB)Q!bW z?PzYg4t3LQj-L;%d;ENO+v8`_J&2p!L2hby{Q08W@#o8aG&e!*eL30j=L^t2d#D>< zEO-3*a<${nm*tEd|B=I^A+eW!F0!;ud_k-q%r<{5zP4WRX8Ni;UWS9>(|IR& z-B4vCWLz}F2Sg#)atfXB;ZXgE&i`1xqE$Ir*pJ$}vsg=06z&xiex zcmb7T;IUwK*Pme@q3Z&$nE7b2$Ir*hJ%09p!U#0ZciHhLC=Nhn@q=cLpAXv+VF_+; zs4`7_QOyAvf2rsA`Ka3C=i_>hpEV%+i#dKiEa!mdX%1F~!iR#8@Ov8W`4iqA(+7n; zG~A3Cf4<1)`1v5)?X>f8 zzSB-ne7p+w{0X{e7G&OafUF||g%4NWsjc^)jfVLdejhfn5`j5H2eSbx517- z-^e@u1f9$CTHEpGt76BWFVsQx3yyU}(i}hk%X9pEDa`>HQ<3NR`B2*9=OcL!aJyHH zjbRGtEDlgS{}<=@35sKQ+F@t>`GOzn9&W~;FN8UMKH&HG`B2#7r_$qwphwcsv?I^7 z^IaCGd~p2vg4^-uBWb6dkL8iljxZzG+?VVeKVNWj{CvRf@$(_K$Ipi#J)p1=cKpdv znfU{BmoR93)eC9Hpa1`}|NPI)0jWoI89qJ)trrHJ8w8q1|IZFdBkT;2Gy*yof}H_9 zjcfq-zrV9X(#UW2pAWyg|9te@9h^p#AETy`XDpC@r@bTN6i{A%@!$RD3vrI055zqn zX@Z&Y=PogVY2pG0C{4U)hop(m>^~p9cmMhLv-{8flmDkbc+URw;cIsAT{EEY2Jesk z58A7aR^R@HoDT&qgFt<%`|QyAmi_00`|dvDIJ3)=VX z`155kB0XeR=KSDbc&xfbkf4=f|{Q1J) z@#o86_&MwoUxDfdXuVMN@4q;xKEc*z1FbhZed7Q07x@r>!TUDQdRPwMdb9oPKmQ+Q zhpabiyxwfO z^G?t?%AhrmZ(ck6d>!oxS&zyHtye&I#emlQJ_hy4k>(k&hZ*ENiq+6CThIRU(Q5af zkJr2ZWCMlSV)ma8m$Ux_g*|e;a^O9ldS$cw&&S){e||dw%7c(P8dPS1%B}~q*?&Hq z&knDn!EpwvS0=MV>Xqs2KOaqY|M_^j`_E@5Kd53 z@U++rO^fa9KOZ!^|9sf){Ll84_L(tpI|I=TB^nvc~0+q3#^=9`Oe!dYUGT&4~ z^G!Yb&qvknKOfh-|2znCQ!)F`hvn>$^=2URL1iiEP94x5b>w#HWwd;g4Rvci`_Bj2 z?mr*qyZ?OjtRbkGts&@8=KtxhUpxGKbs5wLb@=(>zQa#YzZ;Ye;p@$k*?;~|XaD&! znH^GgrnCQinC$-ZQ92}#TxTI6k3>V`JD&aLqiFY^kK^5cc7gmB%>MIXIQ!2RuN{7Z z&bfLCO_SjDW}tKjn&TE^umtsEpnVm{dan7-h_zw!8NvN0@Y=BXjNowt0tS?opC4US_jLQ-HbaqH#%6p>}TA`xz)k)@Fb)dI#T4^}(;e7xS_=cCOIKOb&)`1x_S!_N=( zjyvBsJMMhf?zr=9x8u$?{f;|dPj=k-YP#djm$Myrg4R+!wr2nN$e#V@LudA%58T;* ze)MMl`61cL@_o9M<-2Sv%eVPfmT!u!EMJ#fS-z^avV2)@WeF<(@SQo}0XozCqRqq? z#?X9W&i?a}vHQ=*=I%cgK=Gu_{_~+eJ5l{!Q2hb&?^6MWDGKZiW}tE&G~Nx$kKlMj zJ0}=!w=&djb@rc+l-++mR(Jo&2(nw6{pUk@_Mft#y`k3bKVK|o`1#b{9n{8y>@gOG zrgL%jpAUrHe?Am<|GDTTq+R@kS$-9J=Ktw0mP67vXbuLH#zEl$TA%lyoBij1es=Ks zoR{3}KVR^(|9r^p{__#P`%ifmhAG6Xe|iDxi)sh{eC6!^6TD9IH`~wu|Ji=N{LS|B zrMo+19nXKZpA1V6*fOkauzkVq{`19R2GCtwmpBz3fY-q-U||S(vDo3~OVHXls2Bri zALC+&pPHck{!p<5s8}a>Z$Cuu0Z^ZDvBS@kV0AB0%*$kJxWuUd5n}+&X)Sj6nF-bl z5d)uhy4d08N+dDRJ|ocGsxO$`L1!*lg3clXol^|qH-P!zds-p#l^}UtP~3p|4PZXF zj|=8I>;%b!*2+TlgZW72{{+c{;})VG%m?kK2F)LW%j<(o6JLC0`*{L%7TtHYpASB} z{e1Y{?dPM%W)tD%@_jaF8-eX7$D4+r7pHk4_XC{g-3c~BmU-ff*KFYZx-Z_d{S-+C z-2v6%RKSrdA6ULj156AFSCK$Sx=MxPbWJ4?`DJ4 zN&DG;KHBZ}^YMPSpN_}>Pk*qP?dQYoY(IlRVVquN`GT3j>H%RgY2K}0G_)dn3rcm{W72J=cCzfKOfI``^g9L%Vf5n52v&JRDhcG z(%Sv!%gGFoF_?ZdzjQO_;yZn5RYz&_-+?5BKpKyiGXTsLQ9(ehGx)Kv~ ze3%(&jyj9;6*{u92Y#!;}}z4nLo?gU)Yq1&?by@Min@(4P&p z&Ev{E@r5(gPItDSkDT3pK6ZEex$@Zm>7aZDo4b9%%(&_y=v+T*wx2KT*}!x51uyHrRsJn7!b4 z`^m`b@Uu~f0X$Fk7`lcC=8ylsS%3cj&-(M_Z`PkLx!s^;FzZhS)dRK+nhmxOncaRq zVt4!b@9qETtFhUm2({sEAK>K7saSDoy)2u&V zoM-*{;dvl@Z)x7|p&4|=r0o|_)x?hYPu`e2&Urp^MzE}*6 ztL3aeA1!wM`FOeO&s#_TPk%6*_2QTV^VM-z`26Aj$*e#BPiOu4 zVlwN`7l&OT?dj>PKOatZ{rPCR>rWOYhAA(?A^PBbJg6Vw>pQTx4>W(}eDweHU!XJ2 zLFL(FZFqUsmdiK=lm|g!2o5)Y$Q>e2f)U{c_TNE=i_YGpDCbt zjc5J&Fc~dg?HzuC&k1Zt#Oupu*PooVoU=i7Jb0cmob~7bXx5)E!dZX5sE5XLH0#fY z;jTX)MZ5m&Vq};CI$I884k#?a^OR6Oo&Nt{928$qu(%i8&H;@z_(RM|z2yIY@dQxW1lzjfG8QgmWe5S?LGxJN;pZcBhn*n5KQMOq`_SCs??YyWzn%;YL5#d7 zXFX(R_<8Cf_}rzRpgR&zFfy1wV0QS+p^zY#4ch+$N`uh*W02buNvsV)i$QUz&G7S~ zKEqFtJs|r)c0FWw_z5y&%ftWEL1zL!k%yc$iL76Vw;^aUNWU_}&xfG%|3USsyu;6j zApdha{9Jw;bS@y`uKB;!2=;$x&^ed41XV~GyHw5&F~lG zo=52nJ0FAY9Zz@I`9Ry@??ZKmzmJq1{yvs>`1?4U;qRk-hQAMs8U8*fM+)C`r0@l? zVc`p6!@?KDzR6ga$j1=!K-%HwW6(Vd=?*(VW#EHyhrbWA9sWM#X88Ls-{J2=evlmw ze?f8F2@7v=hM#$$@CM~yRtHOPcyl9#w>jjjQc#_M9A2RCb_a!5GQ&^MT~Ek%KLp)5 z$L;Vp;^F`4PmuJ3?wSCZ@fhi@2~fD39{E2VbXWHS=-H3(c;`oT$79f${h+h`r4i>} zg504Baz`-3&xhd*KQY|F@9@_QoALNEd=?*)=;UMhrR}7TyKzETNxdCQ>5^qD$*Tes(KLFj4VbAcB z6O``E9ezFpr4wm~pPb-y7qIeAzW>Vq&XBWA|5l^&;dc};b6tF(&w#k+qMTtT=w5oz z*{9&U!VYsz1kFvouxI@F!rJktCg_d@&^?Ftjz3>&L+@bGhTg#fs=xFh`2^-xaQO|| zlV;2a8M8NM{Q1b(@#kZ6$Dg3FlZ7CEK<`BO&&-8#Chd!Ihn+9=9ezHTf529uvDtpmQzd8GdqbFl>1My30-8;pczQ+=)En&zFbUCxYs< z|Gyc2o@8RU06xd^KLg|(OJ+upyMkV_GeXX>1l{Gp&j>lkQkd~4=)Q&*zZri1|IG07 z|91w^8mv`3X`r>F4nH4*+zUF#QXF)SJ!Jg+;b(`RkG?znoSFo>gP8&249k~~IUr|P zg7PEiTy|;3pD#djHo^=)HJBK-ybyK(hr{D?hn)}f9ezHvcKrFs9&{Ik{j~+4vn%Z# zem;cCRo(hO9X%{S;f#DHqJ(7?m8-W0G}!2$iWcu z6yzspx&YP1p!G0M_z`WmNB13mK7Q=*Q|>Tme$)YUe%Q~){17)kxX$qN;cbLkCf0_a z`G*kdK=-kM%zt#c5k3YB+dl#-GfrYN6MB~cERBNB4eC1de>y0ygVG!5Oj@|P=Mm;^ z!)DfThMx~lBiyIN+7MKJ2r~>pY4|~WgYAR;4nO(L7^gg72Hk(b@RLJ?;o|}|(B4jm zpB%CbA00xV?7NH~4_HFk4;eo$uz|9lGJb5Zhp;mlKx1!^F**k)h#2ztUV=MB40(KS zfhR%nhu});MXo%QJBr%6Lh#03J!aRmVh?pmmm_iCftP@GBAsr%?$=h&=GXdfc2U&<% zCz99$sMty*u?9Jax|2v^4Dt}Mmq=m@pkkbSNOmYd)M+A#9e|2?B8w?P)MX-xEl`4p zb%MkiAZ|`jhKQ|15@S$>h@C_dgQX=+P}(>E(F;p2n#>KCI3Ga74)8$qz68ZDR4f5> zjvuqbPfn2EpkfSs5OtbJVhf;Ro=9R2;Qh%CKRZG8LdSy_m_zg;j~gc#Ld1~AjTab0 z#XxR>>P^ssh#`*~FVKOAWrEWhWPI5HnlDx&i8a_k)V)L!JKz8j(*&n0h~5X#G@gkh z#^44~w-QP00O-71P#XeCOu-wXP7|EgAm%yvLBukV#1f$S<0Us}PdY?h0%%`1v%^nM zkoyim#6V%Nh>1Z2RQ^ALmc=i2gZf8^^IaGj8HCDi{+~XN2z5C(|4*NSU0o$?od?Lg zq?`YzcVSnz6Iorv&HvLIu&V>F!2+G71v1a?=KtwsObjBRdKXsTfcya(UwIJSVEb^h z!_Ph>}m zP?7_k6$nyy_}>5Nf!Njk<=|)t0;$<`@BefU>}pW#+;H#zbUWhlZeK9V3v>|tRf$r{m5bW^xVYtKJN6`*{AIF3GACNSi{^$Sn$)Is^(0##3 zWeOu>gC%IM3KJuP5a{mF$IKjB=C}V(@4%v#gVDhf6tqKEu%faZd6UA(( z`oFjSPxr&39<+ZDZZ=0l5GYJO-TFV>8HZYUctF)Yzx98*1rD|7=H9vWf4VLXwdm$v zy!C&&5|L_;-TFUW95jz&55CI*+}4Mez3L6Npu7DZ`8)g+dH8=iFP3x#3WFaH|4(Ow zngMPL?}ps{gWh*q&C4+50kr=L8XE?+!JnX}F^qID@7Dk6??LB>qoqe&>0r{W|I;61 zQI9PhwBPza{RS4bxY9xOt^d={U{MbW1N8VRxb=VfK^$t)<16*n|LNPXs0H~ERHk#* z3IxAk=G0=eb(jpd2b%7~ZvCIWoH)Ipd*igg`4Otu{nr2KGqCI3$;o*j3T$UBlAX}} zV0r8R^e!CwK<>qshjecJpI(by&ri@DaBzP?^9JaCn?gM5(Zf*W*8l0LptBn69ezGV zN>iZnl~HDa9|Ma-oFYToJSK*;c_6!(LFJeL<^?$lM znf8Lxwgr)T(e3TO^?y2OJp;O%85s}QD#$GKQ)H2d(_l!O2MSvbkiU5k+(P$v-L3!A zC9v3!&kS^TgR*T3eG&k?9={l28{!Au6)4Hu=61|!_P(HM+Xu!DpfOhPo${c&<)2tP`~;OhLZ?9E zt)46YH#33n@1d6arW0@<50UN*z;GY*-gI_`pBUjM?(p-8umgA;1T-G;5;P|Onom(@ z`1x3x;pY>12GBX(6BwpC?0l%~@bi&6o1Y^~uVZHAwmX^d0AcSnmm`~>A?(EU)4qaA*>IWSIn0Gbm4-zf+2 z%OhuopWjm%r#$p`*a^Bj{f)cB&)41#KVQvv*!dDP7Z>jE^KHJv&$SO3C%(02`1zLE z@#kB8hM#ZQ9e=(x2JzV@zBOm~`Q|Xg&)3Hpex7D)2zou4ap$Y)p!-r8e!jTO@biH) z>%<543_l;IGEM=Hc^ZS~kbb@Zm2J@uKNCRivIgG;4K7D6r!r1?TkY@@n_HelJN$f? z@9^^+Bjdz(@eDuLu`+yIaCH8xhs=&YAF(_Be7u-t;+yFVKVQ#g`1u;-7Hh_xuk0Cj zzFf=zUQ77GnPuYtZib)#`x$=zpUm(x!+~+i>wJfw;QJes9ezG=KVX|6*kB8~yD#e@ zgC+RBXV5wa(EXC2yCJi|=cP>q-;rP!v=;2BA_*&s~$0POqBiqfBMUO zho3Lv9e#qwELi}PT&BgiDqbeXlMBOpxNQ)!*++C zNt_Kq%uEeIm*W0Ue*h|TKzG{lJN#6r)c66qWBktl|Kk4-gYJX^-2rt7dx`PJGDBH1Uly!_U|53_rEGKxu?w=d0-qJ3;qHg3`B&1LKsJ zpmBX^(3%&tJZSC!8s^NPJKR9yFr2TwKSFIWvBSpP$h0=5q$w#{!D>`1#bB;pa2Z zd@86sGI#h1iu+ffJH+k`<HZe%`T%xQ8>50X*jfT37r+n&BsC{`0lC!%rSo zhKZSf<4@Q#a=cDtU}DW8af0qgWoG!vA?g6W z!|??u4>1#A20Oz~kQtB69e#q$0mUz<4GQWX_~|iDd1&qcy7%j+f*#`()HDhz8@N}# zP-po00M@?KcKG>F-vJWd@(e#^LE#NrQv<5Yl)-bUKTmKlY;)mIa4F;mo%ZTtBNb`~=m>pmOQ~ zGbHVDK-&?LAUo9^euB~}L&HIv2g(h$pgnn@d+b2!LG?B`ABZ#j+^)+w<)OO6&&Qzh zOxfWl!$Zc2k8qS<9g+<}FVM>`SJsIykjgJDP&!t2_{n*YVIn9^a!7*G5(79ry_O~- zKICEX;qVijj=7=f7_{bxA5s_aurlCJ7yL+OfYJphF9>4f1^i|}^8zTm9*8^qOa{k= z-^%}oVQ~TK7jc2t$2*53Gx`ju<3_l+n=9u`v9Xt=M1sV$m-wOgV+uh;kqGZM?2N)Pk9x%(V`rnK? zKM&TY&G1u^p&@8?GUF7`x-t$1hC)!8^Iw?p=YMg=pAUr{e?Ag-{Q3AX`$SDO3_D-)GwlScPi313TEq7eG>6X6 z5cJZX;pa>w&klqLU3_s1$!+kfy&;R=wem>mo@bl4rho6s?SrOq5x{Gx=!%t37 zxP$84)eJv7xf_CBMl(Xf-JD_P%XmgaxXUyA1m9H;3U^SuXgefKPK5oR4yyYeGP6$n zznI~ta5CeRx55rT--tW>d~NQq^A%{lm9oQ6l(3)8@bmwChMx~-JN$e!ALK5UiErB( ze!l5u`1yvrA?S@XDF-EpTXD2%)rc0Oo#+$o>TIOPTCj$Bax zgOOnihz&X``2c7QnZLtN4o-%Tp!H-N3=ATmv5Xhq4m&wm83bQAL-ugJ@ORh=VuQmE z)Nf^Go%ksUE$!Ab{QTbx>7PAncKG?&nHdp=+0gLIX8_HU2EBaD013P242WKOJPWPU}j!*h>2l>Q-H+8t4WMg7}yw0UVzrHay$Iw zDg~Xp;qX(Nnc+irBkRQ1;S4{y*&BjhM>G8F=4}Xiy_;cYHbX-`Kn!D>?3CcaK) z`1u+n2D+EtoAKvMf5x943=CU^L2EKW`$L&Qcjq!}K z=A8K7p7G~@XU3oZ-5J68`6;vfsz=PMs~$76u6nkZX`%w7{WVaSO-%x=UBF%z^nv7@ z9e$#h6aSkr`~9HyGN+@1r6wbT5vL=AC4(ZvL?azgordT?|957%2&y+hZ4}U%8ytV{ zb8s-q3313W6oKX&L22Z_Gjz-V)_3P;_}P`jI0e+c1dZi3CNWNFU|=vq9)|$Qfy@K9 zg+XRk$_c#?X4uKWC~x#aoMGonafh9+gdKK*`WJ7RxwPIfb82<`jpvYO)XfI9uloLS zb9DdzZ^|vpAoQAJH0_^ z!5o@CTG=MPmS_0M&Daq1TAAVJD^U4s4oMH-^Z~lpm>t3grw?|ApU*+-Z$NDjPQb&RM0I)V1sP6#YuMTRv*@F9H9~D9O5`pTs!weHSpy#$cNo1S? zYPW#mlZk;rgawr5L46ouhM({L{}%_X=|r~UzccH_Kl#Ed|5l5D`%a*7i_;L zUOd9vZO;4`UtDMS`QSFg&xiLJem;84@bmF=hMzB1FZGwy5!)lbJAe!e>G@bkrGho2mOoiD%G&hYcqZje0;;4%ZWR}`kc z5?MXyjGg5SKSBGd!Dk7rXZZPIGsDl9+Z}$sTJG@k^=gNoFV;K!e6!i%CuqD5v@i4Z ze1@N|7K7SjoUfCZ8A4tzb^!0$1g{x*&iM1ib4SSC%#Rs=zI=@4&vwS0ksyCgclZg~ z_xO4-cntHWmm!BTnrOI;~B4)GyHtDn&Ib5sCz(TXrO(eAiF?&zhCSJjafSU ze6`!*=ga*LKVP;p{Cw5T@bgta19KT5%Y-ae`!Ng(q613N<9BfzRi+uLV7y0g$nv4#WFSFSzUuL^kawtOTHJDwX zc_+9YPKJq^oD36R)-(JB?I{Gs;mdl5pRbx7e!c?lmty$o!N_0+-ZzyGw!>1B5wyk$ z)l6mv1`${szi4;d`C>lf&KL6?LG^4AsDI(1!(ay9zXRIClAAAWqUn(6Ems+6v zDv}+3J_U`Rg3g|bXZXnh+LLq8U?S*zDe%~LJLAs>&5l1Gwmbf8a%c#8%+wGxCG!9D zm(YDsp#3(W^$#444226p?aO3v9W)U%4*D2$=3lbI&u7yee?9|^)5FZJW`vBZ*E9Zn zQ0@5hVZGzeM-B}^%!~~|Pnp?P`A7Yq{t9G%G${N*X^X3ygOTg?%VNf#FUlEzKG+S( ztDv*8KAa5WA6~@P+z(DbQMfP#r4>%6HQpcD~?m2m-ZpUbN4b(yV1FeAzxj0zu7bVd^+6`5s%4?kg!f?{P`f+@#n*I$DfCsAz`fq^PfG!e;~gtWMT+;;tbl? z>-ZBiHi2SZG}OF!#-9(O9e+NIhnNRS7knV|K>Dna%IO%J>tsCjWu8Q$;kcsl`-Sbm!SD2&^*%V23zo6H&7c7)Yk*$AJF(4Bj;-^Hii(; zo|mV}(6Ew5%0Jprzvwgme4y?4^P#@u&qXef{BtDY|8&r}H)w1Uo_{(S3KxL#BWN5K z6pzAa;iC*SPo44S17*jb57ixi9&%|2Qf6!j+5j?77&J}<8l&gv29*_>g^Y!uc>wTQ ze|c!0gtjTcX~>-6CwQ+Es2>VSFN~b8L1`%zlm_J;KzqR_KH)}l12e%qTSJgDQ$vs=C=Gzd`9X7=pnYDT`jngT=M#R$pAXs(*goio#t%Q} z{2S0&RE$3#FgyNy$nN-4$qf-dexSGpjq`x^s7*#H1Aa67d;ywgtA~^U4`w_5d^q3n z=c8c9pO3>Ge=__2pPsJO1=y1=mdaK0mh z<$q^>l>HfR{{9z77yA#JBY@6HfaexgI#@D*?yi?-*x3QP-%A)2XP|Zd3_n5Qp#J*< zd4`>!y!jLqE+Bc(nmu-;G$#$6uat-E*Lf)K@KY(MAt;#>wC+QGm0ASo%u2|72B?1( z%EB-OWaa~Thn;_`k>>|Ma~P~R=d5Alr#uV{Q$YK&K=T|gLHlqXJ6OI1%~dRBumtrN zK=UT3bM5RG|K!W8{97%%6130xVKoDIPvQ$uJy;E@XB~dR#)DqmcKG@7K4{(-x__qF z;im>8!`AZ?z<#~pmoDB>UHEkV!YH>1re3cH`8`KcwCCTvd<#mRgFY+0F zW<)TAfa>G7=?*{7FfmN%5j2~~#n2GM!N4HUUAcA#=q#&O*BN%c%mUqn4uBteWJ1T^P}yzjt493qCi?;rsxhO+NK5~2=e-+>5340+#y0#t7& zXuUM_oDv2Js5&Gu1*jPEz5@rS81lY@1kfF*@eV(c_Z={R*8j&l{6yJz02M>tcklpo z9(26JPvm_E4@4nuLEd-Z0J8&WJ-h>G%{|Btq;pgpI3aqG*TW~k#E{m*H-PpX$D^L3 zvH&WEydFM52x1<}dU&W9@_P6MP%-57@CTsbjJzH`0UCbD>){_j#a<$){`WGlU!mmBZlne}knaXq;?4!%ol~@KJ<#C9*iEetiK^zY|$}CtSV5 zPh|1UP;tf!BCsYo7Z6t@S!zARm0pF(uj(-R68h2zl(3(4#y`c5%$a3H_gibsB1li5N zA`u5l1L$fraJykLvRQHnb@26+9JLN8YD5ugexlpM2bII;7H}JxS$-904*exGPrO|3 zuoHBS1g!iHW@Hfgf0*GXxGWB4_=&u)X?U^&SB z37nw&6Al_o1ob~xvNZ&~M4B@IjjKK`Z3tpvYzTVB4LY~+#ixrpj8k4TH$vhZT9+7r z`X-?Iq0zze#eP;xkeiVARJ{Q0igc!G@~RI%xXc5cqXo4Wyk7{HI?%W>R2^vU>mx38 zDB%iq^UHFFouGL)Sh!9CxeXMq<_tfP_rrnC8UxMKf%?m*`5G>9H$3?^%7c$3`1KpbnZd+Po%7Meh9w}U)=7Hu- zKyxcFw}8%=0+|6C>jQ_2JLFuZ2cW$>-ALiX&ae|Sb`N(?Kc*bqJ(Drz!0rL<1A>Js z)I87}3~25M=AM`8(6z|WaD8#zVJB$K9BAC@g))mJYz^GsYSec3f7m)&euke9g&BT6 z0`)aPXN&NI_JcG01g%vDt!DtO!+gMh!1jS~gDq%%7-;?id5>-asQt%{b_O44&m}kN z8GH;-G30i!0yjelXdN(e8~6ceA11fMPn5m4P%-2-FiahC8~6aIZN`n-28M|tw}Ihe zNNv^!p!O-Z!%yTkD_jgzra|{tCa^=?jJ$^vCWhQ*Z2+AG!|m`BrOgTzLvFLe)FHQ7 zVPT5WX60cBc?s%AGRv=8CD3q*OX0;QO-8QQpfsky!w`}JI?D)j-h{HlPuB?0nQRO{ z-!@Ap92;b#(54AjPfiDg5@ypi;lLd8J&5~i*mD&~l!t^+D& zgCsT)DrSx(HXABtge0~EDh4XwVRo#Aih;^InAmox7^r-Qi5-B7f$B||*h#1usCf{KCe+k}aIhl+v9cbFJsBqZ!X>r7Gl(y+N)(EL1T4I?{z zu22hkE)_h##_sU*)sO$vL2F|`XNz%w=HECOJ~o2JFhT2AnH_#=IyzLov}dRU*XOJZ zA3@{Cpf(P&Sr3@yQOy2Nq8m>B_&=S)$KfXjFT{LMJBE{ylj~(YgC)9Mq?)}6X0|Hz z&7KW2TbBA}x4_KSrM}s@FtbC6F&i}I!-g{E1KXzpTE_w^SHb%$Kx4D|3_m@5|4)Am zIx_>bmK}5!2WX9vzQa%Om=N@=pO>I?7`uT+0VPZ>yz(mhYp!>%Ke?DXu`uT!6W#^0cJUd@7F_^q~@3ZqIf6&jD z-vxiZ_^iD1#rMFUFY?)bzW5#Z^F=Y+&lmk};JLb&{cb;B@dy3XU<8eOb9HMlg7z`E z{d|z`205$uumH-K;0ykspD*4E{`~(~dFPAwfj?iQv;BPWIq>HT&>5Ea%*=NC`5+yK zncZ%X`wrsSAZG=F@^CWSPmWB6j~*>dA+M9&Abkr)bBw;l!+1B)y3~mb3ViVO0yiQV zryz&pqvL@;AD<3{huNQv|EE9LFZlD}VZom-nv-|F*bWV|?a(mWF8K3BvGUFr+XH{T z2xj~FVt3%r7vTiLEZptqgJA6b`zXvH0*Z4^M~BK+i+Lw{{P*dp)$7_+qsnB%Q1m{P}2g;LpeF5q{ne^7CTB zpAVM{{(Rw`yz|9$sGp}p{XARn=L>7)oiAnw{sf)#`C@+H&lm0l{Os=b^MNyVKmP;m z2SiQF7dSrJOnfm}@Mi~T4tcuZ&qtF3e?Fd$aN{(P8@mO6KI|9#`9eB*=Zku%8|$HN zY!>|af?Ij#i{`+eFU&z_vIhQq0Xk486AC=+m>vfIxG^4Q%6 zN{8UI4K6<#f|zPKXT#h9S~CsWXALW>?t#KCTJYz?c)_19b|>w8VGa#DbEw;b1%JL+ zt+ew+aNy4u!fZcZga`h7Ax^+;;-K;pyW3uX!fm0K#;U*I&qv;YKOg%e(!wiH_&N*zeCRIt^F?>k z&KJ^9|42jqV=egeMYYn-7uJD4U$BGD!wvlTf}4PUxZQp}V8`ws&>m7yc*DXM?8dEZ z6JHoZ-DocO^O14j&&TEnHy#AJQCslmLw&)YFQSunzF>#CksazrWl(vbwDW~>;LjJo zS%1Dz5B&M!KP&$F;lJz82ftmh)(_i+7(|fW$N{<+TGe*q3vp<^mlpi_NIdZ8V`+pN zXMo(uFZlDJu;9-Z%1Jw4yyu42Vcw8Bj9u{O3t^?5FW3WrzIf02^96U{&ljHwxbd^= z&j;_ZyRlb@K?Ia%URJw->tc>Z2TKh_R!dm89^z>Tg5{w<>;F%GaGe{Hhpt22^IPEO zi{FYnU;GaE`QkC_&lmp#e!h54z&+1he?EAO-94c2A~p~4g7VO3fu9e*3;cZXI&tTV z{m`)54|UsXfuApKEAD*pI^gGv>#RRtybt*K;x+-d-FE%?;5v4ku9 z+#8XHKx|_2&|?8e9(peD^U>pgpO2ph!0Td3P~6`Z`1$a@z|R-E6L-E?4E4`qsDCaC z{Cu%map#N60Y6`W&L6%W@DqFnF}^bYyz9>gr?LA7XC68Yb>n$~pN~!l{Cs>K;l>Z3 zG;mnp=fmRyKVNhw?tIY?bz?u&jk^VYzNl8*`C@m#&lmeyf4sd)<77zQ;UuEmPXNX7bb+4_XAAs% zVVt=0MLg7P@ldz*3;cYcthn<V`=e?FLv-HoK=c>z%PWefa#m=DU^2|HitL*1qibz8E)&ljf^cD_gs z`1zur_2-N90LVGf`0~hP*PjpivAfMxkU<2L?_YMi{nTu9u;gT9ump`ed$2N?f!qx% zC&Bg4LAHr6!lCIhTHxoS@PMC>qY>e%2ntt!fu9e91%AF*oUrqSIMnUpP`A4a{CqK4 zVdo3?fS)g#S%1Fp4*2<^oj|y@yZ(I8jNR?%`5RpSwAxO5VK4CW1gPEVEb#M@eZbGh z&ImXDSoeSW19O3&53L1$z9>%E`Qkqpr2hHu1*w1Z1%AFrR@nJMKj0_$oNMENpD(Hj zxUt&x=Yw+WZhR{M=?{SV0Lb$Oj;t8%`U@NjZ704^7J#&w)dhY&QV#g}SRLW^lOVTC z3;cX2FYxn)b;8aU&!KLA4t2Y*z|R-j3Oip22mE}I&HD3&c)-sW`2^ga@A~sWHg>mz z&d&hVov<|Egj81=g4}YR3sP5}huY6A@biVV!p;}m0Y6{Fv;KU+AMo=;gYua3}11u^k#V+o5jz&HwYoZ~2`se*6D?5e%xw{UPUW zh1qldpATR2|9o*d ze&>t%P&dwpy74~$&liW~cfPpq|MP`A>(3XD{eQjyozsoajoz+5AGl+8qaQXm9<`nL z;xa!Ze_ZGP`RKC$&&SshZZrV7@ihO>hv)f!zL*`q^F=$RxrIdz1NpzBnzn^F^}%&llXFI??~<3w{Fb<#+x0 zfE&Ae!Qobo8E*f7{h$6In*Zm+c>bR+cE{~}!4Gu@Khzz;{6Al;mfQIv*#GB?|13XW zg!}(|!A!s%%&tEl{CC0Hzlwu}TfE!Pm-TKxUv;}d?*Dw+47p3j8!a3~?Iymk=7-cD z_WVB|S^NKdY>x;>OHeo(^Z$Hk&j0g8cHGVv-#H<5-*-<)-KWj}^F_4W&KKJLKVN)i z`T0WM|L2SEEcp9}-(7w__>A5CFPyRFij<+Df|C?td4LeKggZZ z{68Pc^Z$Hd9k=tveW*L{L)|IN|MP{m+|C!m{y$$lXZiU;-2dl`*96@8+U4hi=h)r( z2t3E?_LJcWLq5aNW?P1n&9)%7zqro=8LNEE0y-0BB7=iDcrOub-}n9y#wnnC;lT40 zo{;;iLGc64{e1Y?@8_fEe&D^U&SnikOPCshSeY6wu_iqF^bC6UNt_Df6p(qK zvWQ{lVOy~K_Z|lO0jX^Iz;Tg%;)~mSkh1AM-_J+4{eC{a?+34&Hm&(T{lR6vpAWC| z{d}=HcIS)j&@kT)4fE4{KVQt2-TC6Q-_IA9S$@7a@Avb?bpm02-R0+l%h2`T6p+%g-0*U4DYs{2pfk-|x`{nm0V|^7AFL|4+@zj2|x#gTxs=>SDH? zHgJIM=Qzv^WlEJpD(IocfP2H`mY}9zs-CDZzWe!q`h(ScKOe5=`}ra| zcIS(9s5{c3?pVzC^M$wU&KHaQe!f`E^7F-Vzn?GG6L80Rm!A(-V|T}k+@?FJ4eg<) zpD(0kcfRQM`}tx%$c=tKUn~aEc;*`xyZn4GABS7r{eNa~GHd~*Wu&ybfy2{o;)`ZJ zNV(R|_w!M+-_OVG2zN4r+*!@{^I<*T&lkUAcD^u&y3-u$&SJiwFJ8;+d{ON8^TlMA zpD)V&e!iGaz@5`wem3%<7bQ5q#x6985?bzLMjh8_LRNlObhxE@GI1fPYwKtlmklSqQ z04jG1n{C1SW9wOda1e`CI%|IPV+g3p=BX8HLdpXKMvY?q%e@}Xr$I;d>me7y>^hB@5@ zQeQ^<{dA~&VWSY)Y|8<=ll7>I%emK z<52$|hx%6-ls9B{z7Y2N`63!r7y12s5l_Is@h(3fL}T~wlXRD#FM|Dkz6fUd`83=Q zGB3!;KJf)N-_H!ThM*Vxd_Ny>`~7^#@As3*vLUFMsUaxJ=l}GVV0|u-yP?BDb+;dQ zZB{QQYCrRlw%^ak`UwA-fc(eI_wyk;-_IA^F*{$(hx%_m)PKKuf4=xFz4OIy-=8ns zS$@9w@B8zGHv#{7yZn6Mj@^G4c{@>m;)~C`kaGJw@6Sh{eSbdw?hCJ%ctGxZ&HMA= zd)}WfZb$EY(GGQAJJfxTd4Ik*Exq%_W8a@ItXY1(c<%f2g*^fH*}MFFV2#~<;Jh7< zS#CFg)+OBL{rT`d@6Q*zqj$c@hq@yl>W<62KVPht-udFP@6Q+dEI(gd_x<_8n1DNs zU4A~$$L@|7p!m#Z`RNYYTgC2)Ew4h#@6)`HI{iHF&qt?ye?C5s2)n(j{!f2!nD^(y zcK3tQ=A+HNa5sX+50U4z zG(l;xoA>9#e%_xiq@#DfP=~rl9qOKD-k&eHrFXt)_Wk*So8{+=cHf^b_zAd&-{t26 zZrtucss}G{JY<;oq8b`r^}IhHRr~&YT#pDZM^Jbb^ZtBT&inJl>!_VC_@VCOhq^Bt zl!v5tzR33d`QktG&lmZ=KVL8ta38bF&j6Doe~`@k^IadvCopO4Iae?GQGgy-9p z|EE9D=l%K6nD^(4pGZ)M(}kK}!SK2}D!?Ew>W=kLcl_u1`GQ$$=ZpV7KVO_@{`rF0_veet1l)1i`R9Z4*xi8^P8-1a;yVwd z9Q@7m^U-&opO1h0!0V7|P&mEk`T6iO&(9Z+BX_=-4t3vjsQaGt{Csg)a_5WZK0jX^ zX8!r&wa?EN#|gOaxbx2khq1d498UI_;q?C7|LG6z^Zb1HnCIt~{Y7U^{kq_;Ewa<9fHBpz(bLPSBmwO}0pB zYywBE-NYA%c_4QkALse`=&;Yv$Hx(2rvnPR-8?@Z?&taWqB?Tti*%@))1hwO%=7a_ zw&czin|*%1Sk3(N#de>cFV+)q^Lpo>4_0G$GdS!{`@qX!Sedc_6n3k5em-2!^YcY? zJioi7&q{CqK=`R9w}K0jY9Cg6_6&OaZ_$L@~*Tv)8&Zy1AL>=L>Gh zoiCbwe!iH@{PRV-&(9ar3AlN>^Unv9vAY=@cC#_VE)W!U)jU5R*7N*)@jGJY3wfwJ zn=9hO?(l~1L@mE^Za}i?(_3;G$IUpKw;?5^YdXa&(9Z&BX+)Ehq|2|>UMXYpD!j$ z?0n(w^YcYD^UoLFK0ja76L5RI^Unv>*xe2e!+6XvWB`SsJ{a^o2f1u9u z^Px7+&lkZFJ74UFhQWTQJLGwOzHpY<`9j|3=ZkRWpD&bse!hq%;ErhLpAW*ZyF(5+ z9Wltm&)&K1&p72py8^gg=VW9k1n-TJb(r)bm>IlgS3{Q}j)D; zcQBxig-qZ$YB%x4ZEncDcK5k|KDzDw^YMLecpdTz6z-R~e?Gj<{qx1@@SQK_L;XG< z>i5&!KVQri-}&OS_sDC4w)oB$o4tR&&;+&^DLhwpq54h@5Fs5=&O|9s&szVpRm@1HM}L3M)n z&lllPX39JNd?1b8Oi(<- z!WCQ|-UZbu+>rUX>D)gbP4@ozcse2-dVs>aoBQX(e(s+yq{DZ<(1-e2AL{33?w>EX z#dp4F_Wt>TA5^D!|9l}#zjFCPQV@P&OaY8V|NEQ?6bLl{=Y4@^F_Az&lkU$ ze!j@}{`ulR6aId~f2W@hemi09zhH#@PrHdPlDU6^&+1L*{`n}``{(0yMA*Mv2Acoj z{`oMT`{#?@VLM;EXNA@Qu8=w)7*sZh?R*jJ{qx0prk^juy??&=Ou&7goqj%ekKKK^ z!af!h_TJn-ANqsJoUolQu0!2%9qJBeP?;dM^M$kb&liuGe!g(`{`ulL0e3ui`uX57 zc6Wfo-kSU8|7x+FFRZ~&p zkBq&4J~l^$eHSR~wYh&j)CcADu$?c~L;buS>Stw8UKiW>LfQN0i}OrBU#NTkd~un8 z`z|~Ed~hDS`(C(1>K82i#t9sO_7h)7bN>Y0xAa1u`{yHR@1Kw55pInKxmB3^=RuAeV{hwgk)4|Quj)UBVne!h4uy7R?n zub(frGyQz=-RtLz-2~ja+v(?n?Ks@(4{eky_KVR$?-TC6S*UuNLnSQ>w@AdP=dID}; z@AUJ*YV2+WxeqjF&BW>e?~j1$V&pNQB_KCl=KA^YI@iw^t3!9b@Q1p|AL^#lTt8pT z7Tx*cwAarU^O=6WIPdlI#bN?(TI}@m!F=p)0+k7{`hp2`?+zRJOXlDBPvfk*wS32)DR`+|teU^I<>N&ll36 zJ6~Lfy5&05EzMj%UvP`=e9`Rn^F=b#&ll}pKVPI1a7((=&j-nb-2x6P(Aa%7G_2~m zem<)9`uVsX;XYZA`--`KJ}d{7At5_o?1#E+bAbtK$KS6nmsWS5iEWBZTuEtNGdY|j(!+22n60-Bfa;QI+L;Vp9 z%KIWaUj%#oeBlnN_q~3;@Fw67Z>OIR+_C%P1;{;Qk?&`g;S%L-vU;grW6}IM>fd!d^cg zizD2c4{|Fv*UyLipnMgw^F=t+t>I9&GK2D!$j%qcUO!(bGyQzQ?)CG9Isvz;JNqhybj*^!XD~Y zd#GDqbN+mBTX^S-*PcILh%^0s@!s?23uyvwm3I31KpeYULFEylI`KZpO^-Q$K77vk z^Tp}loiEg(Zc>N3={D!j7rTXbzPRoA^947kp7#9tf}en!_?><};KuGIP`-ubS>!sg zV=?FqU}zrUhuVFa^XH4z!aHAF_Wb$cKjY6A*FAr}U?yNUv(wK9{~fXRA&~7xt`jps zc7JDv^Ie$Lf&-wF3b?{E`*`=WUX8WQ3+syg%MYizH7n?nQzPQf# z^Tl@0pD%6`@ZW96pAW8M_a7*1A3b)2x4mHHvFu0C8XC@@57%@4d=VYI^Tl#zNFBT! z>W;;nKVNtY?|iY?^XCiDdAG|w!Drs$U88#5@#lln*xdm-Hx?AWpfxlgH^I^xa(VoA z(f{cW`l0dN4|T_E&Yv%=g?GM~?fLV?e#W0K=6n8pahO1O9CrNqU_W+uM6n{3#|k{~ zaaD0|)bbcSj=;+>@kKo+WIU^x^XH>_&!3N*5pih-ipz4&pAV}!f4=w}wDUzdGz`n3 zZqMiZ`QowA&KLQfKVNKS{Q08T^XH501l+#e@#llh*xe2aw@2-s7;(Ak!~f|I(m8)V z%;x<0;&RZ=7x7Sc#6#T?&-wGkVWFKb;yr)9SkCzKMY8A57of9^@vVto?fCP-a_sH^ zm0z&<1Ba6;=nPY6nvdrE`6%4;=i_KZIK2VIt3T(@hrygbUn~yV`NAFQK6j}5+&O=~ zm@KsOg}dj^7qc0EzVP<^2|A}4Z(5u0_!D#<VER<7R>($4MngtT+-HsEjPYD4|4 z&-wF_w&%~s`Uroo1NmE-^XEf#P+kh!`9d7(Z*i!pm1J>r~UPD;s5Cmo-;wp_vcV|FmwKV z!7a4&1+(YR7uldQLp^`K$S2^Ad`IwkzSzPfjs>Y-K4XAT@h71#5 zyyk$6OT6d!`RKLB&&TgQ;B5sF`1xYD;LaDf zJ$}B3XZ-o%zQ@lO$pqY=?D+FRJoa#W2x_~2_V`)z{{M8)+E)%ng=_}Ung396DJ1a& zEDRx_GlszB#AgqTa$>=I(E3!4pAWBd{Cu%GaOaEdP`7V~y8SfA&lj@=cfL67@$*G6 zsBZQ6`68Tv+ru4yJ_yF{_NNRCA|=p$!Y_V%`~M!kY2ti{&2R^N8`5VfKzcA6Vmd-;4kF!)zxgEzain`EWkR&llE#J745O z-INb?(`1gHFSG@BzL@Os^MyXB-1GSP!k9pq89V-bppV^6;5&;!d*^>6(iZwyjv>fR z-5ft3_H+DvAsx8$ML5(=;ZQdw0rz~p-#X}>W<)Zkg?@& z_W1d@9ube8pm;3i`1!D$|q9S-=qJy!|N%?J;@wDAEtxKlYpHs)S>QC zhq@;kRGtXzd=c&O^948K&lm9?KVR?@a1X!Z&j;Mt-SgtR2gdqfaJVHhOneax4YzQP zpO1n)em)LIgxl{0ptBJ;em?XEl@S3uU+_cS$q#j>GbrB*?0n(u0Y0<&g}cYk7t93Q z$?W*^!G8yweS$~d5#a`Fx8}e5KmCC<$IplMpzft@dyJ$}9b-POhJ z0lu#bZy9#q;pcHWL*4V4{pX9< z{5xNKcK`X}Jj2fy-`&A?+2VE2Wrv@j^PowI%k%R=d&;13IUQ>EYxbWnZu9Sa@!I|8 z3()zZ@7;gCI8GoP9e4Qo;4t>E0Hvcx(ulBtrRUvm|4)DLnEmI&=j=aUoc7=Oq8=Is z^-y=*X8-wOH~-ETx7~k&?)`Xi-~H!{-2~jR+u`Sf?bzKR1xr)N>zQ;BZ6I(u>SUPs z;xs#C@ArB3pN~$v|9pJj9o`1|0Sd3f>^~nKXaD)4+kfYabf}xtp>E#I{_{mO|IQb? z-G9DV&G7TZe)pd*KzDuM%LnTnem+=@-Ob>zyY3E8>#(rP0fpUW_MZ>8v;TaN?Z5Md zKhz!mPpgV~1xnr@z&j<6dy91P-VPye0oVGGd ze6g4v(q>rB{`1jd_n(iKBf@DND4b@q|9m)~{pSm7|D7+)q3$z>x^FW3&llSKJ6}w8 zhulLl-Tmi_=>+0-y2H;0ld-!G98Q-p!$}DgPTlN3ANI5Vd?D?>^MyRr9r93jG_(JF z!Og$(MYH?Q7wrr`U$ndbe9=w79o-H;AGBk4MutVL<4s~-fD8KOSe39(_^9AT^`E>W6;IrlN#VzP; z&uZ*$28UfeX4qYR0~)tx|M@T;ln?!OzIe|7sc+spKZ{Ctp%-F@J2s>TebPEa@*v;TZ( z4$6yu;QOk<=c?_8hLbiZFY@htq3!+?bl=GfefOWB^T+X)<e zi-)@BINQ$`lX-W(IPUfnbm#Jm({4XOXBp!SFKq|#UBlSg5TN)&3a<~~b<_LVAnT?N zv;BOu-|gq)!-(+G1%=mkwx17ov;BNg?7Q=YJJfydQ1`88`}rc7cjt@sZa=|ySZ{Xw z2|70yulwX3euBOp6&J% zbOtb9zi~T&_6cL{6Tr`pbmq7SzMt2d;pZcNhMzCJ9e%!YcL48kdsWTw6LiHB+y;$#STBUDzkq4&t~}fA9N>|GV{d$ zpnF5p8GgRZW`Nugkk9b*Rkp)V(D}%(nHWA~GjdFP9nA3aG+RT^>u`pjubCQxUT=op zL%N+|Cs@s0j)|}18GdGi?wL%6++hZ~bL=JPt})QP>(&fEUxMx$0^Okm8izDy0M9pY zf$m)c-9g#y0N#uCl8NDirXcr3(7DVjLH9#|?n49JAEwRl^JTlk&zJfPKVkR8o?u|u z`q&?GpE&3);783&6NOzEr-07Seqqh<^U44J;-Is`LE*CN|9^4NSm~=`$bBrYZZrIR zd7t4Y_+FK4(3#B)KSAdd7q&B=y*B1LFpBAmMo(p=uT$# ziLkxhPOgkoUc3hBVfc8KgCPWT-wx>fBMn8+T|1CFT|sx?f!g*DPCNX3c;4aXa%Je< z?u-sULF&MJ6{Q(|va&k-1efQI+!Mj+vzg)N3(#IZP#SG#_z63!TIpp&&?9|@ouK=P zKx;fx?EX)G>F@CKEx*IhH=ujY^&NJC?qbqngxLRfJHyX6yBU7Iu4dfX&Cn3^x}Fgd zca8iLUms@p*$s-<;|xDvF*E*r$&Pe~EVCmxErags0-g2ylH1|ubAN}QPozQV*YW3z z#q1ORL+@Aq{~ya8p^I53Lhg`dLEL-I-Vg*DBm3pTI0bb6D(K!|&^hRyjG%a6_&N7K z=zbv%l=DRqd4l`mgM5ac4~rRoK6=lv^Kmu9&nNW^Kc9laiCKOXxLubIx?{)T=c{^$ zpRcPOe!hOp@blGkNSXtm84kL4*_j)~d{EkWoe#-d|8Fz={C^*GFCN=O@ZCJu8GgRL z%<%Kobq4TVKAxbod7t6utJ{$Ke871Clu!0U^T}a`pWK`cL9e?RA@{NNL&KVvbK>jM z(EC_HcSnC_`1$fX2s`|I32LikGyHrBy0ptW_JAfgx&Ec6C;CAQ4YhD2lfyA}FT#S+OJ&^>sL3=APA z3=ATmv%Wz3_rbCL3eg>z1G~=HH%A;VWKOm!%rTfXWhi$lYHLUOW7J_}<~CQh#I6BX@?Kk69phYCTbB_!(gP zfBNfUho7&+9e#rE!IF3Q`N-X2=M!~@pV_PqKVKU&`~=zg5;O*E&j=ph1>Hw?n5`km z(f0rJm!P(VzQfOl#-K2Voc}q$`~P%My#k5{E=G`h8GdpdbgpAW+we=-#| z1~oH7?sQZI`4eF9|&B4eGK6m~VXzbpf5fTp|cY(qSJN|s=?)dXTGULyO>5M-`^%$qTOb6X#+7QH8%Q;)6`~P&% zy`rGD{sT}O9xZSFcV@ZxC!c@i-)e!C4~!XpJ~U_e`N*2#C+MDy*Pu9MXqfarn&IdF zcu+aXH1U5h!_WVq_CYYi&sX6LKVL>O`~;Vipt1;b=ViRZPk1?L4=pF18GdGSgUU(h zz198D_Jkql#Mj=?a?&5v9%1+ix|a+T|Dd!DO4p$D^+F$7PO3xF0Jxk~clh}NRDM=w z{(!e9lA+}!sI8Oi@beYu&ck$vpD#goViz-j??MH)C#)TQK2&!2`2dvGA2Uw;@5nd> z)Gh$o2P!AQZ5U%vzH|5qO26EU3_rCP8GdRXbg%@aWA1|t;Is_7(_B%JVd6t^Xg&np zXU76bw;UV};C3emkHb%J+7@sCw})YE2_t95Deuf3e!gXQ`1yw0;pc09ho7%NX+a#M z&f(`-R)(KCtPDT3IT?Ox@iP3>5M=oIw>n_upM3w7|D9PT9$=2Y2CplbIW9g;XZZOj zo8jlfe1@M7K>hV{hM!NW8Gb&lXZXnoDsNzIB2YaEsxP5+|bX1*)qUIbU}%GlYQr@e*_oDztut)rs)D7ORpD#i8FETJ}1)1|W-Qnj$Z-<``{2hKiVrH9I2TB7Vvy&Nq-Ur<&4yupR zA$LnLvL3K~2)bj%yTKN8o(3cD0b3@)1Gdbf2W%h5H`qRkZm@j_x)Ub2!S(^D4)t!Z zeKg(S=flYkKOZ-f3|m0`7+w!=j(6>P#y9!i_zg{ z4l9J6!^-e8ixFJ6{QS?1+CBoMd2k$cgWAfVJPB&cu}t)IWSIEMp5f<9XHZ&X_~^(5 z4X=EMpD!LWZqg8(_(`MIV>TxvXSc>**U21zJ-c5rbF2c@VH}JNZfh zxtbAbhO@)Z*Y*xSUop$C%7VHrgP|b^bXGi!4`ROq)nV2SKSAX_C=b7W%(zKgaN;NJ zTJPC8jGW!we_bbM|MltaVQ&b^uH~7n&B*;a=WqSwOh%@UFV*Ku^)NDge8ViSrNh`G zrOD6`q^Wp%RyJeRr`OE#t1<;UXZ0{L6lw}~&jO!WQknIGgORiA1p_oZndMi3^t?0% z&5q9b)BsL*Qfg> zGyf{kU6h^d4MA^eIcNJZ^1Rk$ysp?fW>!_Re$d|hW1FU~sm*YWZLWIRssUDbR$W--donYUrw}QR11eh3#&I$IB4SOjVyi z>5osaZRu3cJDlbOfRiHEtic9n~4$c$MatL&X_nUTypD(&WWf7tb0_g+k z2kAvGkKlDsGy6qQd-h3zyabi8pgXAh z9d^Ec?(p-qJi||IMu(r73=Kg#jNGp^4|dPeX5@OUd9Z61s7>=y9o+9T2lc5zcQS*@ z2XNm8bRV_6!_SxMpf)|j&kRkg3dtJ{#a$_r*T$QT3@!vzjd z+x0MXEaEuB&kUi)pcj)FcY^o7O$X0eT;O07mr+~}`hXp63&E3ENx-YIF=mj&wPk3LAnc?RHW{01kdwKs>JFfhb ze`p1$z4iYvsI4rx@^7`!$_LsEKOgEd{Cs50@bj@b!%t8-_|n+n=W9?~m7!tMYiL^j zpUm(RH1_uLG1Ej)8~PQf9i0qKp(aO5@(pH15yvvsy3_o8%#|J@o{({m3XiOM9mZc79LqW!}IA4R?%%JJ@s~J~7RtN(9Cx;P^*g5n8Ow}aZK;IUGBq<)t@=)QQgG}H}EL;avJVTYfu%o%=y$Am%s z$k_}(U(N@YQ(GU$JN$fT?eOz~IjGIeJaM5N;}lR{1lb4bcY(&PUN$@Y1oc;6g4Sz* z#%`Ti;p0S)Kxqy%7X`W}I~+7d#PAW+hX&>O2h1E=p#EznsGZ^O@DtRIc+JeI#mRdb zTvl@No}T4Z%RQR|bWa?(AIb3X#r648FTxpig2tOWK;uTr&^)8h@DtQmeh3=ZkY@P# z)R}eSe`1$DnfAJUL4m&+q7|cN9!mqp?etIf0OazT1y<%th zsmcnyzn7cgCkrbBI8VXLQ_xxhkp0UUem+?2@blqvho4TV5c`i=pyr#`>Y#f|xw<(N zPtOAN3$hs*KXMp$&EjHZ_y`)i;b7$I0<{-FhAFKA!r;;-QnjWXQqj_Z5gM4#ymh{ zhTwbw>MLeDfX7Ec_xZlq52|xn;Q2xZlrKQ}DjqU^3vOF5Bia@sAbHSTue=N&xj=VM zT08uF1!@!ZgU0G(VYg?T0vd;Wq3-w-G`9e1gTUGzTr3Si+Kmh! zLG2JNMvm97uFscx1?p!oG8AbFc7XF6xXl5Y2LiP@#2J3R5Qoe!ypVPTkBhuu=9mZ? z7lEfe(Aqjs+GA&gv^j*CAZ-qDCeZo>NSlM75mJ{6GyZ(w%s%mfG-{jUfgR%%(7lbI zdjlWwJNyLQ@dnBRPn=mMu9sz;0;;<}br`J8anX)(3i!TYdxxDXm>A4JV?r;iVeJey zL^}gC4gzx9ZD>1VH?*CxAE}-37~0Nw&hYcGGt0zXvW!!}^)M(5(Ayg9NNo*vhMzCk zLFEdP7`*+#i86QbpPBLE17U`rpz)@c;*jwoP=0tN&G7RjXsip=<^$cQ$PcW{02Paal&l`1K0t_%*0Z{m%@!>kjNj zeukf~Kw~4Ic@?NQz1u|ER#@`wPiVdc&3B>aTV=>x6F4qt+$MT!1DWdswZTC77QIb0 zFNkOHTy}%f4yY~6$T1N#p8+28 zcW3zd0NTcCvT6uA%-j$ZZvKBdINrG-^){$I2O3uem($?#n&Ice|Nq5d?oDKH_?g7w z@bl46hAFVJ_{CvI%M4H*sqOGn{vdI1e9CO6n}9CWaJ@t<+0=0VWBi)MDCB16cF|BgFfGCTg%ILKi6kePGh zOJ&EOpz`bGbVl$#oCnO@a5K-_GEM=R_k!K==d0x$6CFODw|TI+!4@>$3+i)uf$o$B zt+V~j@N*S-zQFP4OOP9&Vh@-de}cv?U;K6euPp`5GlRy>UOr~{37Qjr37UswZ~(8D z)na9s`072wPY#xbAg@M-kBnD4XFX-+p7=P~@#m9tM|hj!YAVB&2cIExP7gji{Cseo z;U{R`3pCgF3N$~OisR2W z#~psYz3%{?$K+;(&RtYy{s4`gtgX!a;l;???ZwE`omHv%12neA&CA&h8jtk&TXWg# zt-~Zx-(QoJVd6`uosU6njN=YJLH9ntdhGBM)K>+E*M0`@+R_9ThL9If`Ip-n!0S6- zK6m)}V!Ol7SGyg4z5=bC+zfGN7pP3y40Y#vOg9qcE~p*PLGD@)y6@ZJC+NO=&^lL8 zdU&$m;pdCP4&b$$PeA=a*xsq-@b=dRaK9HcKLaY~;~9TGfX=@>;%Nw4%-9grX7+#j z>%|T~UoCg|`EoTVULAgVR%(OVT^k=VFob~YL7C5*4;h05trq~vfzk%3PYYhRIp5*u z3s9exk>MkFz6+FQLGxXc8Ggd&yQV|J2Rz?38N5~i;zrPZJCGZ9GyZ(F-SOv(-HtzB zf%XxC_7Eb^cTINq`Eoj>j|*xezd+)H=b5HE{CqOm0lcs9;bGMIu1vH4(_hYZ`1xYG z!_U`~LF2xTsPkQ*cK&)s$R0o@28g>r`|v>STFvceDS~Ux3uFcl`NsKI6|9iy41DnD6-W z;bO<156(0Ge0Z7hXQVpgl$Vzg^IaJ&pu2({e?Da9o_H8k-d<<;`QSQePFfhHE`7!A z`13WpBe)Fu|C#aU|L=@HUpn(o{QsKq=l}PNKVQFQ{P_yBfA%vYWPa;A+6g^UxU`m+-Cf#Jq0u##SB>ou%8*U=3+xOBmczLj~RcS2DK-jGyZ(_ zoAKw%{~+x6^Cf6qDrjs9I^G6uPc}p19NeA+^@Dyp!q&@d0FOs)XN0T+fW|$z@4p+g zzYjDA!1VJaI}_+m*R2ns>p~wb=9~DKnRBAMHRF^QAoIE*eRWv52kLKw)^>u@=F4)3 z-3g$%Qs`U}D2{qTWgn=`me25071Y0xcLc8sRRXa=^Xj0xTC*9zb8(<`m>$eOw!Z?+ zxp6!G1eL9z@`R%@>&J_D2JkuEp#Jtt=z0gRUGWY-UnWD+X(y6hpu44CKdjIjElnTHD0!`12Jz$W37Rji9@qLGxLlxh(Kn08p9D?fCO$I0JZnCMYky z2zU7TD%#=aD{BVunnO@sf>CFH&PuRn`uV_FVB!PNoC!sj@&o`iUDw-RJvKO>=L7CwvxJ(DFg=1yFUd{?b%UMt#iP;ex_8>Qa`xf9i zdr&-}m9y+fmBW9amW$e# z0?p&S1g!&OU>3aG9F^}}~N{Cv3I z;pZZehM;CP$U2Q`PuOw}8e`L2JOleho(RD`>w9$gk@e!24Mqu6Ovk zNVFkH8M-FL0p!a{JEFk}a${Ix6zJ3hqr{zQXMURRdem(@PW6K7uDPx1DOS}J|J2Du4Dljr^0rk&7 zX%DoX0#xsy#}O!Ak>xoKfci6R6Z>)a6_lR9bq;8p_Mn613U&rl@Ekm7EeCAg3$zZv z98~8y{Cov1(?NPb@%0K6CZP4X*$zM7=sSSt-H_`H&2jy$xeS^Q<9O>Z z2^24&zAI>K4BStE+6k&NKyG_tj1=DLXyH8>8s5_x!25t6PIvgZNTvZi=DE`N|MWMY zITdw~n;jtIU)c^nvnq9dK;v^F$ZjK0eF;h@&@~C5^bC$$Wi-36jITP$LF@vpt?f1b zKOH%(JOqUca#}&G+lAy+&{|Yb-auNf3o##CkPweTTGe4qVS5@xk>BXr2$W=3UzH z=R_<>IpK>BxEX&wyYP};$u@mSFMwAT*cxopt-Y|z>> z&|EaAJOj6bFN5Z`9e=(#@9^{ObBCXxaSG%zjpVTpsGXoP?ZtVApD#h$iNx!d9AOQ>5w{XB4+2s93~nc?S?)eML|272k1->P+6AF z`13)s;t41R7TB4Dx>Cu$}nh~95fEW!~k(4Xq*G&#>0$1U+s7N`Qk9< z7z4PB0*x8Whx94IWfT%0Tt>}z`1u5F%mG$LX&L>W{&KOy&lmF@e!iX!NqeBVGx%EH z=?p(#f%*o!89{Awh`T^zAs}~cX8ieTz2napn;n0?I?wp?#brd<33kU~#Fz}&9n&3t zJ_YU1J@5GQ;bqh^io@vt^cNuY+Z}(t1dXk%W(1#K^bmB8(RIe34{tO6lu~A#^71yK zjM8lQKOK}eA3AeSY)NC70?I=V?t|LCsBLmk`Tm+8I`;9K@#lZgm_#%GMA$gU>(7io zUxCI$enZDT{)5IY9Dlz24<7rN03Q3e4;}k>3?2J84ITS94<7rN03Q2z4ITS<&-n8d zGh}??CA-s4(4L_epgHG$=v*>ruTVE6&cS)N8&tM9!Nxu&fX6=eL&rX#aSxt9I}8~| zdBx52^CdrY?4#WQym#i&W4?)xLFK49;}p<(CXjugF?m?I2Wmfn_Su5cCTM>ZD1Cy* zBdQ^D=^#FM>;p80Tn-)kP6GwcM(gWUESG-h(#VQ1Ds220R5321DF z12mokE$2bx@C70}w;m-Ylj#{u~}duXdfGFU&l9d#wnom2wKVg)cKZ2595Ggs`tASp2jS2<0@VMp zhK`j4L-Hv~9RZuK1&vXF#z{bJUv1DC77XBh1mJWAnzQA0{P{-P;pbcE+AAD&1aV^} zP&>hO1ZbQ@AF}owG#>{TrR`fj-YiW+(=_3*xHUDy`XX#f7=mK{$VSZ(Z(deCw1)p-Im6FK&^7!|ni+mRZD;uT5Hwy4T7y{c@be||SP7_H zfsU0(fbt!vOe%Ny`81pGSc!Q&!xYe7JMg?DXdgfNm;uswa3g5_0I2T^9YbgYjUg06 z`gfo;{NR39I$GNT%XkTsQA1EObPPcs6sDlE5LBju`}&CSk|t2!8ni~P7&?{^jb=8M z@e(B?#8|?Uc!r z|I;5jgVtv;tOBcbX8_OHg2o{7Qy8W^a0j&~(8iQNYg<9_1KJY@8iN4EAuGejgP{I% zIV5d>{c4RCcUZ<+n9Lf2VEfZng2E59_6LzJUW4mNP`$_K@bd&4!&X=vfz3BZGat*? zf|41czdsRVKGZA@R)&w@{ywsM_0i13GJXIu57w`&)&D>JC8$oRM(URvL)UdwJAls* z0J--SXpgk9!%q*;9uLr%#X$y3P<;&=1JD4CWkB;TcpLzw~&X7 zC&KIm*K43X=CJw&ls~Z5FQBmrXnFv-=LNR<1*DhQ`h^Z-6FQ){L#|(n@s3SE@+u9+ zCb&RplEB!6i~{P|gm&%!>7cv{8k=ZK#xpkI%y|(sCjKy+;pd}#hM$i?ZCB7dS~+N+ zHDY`Xv^M`mJ!p-x!%qzsho7K+{fqYuKOY=so%kT0;U}zpS7*vNu#5vE*9+fu|4#?)F9n4GDEz=>qBf*n0P(@)c{+5A zTN``506GWtHOLL1GYObEv_O5G`hyIXpmjQ+^*NyRf8aS;kU5~TA2hBk&hQgdri1#p zAUm^|7(!l%L-rfIk#_j04cbc%S`Sp2@dGj^tMLOA7uviW;PpSAe-U%Rp!EqbJHY)6 zb8tLD=43(cLaqm3bF$_TyI}TXos$LW1=Rz1=49dF3>q5-jkEAGLdFC^LGo$)8!U7#^! zkh}ha&SP-+`QpFBPxP^Kusd+g$s&!F!`c!Zpfm$k?}%vUe|Gr!@Vmp$2g-~;AF4C{ zoF&IN<)u1e{AXn~=-h0FpAQeSPGkY)!Dt5XSrGr7QQK=Md%n#Xem=Bj_zB9t;C;{5 zp#A!wv`}L+7GEdoiLNe!hrz`1vZC0dl?=a{5B*w}Rspi4RU+uzqZ^ z!%t9Iik!ZLKro`bVXs;ajd^V`N!0rIG z8?eoRWJBg8LGFO1uMaw~ek@|o#{=lPQCQ!T36#FT?PJJU0)o~5r$4lZ?B4*blLn17 zf%*lRi40TF_on}E2JMv+SoybFaODGihMy0O8Gb%8XZZQpn&IaYd(irRho2xbK7b?I~U(RN9nDiR7Mw^vu6}K5Qu~Jnq%MWDYe3=d%rx;+ z0w``#!xJ%1!F%!PVuqiOmNWc(xSHYTgY^tQpKNCM`FJ~IFaL|x4nJS6clZfjH@Vs2 z=bP;gKi_CG{(Pm+`193a_K9zpxmLZI%^=wXZ;XpuaQxeDxW$_aAgV4g!&kowpxYNtMA?Vd^#+|P~ z=N8;%_<4$n;e(eW_eAiSK=zE_v#>#H?qAwF{(K2)cg=_R6}(;&H0JkB%!pdVCz zBAr_R8tb-(tmgxtTVT%k^CavXEMvx>ugo1G=N5qWtb)$02Ax~b&G7S;J7`@ZLc)?tcL{Y1C{Luq5ImOg6vuC@bdvwKMSkFPi98YxPZLYlTaM`IT=1W3PASB zKZNN8tskB4@Y9nKQqH}qXZ-oHn(^mTXRe8lm|0hW#gwSXkX)`(QbiGZuC? z*go3cVEb@$gYAR$4Ym*V9{{U+!OXe})K7Wh@A&hvx8u)8%<@`$Lm8$#WM)|Pu$kfK z0_fQQptH0dlr#Jc1D)Mo4fPXf{EV4l73e%PP6mgcilBVP%(x14{s^*P3!kRPT>TFOQ;_wsH&jFR`ptGAm?IG|Ueo$YE zk@Gbd6C}()V@0n(XQ-@)w9R-v)?Uud%=xkMZS`d@R^CM>n&e^ z%7kc#pB~JRa}b_@&d*ry@RO6(;pa=xS{_aZ$h^KeQhUXi@#jNOdNX$X*#s>U{Ivg1 ze+{bdKznpSZpe1{iC!jv{PPeRes4fyhUJj759$;BZ^ledFPY`FUe0IO$-xM58z_x& zvNC++VB~xSTBrG9KEqCsnJ?x$?9^akFaxn4fz~812c47D5cH6lLu*nH!<2`hJ;vu5 zz~>-?<`-Uo&O~PB0H5&zJO2T+Uk}|4pfvmlw6_YD7N>*ukwVgOXAEW<2C0XochDMd za2(l#&VF(D>B-74QL~ZZBWQj?@oLvB`T!4x5JP&R}VDptgbybdu=V>Yz{`=)tZdlyS!N)esY1<^k?e)(D-;_vgY5K%i#Iq z!w~zR?XHQSy|17>Ax}W#S+Mk^&G3^ImY()AfZD&1{kFRqz-!~{FM$Pcn!ewWt& z>2LKx<-NmCkRL#6RYCjaULSV&*n}t)~ukFX$W~WyqN)t9c;#2y6x;sD9&E1=`Q7rN}T5+z;XeiE*w1oeKmCM=frM zdQhL}Boo60O-JsDFO3<0zGQ0%dTGx1^QEyPxLkgHm}lZ^VTPZt<}?0$Ih*lk2kg8Q zanM>=$o$rK1!^C>ZswWz8q~g+%=icJesDbkaeFu8&zIefKVS7b z{(Q~MJMlGWzt(cbpD!1K>JR7{FUpX;&nWH#ojC>SFY=?h57t&pg}IL#681+OJoO+BGrz&x5yB1^ z|2NxQd?D;Gk;74N;*0NWpuO1>IULz1zWB}d^F_1u#25eBem-Sp|M`d=a<=UQe)gYF zgxP;S7H5Z?Z^Z8Y^A)rE&zHjPKVOTx|9tJw{_|xp`_Gq$Ehd7)?={;`2gU=oj-YnN zCLt;-?ROEnQk^w0kk)$ zzu6WvrUWkEKePRWmucMYKjGrf+2CiRJbCT*^8vs6Ptdux$aQZ-B*T>d!VVMvH`}1r zzufLWU$VP{&q)KFGv&p|o&Ab^zSOJZygNa0^{|BzeE!jk=Wah&g4zv@pnf0c>+Vg^ zbobir=d1T_huDvVD;)^7Dalm+b@nF53s%UA8ZnSysKc&Gz&0^^l*B zE{FVl!0j-Rp+R*b===zQNN9a~pY10D3#8t7blwfT=K6)d$j=wvP&X)d**=i(vVFnr zFp;BCb>a(a5lEV8RGIj~9>!Ll_`(^+R+{+29m+naI1yw{2WVd0U*zXQ|B#;#yhDCk z1cTO0xcz)^n(e1GD}%^WkiECve!k=er7g}?ulBQn*O$Ng%&_Uys;*C(wO+Fo!RIJ3 zu6lWx?I)~GfcQscBB(u*5CQeiaV-8Z7y0?Z80sJKF53sfNd8fVx)tOfbr@TD;tOpU zTWR78eJGnzaU#eZuz$=&em*o0`T4*&JE@w`C)A3i7$jct6uzz*f?dQw=Zs2hD`dNSZH8a<$*PGdXDl&4tM)iXd z*bgi)KWxY12X>L4FPNcz_}^*!;CCk?{d^Wiq@V9Fw(`UmzhP{pi7)=c*zyxW=79ac zF7opsd&tiR%ppHlfc&r>;)m5N3?eT#yZr>Y|HXc{pRXp1{Crg`0xl~+`T0e#$j=wk zLw>%fX8ZYcb_nFW#_4Q7U)T#k>Q&HLj6hN5Vxdab4z&0&sWRYem;#3 z`S~)P{pX8h_MZ>a-G4qvcK^wg-w^c3o_FUgjsMe;?SEwNyYtCrXqYU9y5qg@&lj(S ze?EL4{PV%<;GfPM4M9C1w}8&9UhMYs!E&fuf+22k(r29V@Vpzeyi%F?U^UxMtyl&m zG3AMBD14=fO0f)6K>6+AYPX+H&bz_;VURLHb>b~0X!)=nOL~1S{PV?QVMv+#zSH)> zYozpg8I~4RCcd~1V=GU5aT~@~n)u>Aj4d}2WDYpJJ{SJ^@Okjh2akh){t0B5@?bqA zz5ZuLly|Uv^^n_PqGE%}#7Eo?6P+5ACW6NQ**`+ty2V)BdtUhGi_=i|KJK)Aa39IN zyJ2oonfPKqjIBKJ#bFp*Y2u6HQ1(IDi6C>p?maL3^Wpj6pASw4|GWTlZ!yHZm!a+j z*Ri+V;AJnWo0TU@eTBL=AB%gp3;%qv8S38aowg4yBe{1m)GeSgZ8?msJn_Y97+Y!L zi}g@8qwGYGIbip07ykKhd+^T(n}dHY0l7CH;@;&@_kz*__V85(hwpk=Um_ced*=&- z?h1vZhtr+54~`?bw;SpfkbC=KY~_hBCd1fD6JJb+vK?h6zL+ii6YSpk!apC*5B~XJ zcJR*%kbAQs?yY8K5CNrEkbB|n7if9_r2`#Ux=qL8&UWFSFPfp@y1&!*!EPjX7DL?t za%VY=tvvBXHH@t^@kKq1EjLVo(7mLPu-x2f`(Qni8>3aHE_ngGD_aE`3p^}@mSm&F8uRFFf>e;ciKK!jO1Qt zs9Qi`>JDQoPkiAGV=GO3;SXgqN=*cr0}j)0;hzt~gMU5<4*vNwfMLpmc!+!dfbP_R z*1xc{3Yw<^&HF*}7bLCjfYr6pSlnwb{PTr1)V;GiZ68cWa<4YjEg<*m!`R9bUl_yK zN)un0L)ng!6G7&H-D@xW^Pzq4&j;4QKhJ{P8x3*q1twf+6;ft3DniTHa4har7ykJ| z8S2jdPTL3FNbVGdx&h=)aTr^9;tOdQTWR78c^F$_BFG%DJJp4MK2#6>`9L}N=VFjM z!y)cm1`SuxogJWj1q)k9n5s;Cz|6F2{d;H{2*%=8evn;Iw>Ed$KBz}>>u(`M`{h53 ztvvAsGe{4pjjS~B1v`{|P<-MGZfKh27ykK>KltYZ?%ywmnUF_K#!!`!Db@x^l(TY2J(*D$uy#24?OY)0{k zAalUs`d#Sf!|y>qAAAn_=?ikJKg6v8P`Ba^SH@K{K10LR8;e`-3;ld?8|v2VPTL3R zNNzn1bq6R7oQJWMC%(80V=GO3aUIHb6q^V#2kh4SLO&ng5BmAwcF<2HkXyYWZdHZ4 z6RCwM%7MAp9gBO93xV#xg@kQHHx&`Fk?J&0T#233^Y^8}W_QTks z6JHz_g46@Yg?>If9`y6U;h>-2{6XuyAnyGMy8Gz7+fVd#0C6iMe>uY3>Wsy$>xF*4 zSPc!^;7;2I{zz_}4ReRe#252nY~_hB7Q@&|6JIQcvJZ+(1epU4+x0>}AFdDj`CxU> z&(k2cIz!xg4zF8P!S$;c%&qoV+&W$8=Zncux4L)QK5#~IYctdxpm1%6v6Uyj=!UVC zCcfy0vKd7tg3JNCb-K{chtq?8KA0Tza{pZmk#k z`LI6d=Y#5?pQRwTT0`7gf$mmT&TdqQ?RW zO>hS0Mq?~)^cVX1!W-&FJ}5X5WDeMk{z5+= z`Um}d;2rc+5#&Z=h#OU4ZUpstklY7}ca@2YVD8k%;!bm+pD&D|?iBB|eIShFPGzVY zKw+s4V}r&FU~Hv{FZ7{oM!|_7bHMI27y9|oJm}{G(6|AV?Ifjr$O%3hPd|})V=u1s_So|ZdJ$PR(7GEFPNcW`@h5X!S4>F z@c}_Z{rVlo28|EE*r4$N7@L10$Q*FkvJ3ru$R70b0dvsL1t7PoL)^L;uUkQF0mfBp zU~W~$;@0sCm)+6Z&2JQlZJ7yS9+GSsclJ8U03Msn+6s5?Mu z;5dw}Jn_Y87+Y!Li}O%6Bi}@jIbgS57yS9~df?9omji!#f!rz&ajP!_g9vEc`31lG zPw-f+IB2XEbQS`~s+ZDiKS6VxtD*BJFQnamzT|iRsl^I9OO5TPDko@uh~eWCem2OQ znLl_e2C_faTj1wI|A3zlyaRqJs|1^)eJSqt6FQd;UT1d~ zG)Kn|87Bsvy#;a~$le#s@>-yI9}pit#>vh0^TmF_pD%Vp!|Qg3?Stz`;k6nX7NGE2 z4`VA&e6bnER+{)?JCyCnI}v0KIK1`?{(QJU@aKcwfj|HGGE8~E4GAxh-49N?{d~aA z_OqLfK?FL!d_l7kGQPaJ2RgnC8drMl_Ve|7H}F~Y;JZQOC4Rn=miYOU+hO8T2m6T+ zm|0gnc+UD$f$@N?B50ibcem|>@7=ZvoCjf8-eDXg0=i}Gmkg*;I zJMh@zThLr2Xl|LA?dJp7*z|K($k?>H_|F&0P`CGY+dk;-wtdjv4Jkhy?Iyn97KfA{ zj=a|X)WH_)ryVdq-Dk!06TA4&7tByU z)py%IsP49XP>$rM*J21iy@#=FCcgL#V_Q#r@g2stn)u>3jBPpb#eW#vd?LsWu%Fn) ze?DXn|M`G9{AVc0PxoEHemaQcC%Aup)?bG8Nx=1{gALd}EinJw#^RsnVn1Iz7K5a( z{BGL^+1<7e(vkdg8s;Y3i7(E>*ftYiT!yi&C%(82V_QvpaT~_AocQ8CjBPd%WCz$k z&&7T|d>;1m!Q-%>iXi{ohWMwKDF0Z4{SyH5&vh*RIWG3|#bKy_;=64hM0eXh2uJeI zYM7gBC%#w@W7|x8u^Gm;p7>%rjBPdX#cmkea^j2qFt+JLkR4$E92fif@OaqI2ZzIc zzV%_4^58neKat4(`R)2s@n`*IQ2+43c~8DPyXGu z54^i=AGjm=sT<}l+lepwVQia;FDAp-))QY$hq0|DzL*VTTTXm2AI3JB2(kn0r{!Wl zA1)93`CxI_&mAB?U55Bc1<6my`3Q7IG{}FbY0nbuucv{~Ht=aI{%RNd`Jx%>FZ*uW z2iD!T56qGLl?`*7?Zg-PFt*La7sW8P^~4wDFt*ji7u7Jf<-`~DFt+hTkR4!uwTu0H z*dF%tL37y8CXl~QL;UrQi9zJWZ#Q_^@anWU=uV@F*^agoUms=#mlYsCzFaN-^X2LA zpD&NI{^U4XZn=U%0K7f}e6Q7h)}Jh(wJ)H(1N&Ja^RN3|e`Y|}K3IVEuyDIW%LcoN zp!tqO==`_=OzybrPfbqH{W_elIW~6AdU`qhCnqE8YmSYrvtDdw{rTd2_|F&HSt0Wx z;oLi4EN1=r0#YAO-~i2yENA`s0=Z7^Zwz`A%#FC)YCY@EnM%+(fW@vqUo3b1`6$?X z=i_kioln-gLgq$xvqI)Z>;+KfS-O?}Pk*u5_2+}_u0J2{b_LIgyefdqXM^g?7wf}+ zzL?MY^XcYr&|D3~J(F2~zIe?Jac@8C&lm3zb1jR~KzI0Y?*z@;faYw9Veaa8{rO_D z>(58}-aDWChPr7s)Jy)eV||2F=?@X);a$ zyAL!c3aWG3S%1C&#UW^|VmB+e?b8iw`*gehe0e_n=gVf+pP;Y@pC?++3h@u<4ghZf zcpC`4-Q%qEfBMUM*Pkz%T~XUT?XD>8o_nBn&*^aRnRFm`z5ETH$JNp}Xl@DOKY`X$ zD1Au>tBK$~hJ)S2$uiLVRE;G+rHlQ1kqpgG`rWnJRyD+XvF!whzRS{GknVi|xc0`Y^W5#23aew)Mmp z<}kL^#23~uw&lbZ_As{LM35a|f4GbNeCQtb^MP~N&l-?F$|3%E0UA4j#s_NIW&`zy z9i-3aU^}tx6|@gkjKx3dVn1IfL;b_wZTo<`+x7uFl7F~iZUVJ~U~Eu32*w7rgJ5h> zI|#-GwS!=6gNYzJ!2VGe`}t5k?B@gJu%8|v{}e;~vjx=0hWZDVz98w!20RY*M;e;8 z^0D}VUF_!zW~d+jciBGp-DUgWJ9NGql&@ZkLd!PWi7(#6*r0X~j16k{z}TR64~z|J z_rTct6G3)>{lG5v^C5fK&j-w5KgB_Q$cOl$8E2eWL*v8>8Yh+$6=89bjm1CDMSs3{ zEDCA&yzjDo@Vd+P!E+@4oQAmx)b4??LG2zG8`SQBu|e$~7#q~?fwA=_g6shM=eg+5 zhtETQK6o7Z^RXAhln2=m|M+9^4=hf=N7qwmK8KZCsAX-FhwhvZ!**;i~f5*Qm)m%!Ls z6G3)>{gN*F^I>}E&j-n&Kczu_iH7*49W>7J+!eBJ?7u6#?TqRl%ZX|*zl3A)i@WI0 z7tT<>%`Vvb zHXn2xMqc6n^q20gKVNvGwMYC>+aq^D?GZxbFrc&qYS%im{(PY>`tyY{G%WkOY#(%Y z**<7T3QKNSc!26M7#mcV!Pua>48{i4WiU3VE`zZ(CW7n$ho!pc&xh)vKOZQE{+tR5 zOJ_(}g4#+C9=ra0V9)wfo{2%^<#RXio_vj;^_w~VvVZK+fR52Tcl*ilm+>PHjE}x1 zuwL-z%W6UBmU@`BqPoOYk;yF$j^j3IH($jH$R9$ztM{rSW{@aJRiK=4}q znSRhR(wY^qR^Qt7=L2=tpFE&FwV-%#7yS9cS@7ozWk^5crMc_R7s{?bU&w>Z=6wAK zy5{$lyz9>w#;)M;9MBqb@Ld&#U9-SzKiOG-dNFdo2Cp6C2I=E^tX^U4Fj&@AC5%v+K{d?5;oGaJ&9|&Fv1} z7uUnc(VbJ7^J6U|$Lrk6+#lVwXJ_}+^3L{ReM2JN{-wimqrUfvaMo);t6YE4GY zU9a5(f4*@J{0YNU&Hm+x7AzWU7a^W}GzpBhXI=Abn6;=Rkym#&n!P*d}o35??Co`cKP}0yUS1Q zw+@ru9JZg>U8(WI^W(|MUZAre-35QXbQT2lF(!iIYTEz*;@~k(V^{F~A+H{@fa8XP zk)s>7hw8<1h}qyceeUw}#eI+(&ew~e>!x4acY&7++#hQ%zdUR|Q8P39hvr*{NuHVD zv)3nr%=iGx*NIK=2vX1;V3uGPnV~Clc_2-~|>5JPCH@vv*^7F-Y7LXYq zxp^V^32X*z9r!;rE=%T%*IwW!czrQwExfhB&zIH#KVR8H-F}c~;_JgKKVQuk{P}XW;LjHf&^6^C`*uUz z4tM8nm!D6syZn4{7}cGyHRTsz?%eMJ9&>ovEco+9yWr0U&4E83wg>)vxLok(gT;cN za}=k%SRM#oQ~ogr(g%O24XGo&LF-%9A^GuvI;g+S^79I4TmsuzwY}iaSJr~iv1$&; zSoLxi#8`EAhwX#*4$QIY*&VizrgzvroZMmipufZR!Tb|ob)dc6FPJ%3y;#ix8UJO5 zj@Q?B*gmN4uzgV8VGCL-0V<6+RpAQzZ{G1K)*Ls(qFJ22k?3)isw=Y+_{CqLr<>!mpkhI7JEe~JLb^(_& z;Pugt>=QW{Yd5`UXZiW&eZWr*M$T^DkF}S(GIM`q^g8@_-OcioyE5}f1~mVBF>!lPm!B{4 zS$@7OX8GB{!~nj7_hqrm&sX^nx4mwMxC?au8z^ibZs1xCss}h2Id*xYhXd67m!Ptz z9~1{HKj;4cFaB`33p`FAq_g~76vQy){cpFQ??CI*(p`Q&0?B8y{CxE~;O9w3ho7fF zXS=)>`1$IfgXPJC4wk1tXR;k+usq4?@beU>!_U*a4nNNbI{Z8<>hSYH;{lt8jR$Ss z{}1?iUXPLE z^92Ymwwn0ju>iR3@Z!0^&xg+gem-~{@UzMt)JKD)Gf+M8V6n^32iqZG_h7pVxZMF3 zw|5246M@<6Za*I+v-}j0fV4+meFn{WalO{q2&!{AR=o~p`Kf)dYu4*0@eq3(akXBfj`U7r{WAEFM?e_W!ePITF9JM_Z{e7 z3XJxV^3Rvm%0Hh7J4|eGkb>-)FlIq&A5FAE{FeiM9{4C)z$xpJ@BSS?T8k z`H8j`9fR?bf?@z4$zuAI9p;OSPr~5M|>h! zEr`8PU?NB_=eDNE`7Mb|sKa4Fr@dY!?e?k*qu*2Ab6G8Sv?BbsYa*qaML(mIhrJoOl zlYTznPx`sZjbX|IZxDQ_n$Ah-G74HnDU@>?(h@b##Ckj z*SX*}=*F&DSoe#lv%vdz4}={iGB}8V>wqiX&^EC)mhgJ6`18eM#h)*3D?-BS^#t1o z&nMVEcs#-O!F{Cg+70uw#Kaf-VQlex})_~J5* zEj01Pbr@T4BFKJlcpc=O2yzcNyq+umeE2-^=Yz+IKhr?rr40!$HfVS~RCoFL!rcYU z&!S*IPlx$g8jGK|EB<`3S@GwK)lffQo?!dn`~=$vrzhAxIF97!ZkYQdCcfy0vBf98 zm<(f!O?)vO#ulCUVm6E|GV#TH7+ZMai^VXu(8L$ZVQj&PAp607cI24|au3+g+ZBI4 z+@ARJ!RExDnjk+*L;QS_7b%UXyZn494{77T_pb=EpzdD*$G-?TEJ9#mA&w<1+7*Ak zXjc6Bq8b_&yC>K_*gnDb!R86J57r}vMKsLa5))sckr&_He!dchgu`ofm!EHh9VYfTicWmP&hqp1X{Dd9S1bK|E$lEc+fiiVYi>wB z0`kh_}v*iALW(>X$ynvnBUBhKH6{RpD%7R|MWmFXTueLz6e(Q`NA8T zZWd3leK3E5?St79Y#&TVN;lfDIF^|BLLbH!pZLNU#ul6S!W_mHo%q5U#ul0Q!XCyJ zp7_EU#ul3R!X3s2t&4-PIVXbL15P*Lia#HQC;og8ocJ>Wlx}W2gUi_;Jdkwrk{yzF zUS4PZ$#K*LH4R*5Mx=qu&@i~{{PV?mq%?5e`R9w%%s;JB(ts#R8Zd;(U3W%J1Dlc3 zz+vW}FV-jhd~qC_2FlrYzSxYG2DW2K1I36mPzsCx&CWkxYad@BoiqeoQ8(MY3H9W)?-Nr>WV*KC@cPa zAq`Cj-4kpdv`?^o&^*ERK|NAB_^p7bZ~w#C;uBvm!{SeD;tO^dTXfLy)>7Wdj4!EJ| zU^OTmIHRV6$JT!Ls32Q6)_%lpF z@I@zjpzuW|y7)6p0ktRmL6JM-{v4tnT z*bHL}O?BMG@-xWq zsD2g#``HHO=V~l|p04oo#bkw_FS?)pWZD?zaT|9C*-yc~=F(-nTcNLKjy zA{y#{?FqII)F;?JP@Z7>Kpx5e)-bn9OnhMvV~bCG;S6JoO?=@FV~b9F;SFPpOnl)F zV+&7w5e#DsO?(j!V+&3M*$?*rLB@$7_kjJMuJH3=dcw~K$q7IEK>ja>_+O73QcuGC zj%Z&AO?;Eh{PT6T($Cl4u=bVU#Mk-E;PEza`$}8s=gaJ*pD&9+WvUZunVODNrlv#7 zlXT~wFOreU)MV$MFXEx?D|UBiogs`;rh?b|faHqN%G6?{GBud_=ZpNLpD)6pW$JXc zoiCi>W$Fd+dLMTzW$I)$MElC0`R828|I@*JGH2(XFWjAfKAP;d^YL`IolpFs?W<_) z8q&UcmyT4g#zXxd@BH(HJ(lv+T;b;nV}+kDw4v!nc!KQ% z{t31ZxF^^?U`I+f+^{&7nD~Mp#ulIWLKwytoA^Q;#ulCULK?;vnfO8;#ulFVLK(&u zn)pH;#ul6ivLBpo92q8p+yhQG<_bR_nkW2xV4U!i0hDg+A?aoT7bM-h%ytH+hnLo% zG~kGu2F#JtfH^b_%$$bil6g^98fQ&lkVtA@%C- ze%lA%`)wb5?zesLz8^83aa$gmS0pCBxDR8CPkiwh#ul6S;yH{hI`PG87+YlGi}x_L z@WdCNVQis^FTTUrf)hdZzua{DYzb&N@Y?C;i}y}HA3b*6`S`gjqJ8z9 z32Q&A7o-o=zWVO;^TltcpAY^!!Q0ud(vZpnW@s2NJO6y~oC&kPbzT1Fi_7vqUz~=f zgU9{05AOHdKDga)``|iKI#>;hGl_{W*2CE16JKnGvBf67*bZZhPJFQ&#ul0QVn2*6 zJn_Y07+YxKi{mi1;6#x9;B)|5bADO=CpaBkm;d?jdi>7^m*ao_ab%eC;JFjHzcq&w zxqT%(@rw^~`$}ly2Nb^G#5X>W_7!H^N_^r&VTXx|4k8mD2|G-5auA*P>j8A_#bYMS zcGhzFpDz~6|9mkU8dj(KZ66%(w|#K9-}b?Nq_C=n`AcHri+UJaeBz5{7+Y-Oi*^`W zbmEI{7+YlGi+&hec;bu6Ft*Ud7t>*E!HFRI!C`gKdLqa@;ILXQ|MTJU_@56J$N$_2 z3aiJEunOdaw6j2M4%9Z51k~^1P``^!+zs>leJp-2m;d>qSpMgWY^dKi_uD>L-*5Y1 zb-(R{;tPKmTYTb+U>I9$;)`$?TXf=!Xc${$;){3~TX^D&WEfj$;)`?` zTW})Cez4yittNup1NM8l{LhEw@jo9F$Nww>`Tah`??O<&gU?++8qb5oxggZvLKACY z{=SXH-|q51UpUMEd|?gs_w0V#2h;m)A58AIebA5OZ)untB__U*hq1*czEFm-#U{Q` zhp|N`zR-rTMJB$`hp~kxzA%Qdg(ki*hp`1Gg6s$T`=G@{kbA)Xc9;M8&^`X=1Lydk zCLn*`hWPsm2PDqHd&`jg4e3uvLj5f~(H`dS>sb6P4zgSR=L>GAznlAQAJq5TKB(@u zeNc|%@7HpO`r$o{4I1x;u|ebAFg9qs8^#8Wcf;7A@otcPpfj~VA#_d(N%Aoqad`?=iDhtK1FK6o7Wa|g)Zmm&U+!0B&T-WCD- z`|y2e*>)a_zqiZ%e6d;X=Zn=)e+T#5KJf3iec;`1`@kK^-`y}bg2t|4Y|z*>j13yQ zhOt3o*Dy9{>>9=fja|dops{Nh8#Hze^|zzRM38&H{@yP4^WpZmpAR<2{j37{`#i+o zQXC8-PoVP~@O87`@?0G3UoO}>)6-b|+b;L>MYG(`7u8VzTKC&NFz>g0VBBx}Kp)A! z(J;4x#;0Ly(D*crEjIB*I*bh(pN6qPyT#j_aL-=45|K90rT;c`D;1k3$=;SKe-a=+~Z z`F`66(*3p%#F6~14Ra%Cd=7h`$#={f%CpLF#Nlu%CHgem;!F&+2kNUntA{ zd?5|>Gk3r31NMH~2h9Dp5B~Qd+Pc4G5oOtb7#lQ}2y-`RED^>AjU~d^ps_?48#I;( zV}r&LVQkP?BGk_Z^(TVd1NO7J+|P&VaX%j@$NfBP&oJe|VThlT*&%5g=4V*?2JKY} zfvu_BkHxRwWq-c-Ec^4tYgtJ7^|{aX!TUbj2e12VA3R6$>uH$(K;vaFHfX#I#s-a- z!PubjG8h{)UIt@>#>-%A(0Cb)4H_?#g_K{8dJ{qJ0sHm4?9YeaV}CyQ9Q(5aZ)=zvL1SMqHfZb%#s-aj!Pua&FBls%_61{u#=c-|(AXD@ z4I2A``um{fM38&H{!W+u`7k~9=Y!e~UufW011@)?KK-*JJUw zx$Msu#^C5fe&j-x0KZ8O3UJdd0 zXV4jz(6$Mz-vw!l3PIx=Qm)0p;(Iw3e_xmR`Qoz7&ljhm{!Z?*eGuPg`yjf{_CYw3 zzgNTD2YKyZpuRcO-;SyiLGA(j`?}1} zhu33%KDZq7QxxRySx2)pnf)t4eDpZ*r0wkj1B5%!`PsHHjEAGXT#W_em2zK2SMlj z$Uw#G7tS(2Usyx^E!}7PK)lcPfpDMg1AZibOT*j<>Sx2)pnf)t4eDpZ*r0wk zj1B5%!`PsHHjEAGXT#W_em2zK2NfoQ+ynNvyUfpr?lC_fILG{q0{MG3#NWSIAZ;{I zT?T8P!Tb$sr=9I#nDS6u=H~-pnV&DjV}3pWodZ7|%NQKL%+D9xGCyB1L;e20*Y?5h zUfT!Xdu<8CP9@3az{PvG{Sl^v@TorGLIy4E5vrUfTz! zdu<;a@3nn!7|D;#F!xAIe9;bLi%)#f4P%Qk1a@kKn0 zEjsZHjFJa@kKt2EjSTmKiJ=mQWHV$0sFgN`sc&?=${X&qkpD> z{M`-lHyciW!_qXQjkW>S*KEh)Z-42ZFTACHzHo;6dw#F&gW0{d52p9pKA4Q;Z)KPp zB__U5hq1*czR-rT#U{Schp|N`zA%QdMJB#5hp~kxzOaU|g(kkRhp`1Gg6s$Tn^AHi z$UR_x`%C|P=pX&_fp_#z4UoUvA^tuAIzIwyUWS$5lHl^Y20WIxp3 z?Y*`SntN>@)c4vxs7CVlXDLJ(_8rC+pZMZ8j4d|t#eW!Ebm9wUkeQ%yL6M0s*kNqp zi7&WeY@vxS_+f0pi7$kuA#Joq@rfY!fc-5m{qv!G^v?&<(LY~VGfa8V4DojtGjd*r zj14|{0!`EPSp4{2>gS8sQa@ijmV%U5`MtIevU_bGr1#oBNJjGGVVL_RCcZchV~bCG zaT>-JoA}~9j4e9x#bp>O#ul6SVm^#5I`PF~7+YlGi{&u3@WdCZ zVQis^FV@4@f)hdZgZgR*qQ9p}8{;r1jTNr1WhWQ)P4&4j$ zcR3b+_e=eJ(Jl4!MKjdj_Pw?btb1)AnD^Q~Fh=rsGR%z<6JMmm*y0mkWW(5E6JO-R z*rF3(6vNme6JM0W*uoQERKwUp6JONB*n$&5_JjQmTD#dT1!;%&OZ|MNYNBw*d9rg2v6~mMV#SlNw0G(3`^)qT3hm~KD@n9!dT<2r) zx4zWR7ur%kUnoQU&EISLfVakn zhq1*czPJrzi%ooSAI27)_~J2)Ei&=Na~NBA;)~ZXw$Q{E?_q4gi6HyI{%+)(2yzeD z-~T0lKKvi~^TF@PpEV$VXG8oggOtW!s=NF|Igb>)eoAQKpTp3#Q|Vazd|vYBi_?-n zUmS+|`F@Y>gWEl}53cvvKDdnJ=fyDhNlbjP9L5%(_+mATEjIDRdKg=D;)~5Nw#dX6 z+hJ_si7$4;*g_Lu?1!-hCxYw;`MAGb_@$reHryOxzFib21h`&zJo9Vz%VZ7n7lWKHg*d;Bb%agZ(|W4|XH@xftd? ziHR@DVQleioFDn~!R*MNOdvleL;So5bOs01ttHiiO8-@G@Wb#^=!f9Fg7e332r z^F=b$-|Ks9AFS@NeXzX8_Q7H#e>=n6C^7McJB%$p@r5^xEjICmKa4Fp@kKClY49*^!M04=tlCdFwAWd6JLnK z*q}BOj4d|tg*=QcI`M@vj4d+pg*uEaJn@A#j4d?rg+7c8IGhpD&o9{;uz_eNf$F`=GqX z_CYa{zaL8=%CYA#HmDB`V}tt8FgB;bf$^1%TL%ESk!nHop|~XvN~^OpuRJV4eC3?*r2{Mj1B5L z!`Ps{vjjArSto+r1NQHIiJuSeNBn$nJK`rF$iKl5|E^ALVQf%;8pa0o zr(tYRe;URH^`~KMP=6ZgZ$_4hAoqa%ySuS0?P zU2Nj*>(KP=jm6*f5Knt@puRDT4eA@i*r2{K)DMh|6G83)`@vu0=R^O9pAWnvekOwa;12Nv zc>l1z%g+bSOh12dK=$WyLiYuO&SW?Zz0(YI9~$UPkyo$Xe!h9{_OqMO;b#x4!_PPU z>OWt1tN(l|>@acZ0nqtAtg9Z#Ga>GG+dSF!!TQOV_q!dQZ2M^cWZQ?kC)+;QKH2uc z@ylR!uRwRm2CGBzyl|uKgXNQLA1t11`(XZL+gHZwKOan=Z2MsHWZMV*lWkuKtN(n^ zKH2s`^JLox^^wtcl(?dOB= z$+i!IC)+;opKSYTvf9rF?vrgFI8U~HU_aRwbiT+deJ1eP7~nG{jG4geabf$=;AhjC zGeOR#wPyPHBtHG; zw(&%e9pE*{jYbo}c7o2TEm!;busrSOgW|NG_stomJg|5A`9PZKrzB{M8{|f7r=PFP zoqoR5cLMtzW9|L{3-H=~UYH-nvG~zn?dJ<`wVyAXp?;K~Z2LfZvh4$LBtL4y+-WiK zg+7dJKJkSyjBPgYg*l9EI`M@yjBPUUg*}XIJP~9E*pHxf79cx8e)L!S`OrV@=L7Gw zpUXgg6o>fn0ciY7-s$HdsX6JI=su}vqwcnxElOnmVk z#x|Y^vIFeLgL)Iec7pu)U-jq1|EWJ8{7(I84)P;E#E*qYetc=}ggDohoe3=-O~HOl zh53;iiyyD6{(Ny+_2-MzP(MDNWc%R$B-;nKk^HzB=1z-=FSf(j<`ZA+hOx~izSs|A zgU;oJu}vnvI1XbQPXyTk_G6>&M6jJ8KVDb;`S5z`&j*)NfBrKAo&OE-qXpED581J$ zPZO}e^kM#D#^SH_sy|<>R{i;6G1On@C)qwYJ<0aLaU_3r!`x;u@kKw3Z9ehEWEk6Q z;*04pw&}zdvtewLi7)2E*v1neQbnK>lKe_=^dz zzl_2D`e_Z#cmEkN%glDwpD&tKf4-=O`fK+j+Xvex**@5e5D-kmBW-?gj$eAu4)^Fed!&q*ME{dWYH znP-?G`!-;C?zO%XWIy#m^NDZXGyZ&Kt^V`XZ#Afx#l$zC8GmLoI{eILjw*WVezWi5Cg&~3G!FRjymzWmMjlfyL=b?yIaM#LW5*Ni_wb@z+cj+kftg7$qJ zv_x6&58nF&ItTc-BkI0d=XAv0>idj8U)ZPreDRp^=Lyh#_3N2;zBtbaUhm%l+gp8^ z5p%u&YG(L)|0lN@f6n89?x{TQ`18eO$DfZ@JMVnF-g)Pf+m4XEwa*!`uKAz9^MCq_ z`;I>!Ja+u~@VO&+Z}s~q$Xb7}U%$KkeEHrH99Az+gTf~rHGGaEh0k$l_#8(IAJE@^ziu%4WH$p@X0_8 zpT$VwvltpaixJ^t3EO)O4j&7Y@B!}|0;QkjXyK!b6h5;Vf4-1U|M_A*G0;iHTQAAV5SfX)NYyX`18eV z$Da@8JHq#i#G!}LcW4;3gTg2cHH?~(!l)SS{OY}L*%h) z#-A_lr~Q0U4-KQ|Ogmp>qlHmEmN0tE1kYo~xS@M$vK@cE$annt=&{qz$IqP*VN{Mi zjCO$Zfx@WV@#l+b$Da@C5n&{X6h@Ds?La10ho6j$4)C_^gLuZD&oBR<4r*tB)S$|n zPkfNf`13wg{$af1&qv9QKcC8@x3f$proz@jrDG}U<5hpYh*tgiA{biMFP~)lVDTi| z2lJ82dTUsDZ87nMJ&bKW@r5&tZ8q_RJB)2Q@r5^xZ8GtNKa6cW5o8CrtOu=c1KA0x z!{SwcK8#QO`5-#=r?@G@ln3dMvOW+r77Yy-*jOES-r;~TWc>@MT@2b|bHHq(F3f+? zSo~+M`tyac>dzP2Q2$MyWc#3hlI??TB>xG++-NcJg*c3DKJkS#jBPgYg*=RHI`M@v zjBPUUg*uFFJP~9E*nf?nb!^bO%v|;7L-W+14~$cP-Zx>G@*o=GKS`YaGez^C<;0hl zq5b%9EdJwH{rQ4h_2&y_sQ>CG**>VAWc#2T$$zg^5bekJFt+)`7oTBlvxzUh!`P-1 zU;Ku#O(wqh4`Ulo1la-hpQHLju$`dz<5&IpkU#b31MbwH%R&ANhxqRyXbcW({8>W% zX9k)3KVUv_Bg}unSp4@~<>!mXDnDP`R)MsSvnSa;NS|c;AQ{Pjhhc8CnE2v2jBP&g z#c3GZY~qXaFt+K$7nfmdlZh{`!`Q|XL3V)s$EY?DY$wQn&sBate4g_2!Q+&l`5^xV zL;SZAi~qoDI1ZRX{bdQB<8FhkSMkTEFZ{d?{9|TXbec+Gex7jfF zSxkH}AI3JH_+l}PZ8q`6av0lm;)~TVw#md7>tSr;i6A?`emkf#5o{;OZ~Ik#KHQ)3 z^TFv@r6H(Z9efuFpOmOB@kKn0Z9EZV2iR|*wR0dlL2;L_ z^7CPS%FhScDL+pdgYGPZ_>CDf){oTZMi~P>U^>xjFSOn7jKxpxDnDO1tNeUn4fT`s zB-;n#lWZRdBl$@g<}QngFVtad^NBCCVQjOBFZ5w-(}^#PVQiC$FU(^keOLbZ@O$#l2cMIFYJmJ^4e?tN)NkPNX{2!a zqwz#znBUB?`0c#%&ljhaf4(>j_1pc4whwMkw0&?L$#1J+?z5QqVm*v)KJmq77~5>( zi|sJB>BJYiVQiC$FZRRO#uGtyfc@qOx_et0Qg)nI{`v5H^3MmSlYf3RVwm#49O5@^ z&=@o*-azLw8#DfVv0VA*i^a-6U(ANO^Yld92gfJcJ~)iz&Ssch7875z!`S8%Uv$IR zW)olZ!`P-1UrdIvO(wpW4r3cn1la+0Cuq$b$WBlkELZ;daC!322aA(`9tXM87~)P) z|LuV^Xv~@MXDq1S9PRQGbY3=(Cggly(7BKtj4X)rv(e9k+%E9*JY9rAhE3-}qQfYQdpXqTT) z)g6C6X%G1MxH;hGBW8K6%jVGXNt+RI4y?B0&j<31KgB@jVn?H$J;)E~%Y)Az6lMgU zJqS8;6E=qYLYxsY4qPwr^F_75&ll2=KE_LN$Dc2x9e=*yX8Z{ncR$4m4HtgLpRc$b zf4&rk^jS1n89u_!G6bJ>_?rQ7p7wtR@Ypp6BiCy!R)&dOj9jldx5CcPX8ier9cmY| z~2dU?L%>_I2^Si^(*S{TpzG8R(`R2a^_&h~TR)?QGj2zvXl{r7aXH+wC zy!NWh{-IraYPL=-*X)<|0Y6_=2O!S7t`_+DvR(jmcJoA#eNX@Y7k|R-__KqF0diiz zYv{c^NO$sZI5Y%3W#-U&WY`e2n4ux4kK_OJ7a%`Z2mAz`Fa7GU{Y1}7jUO+o1Ae}$ z5BLc`=el0t=gVrSUDAv{*MrWv28AQP`%f;=S<#;ve!jZT@RO5~;U^oX!_Q}r86e{t z&l!Hcc+QUGCWfCc9<%>^_}u;HgU9YanM@jj9^Gf$`IxC82y{o#Q)aeRHk|*bzvg%U z`RcL5&zH{~e!h6^@bl4q$DL2a9l_^^zb+Q|`Knyt=gaHtKVMvC|M~E``_BiL-G9RT zc9^*#h==q4^cUieKS5__zswf+`66H7=fm=VpAU)yem>3*`1vS1;OFcQ3{zfwb^wLn zM%?FTGeFMIzV84&lN)hpBSP*!w<1!>IbivQh zcKF%J#Bc%c`Pq(a6JH-^`1$I*z|WVb1(43qcKG@7vI96Bzk%L0_2M)_41O;4Wrv?n zPCNX3aohpx`Po{abZ{M_@AYYipRdk4fb)|VFY@`>43P7)8QCVj-p}y!)nS33FONgd z`?eQA_yPU=>_)bUuMac)e05#m=gZ3iNatre{Cv3^;&!+@cRT!idfnmYi^Hhygq@$w z0CVSl2gumeZh@aK_6z)cush)A!~Fq2AKn-E`QWy|Pr;uIQ(oK;0H2?&7zP>FdZ_FO zKBvDLv|d#nl0P5FJN|sIo#Ced6NAVLQ27GA>oF5FcF5}R^YwA|pDz!y|9shOGZ9<{ ztY<*Xx1DdceQ>%NbH43@g394F&~g|y&j-54 z3Y4y3|3L1&q>I{bX4FYxoFw!qH^><$wd4%kn8u$n*v#~0HXAZ7D+_Mb04v;TZC z8nGRPc;sq0-400QAmOrEo&Epx7a%`>c1JCnKfC{Y_1zs&Hh*XT`SLT=uGtKbvKbVPu(G+B z;peM(q_Q~~S~jPnmCf1M%4Pv+b39tv z91V%z7tszsUxec+o4uiBvp-VV91KYdU9hs*8(cPTz*{yqGEIE#&hYb9xWLbs!ANDZ zx5Lku!Ju@=`5Im}BZXdFD+<>$*{ z_MebD4&+z8)MohkLLcImm)Z_LU+6phe4!3aA6$?&BiKFa4nJS8yMx<mzQ|_(`9c|Lmb}By7s?JlUr0mD;$nfA^+Fm_=DbsP0N-KorriDKNk)!t-H)}G zJ2P{CfbJg7uFM0s4gD%Jeq`02o1I zd?^kpE8Kr-RBHVI^-n1cmR)|Nq4wt#|nOmf!v7yZ>%KUlzOnT*2t@b0s6g z&lkn)KVLf6SgtteV7c-jgXIfn8_N}}4nJ3NI{aM4>+o~6pu^8Kq7FX~G#;=y*m%(9 zUAz0wb)pPE7dAH9ENE=7dDG7R^K~=(&sX*AKVMd}|9nx-4ykwI*?+!>hTad*Y&{Wv zPe3#~q-G4racK=zR&j9JOtatdC16osR4vEJH<__St1IRxQwmbZMpbu?R z=sSYf_<+TooqmGO;|H_-UBGt-fY_irRvsjS?o43#sln>}<0U_|oPwV5|Khms&J_#{ z;JZgb_i4P~XV?k7dsGX=2AT1I8&vK&fY!|I)L>+={4eY<@qe?;#J|;!EC1vlT5*6m z{@S1XeJlS~Gp_v4?Qrowv*^Va?4U6XiHR>3GyQzBoayJo)l5GhtY`Z9cr(+_N86bo zZQ9jNKVL0(`uTFZ)6dtNoqoRD&Ghs2ex{$Ve>44j`JL(KOJ*@hTL`rGlJS78BkKX% zhv|*B50V=(+d}1ywvUP%Z6D@0+CIo`w0$|B>F3Mk!V?ufp0@$12eo}T7$NI+UaWQk z=OOUDA=8|RH<{_D4d|@g=}w@#AGBV| zv+m3UwWS-OcOF33RK1w(^z+qxCqz3cp8w~|X#Ss1*gLq$9e7=uGC!nDvTw9~(BE$Rpu64nL3_LH3ugYG z59-@(A5^#7J}7Uueesy@=Y#xq+Xvb0whz+VZC@Pb`}rWg-S$CryX}K;kb0I?FWQ-Y zKGygD`AFLz($;gZmt_1N0K1F39J=0VIp5D0i}@gK@Nc($;N5Nuj&Dbc zi7zJe{e-a1C%%{tW1CHUF&oAidJIz@ zbUXcgP|Wnxnw3H1DahV-r=KrD>4lkd)vI*K8ZNBo{%0et9Ramn9UyCft{Fr9laIwe z{d_-PbVL2)+;0289?3t|P`854a;k^1%_hERhOtd2zG#QC4}!*sq5kRT`}wfn@8^SV zzn@hg|A6*C6f^x~hx+GXw$slS?MU-zV7Hoq*G;U3xiuM!Tg&-=z9@#e)x6#IfiaR> zlcDYaxiuZeHk_;=9p0f}317xjE70eIuSo{#r_wz+G)DPP2whz>i{NN3BAIJ~> zFt*vm7r`*L>BJY|Ft*V|kU3yK#Pj`p81MJBa!0Vs&d1>{ zJD+4b{d|S)7JaB&^!a|i(B}L3P~Y$818u*bsx1GfzXYXAeW#xfjGcZm@^W^+I1O>j zZES8?@AvbSKhw{roBe*iROkEoLYeR9Lv_EO50w3WGUYb}J?dxKDZui7ISd_P}E^Zk4%@Avb8wBJwAUCc}%w?sSrd;waQ>koCyYKU8Qa4}AK2--Ua zPH*ND9|SY~TwuX~BxW{o4hr9N;tUIhDWLrJFxctmlX67)4({JNSWFD~_kTM0Zm4i9 z=~bNX=L=zIdS!37eZY*AUYTKO(R|_yb{N}i;tOsV+jQa!ekdEX?oSw6K8W-Ed?@bs z^MSD6&mvvWy^fId`kxt5-oe_I57|NIJ(^E^#11;|5j1AcxT^LH)Veg#x|Y!;yaA3KM`aOIDh@;{rT{}@6QLneSf-v z+zT4_EoS<88S35#pn4OjJVSM}*~AGKpzamN;@;=HKVLkCy7zsX?St1y?!63ii}}PC z*I{h4i7#%$*rpR-+=sFoL3iZxLh6&}ygwg4_x<_cvF}eQkb6PvMT?n!E{D1oloqgu zuNinwRTUP#!dTpUp7-aA(@^(5ZnJ%GAIZJDp>6?{U;ANfvxzSb!`P-1UmSC)iAc{#24$KY)0LQAalU(+|K*+;dbAj z4>tS$JOXkjXf0#f|fMf4-Ovb>rza+Xu&y+}I7Z zALPb<7~5>(i^(vy>BJY)VQig=AalTOoX`97;e6kp4`%!RoDFg#HzaRq;Ea1Sl)SYG zwwHq)i+kI7f4*pjx_5t@?StJ&?k$G7#eCw6av0le;)`k++jQcKdMLXQv=$MXR@-@h zK5X~>`JmbNXFkZi>=5_<0j=MF*1xc{3TmT2V&>3-qyb1;)q}Own6bDwpZDjBY^ZxT zx7j{ekL2EHs9Qkc8xLcfO?;6IW1CKVkq%`a)S3t~2OPfnygwi2`~G~8?fcUia7eIR)q3(snKg6AoGVA*vXj=Wxh}otL=l%I280yaDZMF{IRTI-C=CA zi7&iiY}1J^{Gn_{t%)FW!0rs^{rNE5_veFP-=C5ocY@Y<7Bl@^1`XFo(6kB*TZmiD z!E>Ujr=f2Bjm53@ygy%9L)|*N&Gx}`B)4iq-2rl|K8$TP@r5yrZ94IVIgG725o8Y7 zt@gY>AKLr=d|>VS^PM)sln1{Z!R_B_s9RzA3g%W=IsoM_b68vJI~KR9^ZtCH40UUN zo9%;cB)1B~++jZPg*c3DHt~ftjBPscg*=oET5qHbO|R;_KOd_5{(PY9`|~i!t=}PT z4S>28cepaH;yVuw*Uwno%Fp}r1vk{K&26?1>XF>~n+H*E{fDv5Cca>Xy3f&c;tO^t z`ygoT5Y(;wygwiE`~G~u?fY{E$gQ6tZdHZ46;!Um!W0(&ka`x9w;r8?y7xU6_kQR3 z`QkGVq@FErvwcvEq*L;exj!Xh+84~Ydg%Xud%rGKF`k=x1ny$ZnJ%mj^x(UP^H%)dF0<_Q2fw z9E)3z^Za~q80yyeHrof$NN(K>bBFoF7u#WMvxzTu!`P-1U+jmn8&xNQ%mKUgIM2_A z$9;Z2IPCLN4CL155VtM{t!06hS)jHr%D!xH`_gpcv@OuS<6|stUC;CL#cHTqgWGH$ z_#?S>Hq;%UaGeihn@xPN7{)f8_+mMf4O%m`ng`N$S{hdh*)X@>$KuxMJU?GdhPu_g&Gvyal3Sah?f|*99mY1B_@W!eHl6sQ zAIfG_nFulm9In%Oem3oM3Lejm3@i zJU?GlL)~cIX8XV#$&J}i`$2BZhq28jz9@#VO((u6hq09>g3JNCv7YDW!+M{e52}5B zP6xU1HY7Y%U~UBUdD_wY1m+VZVD7w*#hvLqKVKw6-KpPZ`#>AXoxw0Sm`{8W4r7~5 zd=U*}n@)TY4`nwhO$3<(c4s=z&xh$gKOZFf{LBTp^E$+xzd+;C&@_r#R+&QEEs(OR z;v}@Jx{SrW{yaZlcthQ*+-Cbg9?8AdP`7}>)gHz+oA|;R#x|Y!!X3&!s5lX14%of^ zJU<`$`}}<1?eo(SqbBAdKWzWvDwq zZdHe|%_hFkhOtd2zR-uV85Jjj%mKUAoag65bDy6NjD3EJf!ul?;?~8`u*L3HP+Nd; zl@iRYr?I$Ip6BNaX{cMd+iV}OBe|6u>JE@w`C)9ci7$jpZk6Zx z`B2{H=L2b`EZ8q`6Zy4Kj;*0-KcBA}6kU3ztvh)0W$nNv=0khA~10c5^hq%?3fk6Z`rut$% zXuOnT)yw^$H82j4d+QG~g61nfu7<5qIqdlJ<$9-|TA+F7-Hbm~IURnourhpnvYqkg z3(%gGbbioS%mfZc?ujpw`F}o4_y74I+5e|fUSkkw4aWEX|E9m(?)dY?ZpWV-m6<7_5+-m#aJyLkxhK2W@8X}G2Q8BCKJO3%}U7l^6DPw+zn_fXSUPN z*YllzX2I4D^b7rb)h+b%DK}`pF6fLP)>RMs84-7H8+Y11(C@^&d)v9w_K|(3?L+HM z+Xv>Iwh!D-g4KcVHVzho`1^E&?F02r+Xu>>wh!bxZC@G-{d^$aY5PF9)Aj*>r|nB& zp`Q=fJ8d5@ciKMq-(mamv*6DM-#cs{eD1J)@V>+LO251x0}K6u<=``~_u?aR%A zKObE0uzhg3!}h`X4qNaT{Cr5-fbYd!3|ddcy6VMp#-C5(gML1a4uY%^I{>+3Dp?O& zAFpQo`2aRH-R}sQZ<#Lm^TlN7UE#+&Y#$u%uzj$S1jD zi7!C+qjQ7iEchmZ?n#HJ;hp%R8>WV5;){M5n|mV2juW7@anl8VKAax-^TFi6pA4Y* zT(;wG{&3F<(8HpW3nbsa){qi(;ss zws+V**xX_JU_FwbqG9e5nD`1Vu%L9KtC=UF2T7zNAgLa6Y4kGyp?w_Camtl3%1F(Pi!T$NB3yq^@EdB`>{P`jn z>YwEuwhtDA?tMq{k2TCq0ux`@!`S>2UpT|qd=p=|!`QqNUwFgVJQH8|!`PrZFa>{t z{Sz+u^I>@4&j-PQKc|EI(+u%XFH!#C1N-L~%s=&5{9`Wo^Mx_gKhryGA3*Q2hom9U z8R{@M2~2z;4`cIBe4z|u^G$rA4rB99e4!0v^Gtl94`Xvo1la-hkGbH_hvtDl9~cMz zOa}R<9^#)!WdAI7MC_+6XGH9$1;-ID*iRE-eyYaeCvm}_FNC3fYVWXp(A;7BpdKlX zehVP-(SI15f8q;fn0xsqzF>#3c_+T$hOv1jzTk(k*(ZYR0Q*T?@aIGEz@HC<1App) z`~=#|)Xn%)1<6my`3N-st%#BKc))d~qMf<_F*F4v9~`iJ-gPA#C1>FJ8mc@JxL19>xaUwK$ku*kUJm+3?C*2(sqwpuoh}*^u?7AV0p87W(}#_C?fqNr1dS)uyQ08*M?rG=X#3ingAn`LqCtB{gMPkA0ZraL?Se39+=^MN~L&mE{;!Su2A@&p#fDPZ@3>l49=FZ3CIz5vA`Gsmiz z#*ns8H>~Yr?D+GgebCRB+KfM+ItM}8J?e}Q|A5*%vxOjSp!rB)3~l%9{QGbEOLfPe zFSOCxJ^HBao_qiQi-YWkw|N$W=W(?(4qAfSJWrtY6s&&+DaUyyKIC?osCYndBIgfi zn^GA|emXAj^TlCkev0p~eGuJY`yd=CKdpx434w_(*2CER6JKnGvH2#x*bZa!PJ97c zX9*5Bo{6CKmf(Em$T|^Z2e_O#F7Wf=@qnKX4hQ^H0p%yqTFY+6pHiT)N38zff%-#W z;`Q%Pf5>C;$8v$6FBU`n0b5t@j^vMSm>UHqzUYUs`6s@Z3}f?6d@&uy=AHOrHjK?P z@x^>7+mU4=$PTbSmJ9rRxIEzJgT(oDcF(d{GQ_>p{MW zFUnzT-ihFK?O^ph6JLPVxr5lC`$L+KOZy){M-lfk2Iv5+XCuiL;V9w zUl4!rgU5l2U~wXj#SiHMKVKw6{h;4r`#`(H_JKN*AG~4i6PWnIAI9dN_#zm_=9~B; z9LDCI_yV-<4CL;EJQH8UL&Y7LCW7n$$4R=t&xh#&KOZCq{Okq!K^)?TW}I=t2TfbN z6CrWJGjTdBPK2@e$6es(3umZ*ZXGN6JO}V*!&Y;fY!Hx-OV=< zw9X9@SG*HnSi{utOnhMvWjiuX1la-hkGsInhwcGCA2-X|w@r$~^&lk#2zwme1K7g+Gg}4oL2Nu*lAiwa#*!&Y;2*cQX6JLnK*t`>8 zNW<7X6JN+f*^UeoL3V)sqAu|Bp?bj22g(6I)j)pXhxkPXn!X+`cKrEbxg&ht4x|j@ zpSXNIv>nQg#SiQPKVL9I{qVot_QCIV+Xvs<5q*W%{Ls2nVB(ASFgE|h7oTBlzKJis z!`QqNU;Ku#c_zO2&kyZS+fM}90rmsCz|V*50Y4uw2mJi13OXYM;)mCuGu8SXe?A25 z;l}U-&%`pAAK0<@;W_`$7muOqf!?>$+$}QA1 z#S2bT=Z`?kEM_czInMv{#bKyl?zh`MxZQ61;5w3DR>Rx|s!L#OP+bCJgX$6(8&sFT z*r2)u<`>(EAUnW*InMv{;c@?;4-WhPoCxv@GsG|LP``lZw3j==+s>%|;h8uG=9m8r znElY@{6AkThWh1vyX}M1?Y0k&Bl)Ep<~C4$0%L>f6Brv*pTO9l`UJ)X)h95&*h~c3 z0rtys{+|z*`~Q5f*#Bo7$S?mL!2Qq=^l=#Q{vhZ$%x}nAK=?S!ZwJIU%x4C~ILvzn zcpC)V?t`{V;B7u=dt~bGf74&SclZh3>w-KE^WA~;aTriq0*%AG2Cbv#|M{XB8kYOp zZ6EAzw|%f3DJ-*LVFRkmU~Eub24jQjG8h|Fm%-Sex(pVU))PT?fWxw#|L4PY|DO+< z{eNY~hR@(>rTQT=mTyC{}biUR0;ptY}2gh4& zA6!2QRtMi(!7MTH5hLRi(E3JD+6C=z0gtcT2Ce@Eo%_Ji{eqcs)rFXuLUh5A0w?I(?PmD-azDe*7l)zl*zWN2)ozEMulGat z^1N8g@bmR@hM%uigUsiAeTWI-t{00Pe!g7p@blGbho5iPJN$gJ+2QBw)lT5O1face zIh8p-)-rOu&aKS-(Or9Xc26zuY%fNh)tZdlyFlxQk?nm9YEK_WnCHdFwOW&rbJy!~ z@1Jjqy%BpeCNuneIi2C>tJw@cU(RRvslmix4oX8WKzkA*Z{QpD*S^{0rJw^>Vhu&sXyueuCCqzhRb`*j=gd z1HSIMocrg?Vs6m*>O@dnO#|(p1C4RscKE3U+CSF~3KvlPaCC#lM8R>}4>21Yr~RP4 zDj+qSuNT4A2)8531@4cvmtQhVOw`QG{sG#@=b5Sf0~9_l`Wb$H0EJ68+FpwFPCqp` zA?x(P>+PDMdnrKsP1Zx!6T-y7VFTJL1KL-^%7EDC1~LQWc4m%MuZp32Daw)dQdC3S z3*Spo>;M`&h3s?V=KlGTts&?oKljg<+}=N5@q7P#&F(NUn^A7!>wJcvua0y7e0i7~ zvCpm8;pfY0Q1~G2r9cvc?@_3B`1z#R;pdBd)IAEYy%Yt%{!M=Y+S60*@bh&sXk9y& zy%fm|5VstZo%lK(l(xBlzT6LWFFQBF56s*@Uow0De8moRyQAF1*V&*wdfY!>p5{jE za|79z3~@W$oyiVApVouc#G|?swwJ;U=FW6T9KGDk{qx0k?w=1fd;fg6-TUXm>)byd zT;~26{+eORi|gLteQxOVNN+Xs_dZ6EZv+Je?ffXZlaSs2dnle3ZGBPUBk5aYqlSx@Y} ze?GSMhL*(=;PE5Sm?wBGU^G&B813-$fj7g?*&u&`_NGX4L&lrkA^ryKzX9#5dEpF6 zi(Jt1@TD`PoB^+iJ}5DfgRyoKXfMJWdGDVZjGW!PA8RjnW#<0K=ymw<+L+-dcV*^} z3~2uMV&q;8+Hb+Z$i2(^t-~bH{tAwdrzV5S$d~2}KVMoi{Cr`LWWTk;&sX*iKVPXc z{CuGeamOj>IKxYAho7MR9-uunuk;;$zBYFFnZxMtv%50mM^9zukNny*vkPi@X8VBV zOQ7!R$jtr0#V7!F!wW|4U0#d=t2r3?cX=`Lt;XsmsC&TkETH`y+Mqoh44C^-#2J3R zlm_qX*aFJ)FG2fJK>Id8VWkgo7YB+PxK@M8DGo*s%y0nheNkrk`4Uw2n1l8r$bohCS5#%QBpRW!& zSe`uSV0r2wgXPPE43;NZ9e$qTbohCi*Wu?GL5H7bMIC-VXgpx^u<@YHdwuVp=S3NQ z9&Bv1IndZ(^H!hx=NoPApRd)qf4)-Y{`pcKlyBu%y%gvE`BIqs=ga?0;Ct6!JO^fyb$O9`B2>Z=L2EypC6P!>;53=3=}R8ydilB%#L>ew>!Y>=b(HC8Sewln>|?X z`11ifbbkjoq)o>SE4$@gQTKPSBkk{CXV?igj~%r45VW_*0ldHC!DPt(4AA{S|G6C| z{%01&zSo1@;o|?pOc!4?%S?PB&;0X&GV{-e>dZeMX*2(Ptk3-Oi81rfr{>H*pII}5 z{rZ5JL+gP(^G^<$zEA7(;v-z$CRpRcu@!S?*$ z&iwQLZswmalVvCVU(fvW|7PZ&uh%pGe6^YR=gaNPKRp>5f?n=s{`qRV^Us&NoquLC zFH}lVzhn;`EOAw$mzSA;g2wM2@;m>0!0r6= z(P5d1kC~+>YW!oE@&aU@H1p3Vpt@e)`R5Ce-x(c#zF=ks?~Q%Q4zW9dks;&-v-8iF z?9O1f^fEAnys&o$r%6>%x#kRED}mU|V0V9f@tf)Ai{DN^Uwmi!>B0PC`>XFxKVQP^ zV0HM(QJMAQ#e1fopfd$DE3>>&1c zCr}uH?RpBz$DnpUIIn=kH@*;`FXh3)VD>`Y8PtZ_@=)9P=L2=;pHG>kCq7Pg{`n-` z8B`W)F)=a-O$Ftl*GxYjFfeR+@Y?Aow)F8r8RUP4Ef18Pe?DQBp7u2>(|;yKgLmrM*Bw4OSE(~xE@*KANb#+RKT1P&0Ly#u#saYJXoUeV@7(!k?cLJr&Ak9Xmk1zJK?mP_&o5xN+ISw*^e6fAL6bB=N z5J>#Re%GBGvJ6Ep*yl@u)5$@ei7%s>f39S02znXM{PSV7^Up`|&OaY3OHBmJJ91Ba z>COyk?|3u+JQ>>%^l~=a&P-6cn$HH^uf#j?Wia#4Os0mQm*LDm85kLaKwy8=bw+Xoqs;ocmDb8y3@}m$<9BYraS-4YG9c1;5O4w4h{y9hs@FwUnV>M ze39<_^W}cFpDzxx{e0kTGV#HArk}95$k@?B`6BqwunDSshBtBoXyY2+-pI78$nE2G$ zWa8s)x1Ue?-F|}79eB+1IMdGq%nV!pKWF{<|26B+2hDmDA8d!Xi-Q&7rhZVEYrZ_7nDyt2=d3?hfWiS} z-gDQV4_~|feB^90F;$Ua$^+0{)2Eq!E@Ed80p)p6TL=_pnw$(1U&gcj{C}GD=l}B{ zJMO$Skh~3vXkP+dz8^L2m1Yx~(7Tw#iVpO^3Q|HtWw9 z^Pz47nK$3{=flMiw{e2)gSgEN19IDZXj;gJx~&-MwsNT3s-bSHXZ`u28R|BWdCjh%G!0G*j})MHdY)$bDbLOz z0xzErI#_BRbg+D>&ARi2KI_i^hm9;BC>u`v|Jcy-p|i=vKuv}z9qbK3FPS;CICxIZ z;;7}E&B4I&`o(OfpB!%)K4x(-guI;X^fQCKA&7~Q^Yx>CCKNwEWHthi>Ggr;YbQhf zo6h?4e>N!XYfXI6jq2YEe;KB{=!W_?80z0}sDGoO{*8zFH<|V4i*%@eLFT2q{(P7X ziHl_*|AOu|1m%A=29ZboPN?ouHUzsX1LUrDsJpybfByGp{rO=U&hno_?pFFY1|o zGK1oUaGtOe3=ibM;Si8EN1%2$jJHnVL1~@ ze*ChMVakJQsDJcXfBrXS{rTXq#>5B7sQxJf`6n6bA8Dw6K|>^pD*;G z{sEb%@A~thF~mPUApd~wCOggavy+WM1k`T(|CsIP|L1H!UmiA_`2RNB&;R$?e!gNh zn)vEA+s{|Zh7(`iXZ!i`F&nr}eEFR1=c~tVKVLp~1GTF*fZJ8a*&ywz(`-MrdmDmY z&*p`+tLF29+Ep8}8Tlr@zRdQso2en_^>wzNuU@nLeEA-P-G07|X8QRep6MrOKi`XZ zaNA(wi*QJL1Kh3(2ko76gSD$RXku$u`7=Sv}XGG!k+2pOKYc}FYKXVX^s?@<{&q_;}1)HXjmFE{e0!k{_~|jJ0vWPL1%)2 z!qO5Pmi3^p1es?K4NG;mpD)yze!g^e`}tBEVkbBZ)j{WNyU-u5O(_c zQXFCjyiKai^b_7DRc3;m!z7Kc<2kHNs?7BBg)%5yn0^*AK=T7X`_KQvXmJRNJ5U^g z@&hOi`Jr(r%>MHgzx&UZ!boxW8=4>fvq9pJ85)P|NO8yxjYDqspRdH(f4-CkVfUXe zxtV^x;Ai^zlH2L$3x2SBC%#~Z_!XQVKxY|>6NtnAjF9}m%=Gh>Jp0d=%Fs9j?dkdN z`18?Wb8sB;f#MKk9zQe=o!x%E_|EtfTyFgat>1&T`M*2}05LfVhtSs?Al-z<>!<9`-N`;i%1wzISTe8CMZ+d<}WyZ(I04=LNP%7NPQj^MVI z5Gyn-r?db3pA9;P3QyUd4o%D1>_1+j1bVd8^!KFL1({%&ZU2O+VSU$^Wb=!_~JMu&cSK_aG%X)y z{Q0UJat;T$&wLnizWSqPD{xwl{>3om1<1VfjF@G6IWuP2Uha%2+qW}<>vM3~4qBfK zT6ese5mL67J0r^W{p>&ggU<6p8h5}b+xJ7m@-X|)SNq+6zC4T+maCy*xgJ`!C-Xzf z_H=$k*}ffGF6?Ii`3iJ?*lG5kFHgJwdE_UVj}vVArr{=jAX zbjP1BXG8KVyj+-!R4z=0mJ8FtasTlJ=uCOg9AG!JTmYRN4=dZ784+bW=)8AEXxY>3 z`155u#1445Fd3;_m<%l!x)FB3%Z15|KVM9C{0Un34KLd#v;X`*oj}<>85)Pv*?+#8 z?EdrRbfh?}hsI$uG!D6;ambGphuzRP>}UV^YBu}Nm-9i`{pU;2nez3FKVMcm{(Mmn zcJIU&<&f|M=LgVQf!PG&FdrI+#f(2+EoT4uayc{(iyePH0G}~$4UWU5b87U5vp>dcFcJD{fy1^Imjz3>SL*pW5J8i&ycJK%Ac%=q&~G9(UPYzCQuTDEuo`!5bUHvqYh z3u=2eE@znX0<;InpYi9*d?)Z4MbJ7&(0I=2B!-X|-j3k(4C4DTFof_jGl;w@cKZ3! z8{(fA){NkG(hGaWpWwCg&PaZ9hxknqH1_80_!F!z+3hFjJWnoGhL0Q!4=;hvD$-+M z5P9tE`16swo=GpE*iM#hgE9~nM^>^Q~ia`}Yn ziCG*UnOB`tJU9`+O-5hJTa5{k``2Qd$fQA2}F1r5>0wg6On6??$=%*cfWO*1adcAo>_hsvivK3#-CceT-~7a1VQr^;JHH3IZMWjKVRxQ{(NEV z`16G_D8Af~>&TBBAafZRQ2IR&oDINzYtY!-10~RTZB9R5^1J+1W^y81D+u71t}8S8n?^7F-e7RXo+$h`M1KOcT}0r&4;$uLZL z09sFXn(3!H=$u_pdi?DA^CdsyPYzCok1vGL{Lc;bzc3_yg7?I5GyZ%HN`L&0KVNb? zg2o>wd4l{8GRNKRXAUdFN6>k&o~#T%UqQt*E3_7j%M{Og# zb~c#!8r1&-_5EH$%ft8VKVQ9e|M~JgQh9hCS{~kpwhwkg%ftP!@{n)h>&MXc!E^SX zub^iezWna~^CdIntlO8+b8f+P8u)BnXr1;SwC;pJdH9_H($@XW@blGg_Mb2RL(9Y8 z4nH4!clh~eu^qTP4F16|(fS;azMnA%q~DM&0BIlO3xL`O6S6_`6V@D%zMnnE&sW|YKVSNTu*c7r zk3r`#GW>k`7&MLzp0A$>S`z{)-?W$+Lcr?)ygk5WS|$_21g!n&>(H>g&G7S8FvriA z;T%6f`>r0|cKG?=y2DTKzT^Z(aCrU)ox=xOFY=t>CwT3|d)J>Y&NKXc$?f*@h` zCAfY$4>=bWJhDUMQ5YJJ;z;qx4~<7*j-RjOIexxW24Rn% zpz~f|Y-jlSa?jc92$?S8GgP}=lJZ-&H!mMbGw1pq`Z9Z`t#*th@Id#obT}SaKgh11Y_;XKRF7nh;+0?53}E=<1|GQa!K44az_@Ers{ydQV6`1H{0ds!}$<5$%EWf3~^HoXq_|CJPo|R z?QAeHXW#$n53-@|s%QE6znSId183!l57JTHr3`XcI@Dd+PAS2@&O)hs_> z)I;3`GOym{=fh@*yM9VBOnHzEahDk=t`0-S6CL>(LQvWl(DVkIOGpIyCmHI_WR{=* z(^-B#NLHE%T4Mv6?}CjB`~>As(D}5WwuV2{oxxCdhC|&M4RvQc%g-0dPNnKyexkb(1^G&;Q;mKOZzJPJ9rK8g^GeZUUX}3UZS%)J^74 zH(5j7WDj+dGt18x?oc;@%yW17`Oq8Urd1#}f!5!gX8QRYv^Ez-+hx!nA zwSe3e3<;})p!O!HU7L)(JqzkXaIi9beBsad^ZB3u;-E71VYl1QNBwR;LGxPin?YxP zviy7~42qisOXyf~(2MEN^%|f#{eupcAUVF5d0u>v*=GT#O7qxeq#6zFJ&t`FgRjCD%a)O9e%SiHwR26CXM= zfZMt+j2V7%usHmDVb1WAgTvwH3u}g-96S!-HAWl)khL|i^cMA(A^H>>v=5jLp%;9DDnI*{Z6EtSt zz`zg!9zzLd*a?~+;Q-BXhBNGZsqFmoMYzLG(0**teE$kghAofM(dKuc^G=nZc{X)u ze6zFs{Lc+ahw>92D5IuBBT#%RL*x51Gi1!{J2Pa=>^C!H%P8GdSWGW^uyW%#Kf2wexq&hYd9Yv!N--!uPwuvl*517_4P zdHaoF$_r*_m|Ta3$!%zu+=qtAV`!K>Xa4!(H8Z4d0y6Kl^UsIxoxy#R!;%bBUa*7K z0yF)5aoXwUi`z^;AKb>i?gD;B>|ySUFPzyXzNlvS`Lv$l=c8tZpAXv^em>}C`1z!t z;pgMYkTq>DnjL6`nQPU9Vuqgyj0bEJ zSr6DMIyTrU*f!WEa2~Kt){0S|dla{LF@~ z2?U)<&&lfW^JOx_PgYI`$Qpmh-opvtvlf&Ye?C-q{P{rH@#mwYhM;Cv$lV!F;u(I< zdjD_w%Xo*MFTm?f9V}m_GyFt3M>riChoH6^sQ!#*_z4ed(0S?7pgsQbt3ds7P~Y~U zJf>f9g%_yY0Id(JRA86_K6@Rs*9x?MOxW?~Lvc)VKymhxSzhbqdWN0wGk}{R>(eX8_NO^T5`WH$%=y*95KaQ9L!vi;?l; zD`xpsnucAoKz*14uzNE6!R^qApf#%RKyyj$AiEuYzH~+kcYa3D+yW%rxfy>x1nqC) zcKrD$r6K4sGc?@Y8GhP;!rj^7=No^ApRe6P_ZL9c?P@VJ1bHc*nbpI{_|eO-dlqPn zMw5}N>!mkRxP#7q2lb;tX^5Ti=L2TPpAXqF!wVGdkNmNxRT)s2gUtEO@bdv^-^*`@ zpAY{#V9zJK3?COl!wR%k8aeI5_5vDaFid&)o#E$$&kR3bes=iz;=9Aom!P)!dxoD6 zUOW7J_#V@2ko#VM+OOFTKVMZl`~jN$;5;dgls2|A{PbXA_yEq6n;CvS1f2oC+2LnXMne!YdqdFncmJlp0huQb zsTW>@(xp6TZC=g~j*pzHUNUp7dI?%13o5778GgQkx)n5z_=cHt)f;VwpKqACSG~~( zm0{ekU#QQQ@?vBFrDZJ+#xALs#tc7SK=&>@RCf6JK;7ZzBYlUTkF_0sGJXCx{gt-E z&o}xGKVO2*r&k8W2g9ld%-pMTYq@4;)t;H{#mL*8UCRU7&+wXqk?YsX-3&ip>}UA- zz!(x<;IJ@u`1wMZ;pdC=2h2-uhMyYHGeaJN`U%c#69ttSro037$GRbV zBtZLGUY%z637W6d0>`ntSc!2B0`JnqTKzoH5!0To~@(-6g{Cu$3;pcO4hAA((!E1HFdrLs~nLL>8@blqp z%=8McZ^7$y885zQmYxV&&-vg#XuSyY&qwUcKOb{5|9ryF{PU?W(i&ZH=o(#V=AREi zYfJf^f4<~){`pd#`R5B|=ASQ%nSZ`02d&kWg0I!R{Doo4OVBz|cIaB&#gMhS9So4Q zx-Y&n{jA_%5P8M!{PQ(vZ7D;;r2o^IfBv5hYGcSu{NK;~^Z#V#pRfCwf4-W`{PX2> z=-S-b%s*dEcmDZuw)0PKCWa5-v9D_A+T42R+FWMn+FW+_onSSfv9EUM+T3pDpRblP z|9rU`gq?rBe9!dr#b>6UFW)=;d;waU3c4HMHPW247!eCMC99y9%Xx!C#V%jZl#U#(~U`EoOKZSHfYpAQ~8{d{y-dg5bdsfmuC8K%4d znfDnoXa15Mv`!Vee)Klv4D*-wA$EhuPHsE>e0d)r6jiTnCG9TnL)i_zyCNVatR6PCuV8OHF*_ z?ELewJIJr{TA(re&oZDgSAG>J4SWZ!RRpg;2JP2k`gxLx;R4n*w1+|GMnTum?#Hr* z_At^K+H&X`+Wly2Xvhmp#{e$Xbr73bPcUNWDWWwd(awM$%$Zj&>C8G=o(sW z=o;E+=o;F1ww+)#jl2_I8bjC6n#0!6N=9K^UufZ&Oe`RcKZ3m z+4<*FcW2NT(5jiG3{yaBLN|lf5Hd?mdByCuo|(3_Ae+6 z{dW5K^1sv1N1*fXpBqecfUTcRX8ZX+9khPdXyX59wx9pw*?zu+(l3&s>u1y1em+Qc z`}r{4?Wf1q|IpA2jPu1nosY?z`^?g~w#j+BU<9FF|WcnGGkt+|K&*rLw`qm%Bl0 z+w>>C+z(p+pf~a5Vb-57jziZ!oM!#`;JEA0ho?d7AB-nX6@#vsT+Z~<50oaEox%69 zfaZQQLF;Gj*?#_C&HD2{X#Fa)?nKb~(*Mgr>u2>RzFN%s^Hs9m#8=B%e}dMzzF5!t z^TBG@pAXlA*3TMGe3b3>^Kri0PiIj7v>&=&Z#L`C|MNlXXLT^vMRtMw1YQ?uIPqmW zXuY1{#FwD8svtjs)~Y(|PkaeltD3Ag@#S>ZpD$)Z{RA>^w(HM_^C5mp0QspO60efr z^yU2XsWT#+A21`;jpAVZMZnFg22XWgcHU^Q0>}YONhRpGS)>1D4sjY{G zTQcj<|LLIhvsx2DYafx*f(^)R)zGxy4|N-8T`9)I{p@3woiCoV?EHV&(DH$@!NmWM4J;oz8&7PM!?Aw0 z9I}2^3$%W=9BKV*Hfa4UB0e56L)NM8lVzClARp>qch;Z(y+P||H77nuhvZ4vm2ju@)@;zVREODq z{yz>{Cu=(K|8BOQ|M!E|$r?_4wHvff)?nhR{UAB$I@#lFKVKbo`}y*?8={S~9J(%W zHFTY9G<2P8JTJ73!#DBuW;V!Ls_kq)U!7+A`SLsnyZw9#y1&Ai34Z?sc&^kMQul-B zg+OaQPlM)IGJk;UGtfF&^frz$w2foV^z+qawx2JrL)XcgL+*xnq-;9zv9s|+j*kpe zUVzMVhO}{B97dWejR&ohEwp_37-_CF-UTsNs*SWxR-5VP3vDOxx=`>s*?6RNveN87 z|AW>hCL`L3uapfYz5=xsnGGj`+l$iBd1ra{pRc6df4-D=M}#Fibl#a8x(-Jgx-Lzg z4;q&I6JHBM*Wrk>|9qv){_~|e2!qT4t@&j7`4Y6wR2kgnnfL;<-W0Z$3bf`_88YvT zGb}-CQ90Lhvf(UiLaltLFT(( zv;BPao$cq#-yrPv^Cf7F>1W2DFW)kiC%S;*5MjAqP_%jP+o$Pm(pASB}{CxP`1-?$U^VPrUFG2cu zJ0h#IUdmdD$pDcXnz%Gjz@3e%jYaVU%ZBn`Gd@R?eg>Cd(fD_@kDMB(Ecw+ za9jBZ3$$!^XaD&hwBG$Np0eE?S{`|`|9s`{{_~|bxIBXFEj5OgN9NFVFvZaFs2p4# zUC0LQfv|_JgK=j6`O2UD=gVLacK`WuJtKIH;>-1*b#CCaG4aJ}NSuSqcF>wne|ULx z0c-ztF(ah^x}5Rnt8n(8FQcJpdAZ}y2a6qlK5DiEmq!ypcVmLg1FdfbjiDfy?e?H` zvS?+yJ<>Ya*+}bTXM@fNbo}{ZI&__^J<>Ya`RqUcgVrV@mkXfs08}o3$_G%nFdrJ0 zi`jp^n(zMe+4f=S$E!)5*}V1g$rPl?$LXr^^Y1C1@=ws9b1g{P}7<`_Gq~puoMH~ zXuUOZ9D?Ew6o;U=1jS)7G!Dzzf4%~(_bx|@!+2;MCPU-!G&Db)hvf(UiLbMvahT8k z^Hnwb&zGQk7VF)AzKjR0A!Pjd612`V8SLJP;Ps}kI0UUZttJqMptY!=I1Fd}`Kp=y z=gW3z9ELmod=TvT^U-6_x^d%)XWxP58ytVWNQTBCsBHI!mhJvXaR^$U=Z{vlyCcP+ zJ2Vcx!S4O|!kO{s3(#4T_Ru)A2bH_fvfZ5VC%kO8MzX`)@#jlxh#l}abVrIqcW4}f z){uhcot=@&c6Y{~FWe#d@daqTHCovYUMCw48n-~SsX_go?QKphv*>9qjb;g*0TX zFvdDrm^^5mth3usnEWeY9P4Do8GpVMcKivtTmA(*D1BgGSMbCcDUO`=;p=3@Bp9Z= z0EHoFeHJ%#oh)d*C?nE3S!U=uQGQsNk@@2VGsIqyUtV!L{(QjcL^vi4T6G&P98H%0|%HW1#-y zZfIS-A6i#~)P-Z%lRXa_zheLSAGB`*sg3a3S%2bdQ2!6q_d5+O56`pzdH8@|*H@}@{CuVC@$;p+2dM7{X>0LA*H;Qd*H>yo z*H`KbAle7g(Djw_96w)abNqa%55gWlUmgdo_hk6_5_G27Y4Ci~MDSWuM$XsZb+VxK zrrMD8m7buxV6pY1LF-UKb<2K+pRbHLe!et^u9MyG@bkfL$ofjB1O{*$!4wppATv)x z*U6rD{rO@u!_SwmU4OpZ4v9l>8v%4bHE6vjavNbibd4pbUB4c>#&R>*%^zQY=Fe6; zfajUO>tvTZ{Csg4x=waJ!%xr}PH-DxF_Ilf>p0={%X;V-zQb~a9q=~7dWN4b zKx;+MGa%Xs-`Riu2d%kAjz>`Zf#MMqpP)9vcW9pY%?`eI{^f6^JnMJ$fA*g*nK^#GWcGm1lf4A3Go1}~@5C3N^`@{k0%*WDb+Y9MJK%9x&+rp;ei>+;HfT4`8w9XM}oh&=JjWZFn?gV3}|52e~O2>ZWw4n?UPQL2d%AO9iSL{!k7xP$Kbhs{181d)ptI1B z-4zLPmp9a1-cWae)}eyj1zLv+au;YFD#%^YEI(hwL)`^3FW%+n!(@oN^g-?doz1nJ z3ACR;1U8-sStpBd;{#}VgRPUD4$|ii4L@g=pa0!K>tq!tK5#~jQ+<#-ouTg3hq@EA zHWlPf(ArdxJFTJP0`@FFUpPbE2{O;w<>y0ph&x%q_CdmL9|MEPLo9LH0g6+5sGHPT ze*V`6txr^#_`n*~Ow1^sGC6Msk{7q zs10$`1Ac}n59}dsnh9PfiwG~|IDNP7|MUmuP&0m6H$ms>f%Zm%)@g#)Z%RYg$%58vg4W3@L)UL=Bi3(Dc*8K| z!+)or@5LQ{zLR$N`BvWH=Nr%(8Fh!Bpmj4ZAG_>)@!W;*I$3$7b+YmdJ3;foFXW-? zWI^jlxEX%_Kh6B}|9Q}QPuYo}^Wc!YQr+JnspY#+>Sum!INV`th4Guu&-Ap~qEyAyal^TTG& zi7!F>9zlKg<%~Z;<8}|4x#4Cqy#b|3P+!dP=PPwi@I3#6-3_)}j1E7w8A0cVa=(80 zo8jk+{|rA@f%ZBIL-z8)#2$d$^Ba_=9e#rLbAk4GfzGP}^$9>{LxI-SaWH_|4GcfE zSQ#e10`-en8iKqU89p*z?VR?Kpz+V|43IOozJuET3_mY| z^6+PepOF5c{3_5sLh#v|pmzLqXy4Vwb zzJ2WQ^VNNapWLht;4^T&Dl>nqWp((uwlebvXw8@xBTsi$rRERNS{80z&h9Kmho2sQ zYc6}eb(oaJ$nX=iuN1U@?8S9xd-=4(&zGR}S`R?ho4WTgU+3H{Q2;* z<4>l-#vs^vx^tfVoBndX!_OD99e%!^4oQ2UbCbPzxw|#%+YV!0rI`bwGQ?7&%{q-7(qW=hOM1eTja)%FD-~vAKpI##+wV zvyJ{w2j$I&&D;~eNia-#aGL>qMmFfo%?Q~KdYc)tAM`#m zsGqw5JP!Vu5i&pao$==@(7Yn(>==G0aK8k+*RCD1o)|no2HMvK>mPykm4W6GE5Y+) zkaLxeGeXX*gvR-+Y6kFJ)605>pRYjko#IT8eT1O>Y1IxtA1U)seB8`AvF0Vi6wrEX zkbU6uDnV@lkl#UNbTI?u%*1j?Is^B0L1!<6`X`Lgev&e1teXL{CQco~2Cs<&^>aYu zoY@RNUt~M{1obz-=T(B%p2O^bt%-{Vl^xJEamh$_f%+QY_3Y6864Wm6nmDLk;686U zw7-`y*b0))m`3{Cw&RT9koF$dMxeq^9g898+xAJvlWoNQ{c5>!45wkm^1ub z2P)_NA$bk7#u;AD>ofd(Va)LJC1@SEzQfN~#;9iwgUfksX!)rQ*&FoA9%niK+KZ9r zHD)<~Jm*dh=2dy=LxC`tKe$d)_ zh`YeR*p6L~aDWJ2JI2a*itBWDDY&|S6alSai6i~Va_ci(%em>|2t%*i$*Zn`tc=2yF z+e&czn496}BYuXTkA)e2J`rd5`BdED=M!OvpN~Q3LvuU)e8>)3As0CW5`c)QnGW)7jgZA9WL-w;g0JVLM8Gk-D zXZ)#l_y6<<{LuC;zvIvU&LSx7-De=Z(vCkLf%>Dyjz6E8JN|rP&G_@FJ*2(-keO-K zgqNT&V+6P9Ky4h*{6Yh0yd2av29?90wlb*9ltyhUH-gGBP+xi+hAA(l9e;w_@voLc+sKFUw2?vcF(5ZU+s&Y`eEFM#HZn8M#K+B!KcBQC z+Q{~T3{xI_$I(Ux`Hh*3HnQ*#X(NN&xf!z^PjMR=lzs`fktcxLd7!hBK<&JG#-9(W z9e+Nocl`MX+D88HkU$$**b()93gkAjFj6^=t&I%Q3(7Ckk;-w*HZsJGpmrz7jkg(p zzPj%C^Tln)pRevS{(SKm(G~@l<4A2{aQTVE2bZ6)Hu8PPpAR2H+NQ8J^5utUZDe6b zNWTiXjSOv(QHu0di)_ zcW4{=H?)oX8`?(x4{jqv&P-uug0zuAZER`Kx<3#mvW*NnGZNB9hMbvl9oj~Q#yPl+ z3|jXEY9lK%{d}p8)<#~;Kk+d$*Tl`w(Avn*@(y(N{R?8+$e?kHd}tdPv?o2E0kUrd zUmF=_2dQmjs9oSTGSn`-ZDeS9jJ1snDyKp6ur@NN?8MbZMy@BIZIcJif+%g|b@qxUWRP2t%Xw&fm0%kgRDKSIHZsT^ z)NUh#%17k8e~{bA$Ym?GHZn*rsBFdGMuwDO*vi&ork^j$5p7X$*^1OA2A63_d~n$c zYag`hLf+(C7P!_O5=3|n7-)=h!N0zqtN$Db=08MZudcKrFI zS$yK7&rUxde~08*(B88U(42@hq^%3u)BnJp@h9lsZt5&Ff%f*z(ZZ@h7^O zpSVE%3#eJi%cwi#xUi9y5rA>?v6iSggfng z+AKct@n@%>Prf^W?<+XX$uQ-CKI2aZ7KSbVr!)QhKbz_2i)4|B|NEJK{+|pQe-fSe zvY+Ya%f})UUruKF`C>W~F0}fCh++Fi*BZ$589o6KJ0e-X$rO<;%`l61`$wrBfIgzV-fIL zCeVJM1t7K3P`6ey{rq3g^z%it@WlVcOh5mZL)}^obt@>(S3})e&-C*FG!KE@D$e** z9OPEe83EZ$KmUXJs>;F>|EELU3ObiP8|v14CU_r}3v55ct^b%9L_lHwzgf)k1;~y6 z8Gim>ENc0%S$yI{X2zc@1R18hWM)_eT89L>YwsbmW>{0X}A?$z@7Qm^Ehc6u=~6mbZ4&Vrro2O2j3_34nq=piWX znHg7^gXSWCGeF|fpXulSV9=fgp^5+9nSTEFhK7$jG<=}rNuYghFM^qVKJa(?`7jt7 zm){wFp66hg^60z6&;RyJKmUWyNIon$@xL`Re4uBBgYr7){NxArPCp+yJN-Pw!7$|k z=nOr3#-H1m7(_7K`B((JpNJRa&d*SH8Z-U;Zw@*KUvT1oZKj|9^`Y+6hPqRq>E{b$ zXgr!T{d{2T^z)%P)Sd4cel7*M6LdC!GSkoh>P$ahJQkSvUmogC(7E8s(0Ej5`uRZF z>E}arr=K%G?)>Zk&bK|F{w_OY{sz>>UBJo^0*VvRnmf>42iU^-E~qSd4Ryab)6f6X zpm-IS2x@=+2aS0i7M=JK)CL9R8DXZMFT|nlmuC9;K-}r)Lush{pELX{1-bvZ19+?# z)P{Y*EHLpuGt~W{{Tl30_j5D-e8BGX^C7p>&kT_JL3dHwGyaSLxnJIC=L%K^Gf*EM ztGl7$z8>W6$53}e$CO_*^H2Q$nepd;&>7w!cZ2pvfZY9^@#l-*jF7zkpYi8|-;O^Y zg3bX4<@NgvKixs@zVGn!|7*sd|3UjIl=&zAe-2ttE;jKcwBG;!|MzD8`QINjA1O8QzccgC|L)8`UmX^m_{y32 z=c~se6JLSuv+;)R1@~wE`O4e*=SzR*pW3j!;QG+L;Kt05GpDoJAmiToY&*efKx^r( znIZe6?3sVQie~-^x;y7(yz|eO*Fod(3_o99hu&EUS}O-Vj}SbD30jjD4cQB>3EK-E z4BZPJ&iwOLurqjm>t(p}&zI*x=VUVfe3=g23l6#m@3h0uN6C^CA2*9n-1nGa3V4m% zZRon7<}k!sxqil-FPg(FUoH+std;9WS}S)LX{{V+J`2<@-p>FzbGqLVapv@9=AWSZ zu3kQtp7_6>`RD&;Xc*Q*!?YQ)R~>xk)ppPwSk6CRZbu5s`OvUj4Bc1n4c%Ao&khYs z{)wQwu1x^0Kdse$JZz;}E?*Bye+DBMjTELSu9 z1c&8%hM%uMbJ544VF^9+;n8Cma9C!8!V+vAG%V*kfzMBPx!dXI%jKZ)Zs;Bx=$)US z{0-hu4_YHWAG*d0bWZSm=o%}~d4-_4gV_w=`6bYt7kHfjcf#)as9e%!q_KU&mBJ%Q2V$q zc02t9^=)5*?!&=1{{sr&e55$chsGh6zAZQoL2JE0=K_H4DT@cK;e*B@zIh+09q>5J zXMmguiZt&7k3-PB59oX)(3vWrb46JhJ{|W{Z2n$xI@oi1I^oj&ISXWIRsi;5)55i5{+0}^7Apn zl(+5=}OUXJeT1$ll@S z|MQGL|AY3dIrB~Ye;QgpoM!w9I^!Q)KU`+~`QSWco_7-)!;}Z0`73+IpUW5+L_lr7 z2j&bv!EGvIhM&Rw3{##OgU+yGT=mf0;pc>;?Hl-{I%~)r>#?gZ5l0^G^J~9O{qdkhL3Nf2?Qx`Czr<&xh+Be>Q;pVGU_tlrS)e zxc&Ptj@}k}0BX}87MLHFH*!(5%=XA;P*>JC5u_cQ+d4?4%*nP=kvZm3(k8GpX$hs-m) zn9TU|LBHeAhm#$DhO#kCc>$WEvuFJ230e~X>VGX3oA^?m;phKkaZB);sOwHYUtecJ zoE?}PZuvS{+!E#NK+t^KZBV-wnr=b!SfF$Zn(qRoThQ5dptA!(b8^r-(7YcrOnK+* z`138h!_POMIVXOHpRa@+e!c|V0V?f)^-R0}&5S?)w}a;QxhMXwX8iddbT&RHU4r&d zfx@Vs@#l+XXc)DF*6KL^eAo_+Pi2Oml5C*6Bti4g4nO}FGyeP!+Q*d4J@G&2jQo7i z9x7-Uf#xuZ9e+M7cl^l%3M0_|A<*0j=qxyAIh47U|IEx6|5kIagv|*((q{PiSfAnN z6Jv&-PeFZb(EX>Nxlzy@X)vg6WB8fD$gmZ3-q8bPho4Oh4nLbg>&TcP=cKIUW|;D~ z+I!`HW@hmG(NlAWpAXd?euC64W^nkq1gaL)CyEB8HF?PWv=6}ZP6&OVcm=dj&Fs+W~T~BrjJt=)8Q;d1;{X5mZ(@ba(iv zagbpONbM7G2gLdrcF6h}4VZn_Q2Xo|em<~v`1#P@;b&8ALy$A*{=?h_>I=)8XLT`r7VU7)j}ngvkf3qD@LEOzn1 zeTJV8A2a-X1UmEjHRK#8@c77k2FUuh&kR2wg4Q2B2d%Gk`1umtr)B#2z*z`BE>Z`o zBkw!>eEFOoGA^Rt2wr0byN61Hk-_XgvydgIpZCDo>E}atr=S0s#Zc1di~FGX0bz!Z zpmXlPdJYR({S#cCWa4Qjyw}zf%cq$ z&H&J7`uRZH>E}azr=QNu4M7|Npmf2ZRR@YISUbHk6LjbJN6=oe|IC7xp#C4MkB9F6 z2lpL*K5-VB_{iJo=VO1TpBlUkK@XWZv>t9}_*who|MaJzv(%)Sem<0E`uRlK>E{zr zJq}tIv76y12RIGMfcJdB(-Wv)2b#wbXZra-*y-m(ai^b28ybQ@ZVd&w5qb|jXrCMC zoJdE|x~JU^KmR)mSiazA`uTv{>E}a!%rJkD%s=tLYRJ0ahw+T?@gC+!3{ybooxO;6 z-1*d5XyRjUr=L&!oqlTmnG@70yS(TjGbi{y#4URnraaip@H2s#Vaton4nO}Z^IL-M zRC@8;5!^O@0os$koZ;txSp9yOZz8yEPv)Qa5?ZH&^EGmv?kqG>f6o8upmWDS=Z~R> z?Zf+^F?EES9)bM8%(SZI>;LHw=0n{w-{I%~WRV@;**C0Q0D4v|vxuYS7 zgORf<0~CIf9e(~_%xn2#H{;J2pmk&IpuUacPtckrP+I`ho_OKRI}y}20J|A_-wwzu z(ETy6^G1vAe?P~8o7Q#0ew7wu3tbu<2a(C+y2VK>B0 zQ$cPjcli0R8oQf7_toNzyM^%QqwWW#IUMyr zDE{(6?#g%g2|6nfJ^h2m&R^mSt0^;sJo(YwrOa&!8V7%o?g(C^_9ENy=ZkEHpa0_- zfBpxpGd|2U@qaWlFGMr`1l^$nPFKl{KOe+9{(P7W2`^8OyV4zgKFr1*UMrb#$6@Ef z*+C~;7ovt&GneHH(0G2Z7-MG^mdRS{oA0 z@bkYp(&J zP&tNNM}W$b9?;&6U}zZ@3@X1lEnny}{(J$N?*z4B^c}(H!Twif{P|xUG>^|Q@jvK} z8IU{VLE!}rA9co`p!0J^blNrGOhxtW0=S=<$*iYes@rL z#9{dYbY`x&<4@4prJ#MrFPs^E{^w`>`Ck~cKbT|Ue{N{}a5MgV!4I_`bT%$%-8^Uw zk+aam-5~qz9ezG^#taA0I%n{h++wDm|CfWtV?`!{<^}$P`mM?Q6JO6}0{3BGE{4vr zFK7DsYB6Zc#R)VX2ib4g&IDP9+RX%6hbqkq8IO}^1&tv=&SRJionxQQ^z+qbrk^jj zgRs-jm!LMYHN(%BpuHm2;PH})pmm0z@f+}X9HgVsBM#v%BT)}Mm*$a}J<=+%MP}euBohLFbSE z|IP68|9{ZBZ}y4*LHFW-((QMKpD%tx+Nz*E2B0y0(AmDA^r#C;H|!2SA97=+oBz$A zeh}}<2mA~_9||-4d<5zfg8aeB@NqF{&6u#mPfmt^lR)w4$;c1_N@FjQ8GdGf&U{a2 z_zBvZ_b?r_cFuR@|7J+v=LNq5c%KHWt?R)Exib~Cp7sTELlCHpdJygK^I<#|eT<;E zg0y$x`hr1cayJCM2xs{DAlTvO!*DcxU^g}dy%cBI`GSFA%L@>nmEj}od}t2Po$Mev zafh88Oblj^#2tP<6n6OefZyTgn{I|F;Qes^&^583y9GdJ>bo=ig!NVaR-^e1`hAFUqEvSzLI`{r1C|#qh zbwv2-PyYUu|D8E5g4VV_ybl^zhopH>oHH>pg#2e_{P`a=&kQ?r+L>eGpZtR>Kdj%$S;m~J-W+H6 z`T8`&&sXO`dt*UuPKKYaLG~PW`1$5I=)8J|pRdk4{Cs=a;pe;S4nN;5XZZORbO#P- z@A77bpKn0->g;Ct>B-3O@um5EDexWxbI7^KpnK9hm>A4otakw4z4Lav!_PH8>o059 za?a+e<(#cw%Q0K8_T+3YM*eOuM!xR1AU9!g&mB=bP;g zKi}?l`1!V<;pdyl3_o8_XZZPQHp9=Cpt0h`3_o9j=IbXr{CqXt;pgkw4nN<_2aWYP z{Cr!^@bgVI!_U{Cao1*spD)@Oe!lF6lwqKL2(JV~$cz1uaDLtG@bgu>!_PO&@~g5K zxw>^38iKt3I!=BS&G6Hkk^6Pl-}=dK;~9RwNoM%@I-TL?t89j!FG1s+#SA}R#XJ0b zo$T=Q1!!G;w!_ai`3^td7CZcW>&)=;jXNm)Gl1*G*TD=wUxhRL1jP*pBiAWSMy^vF zjGU`hurq9V8SL=$Rk*{?*P!*|{-C_-FbU+AY(}0g4n~Jd*^E4=I2gHCf!4*pv}gFa zf{|e>Nc|gk$of*pQ(*7D5esO6dMUCTY&tM<%n4o1*E5U%c*p!{Ob@bjI!!_W85 zka5wE-jFrup!+F6_vwMoYX`L@9T*uu3a~PO@6*%x=Xlvb>B1}lHt$u2Y6oV4<%}lI z3S?yXn9Vo=e6~B6Vdt!qwS2Q*)bh~X+2z1^!XkQi7p4T9Ip!*-+DLedp z$IS5aEjz={H=yxCMs9fe&|qZP3O>{SGs90%z4YL-!_SAH`Dmp455Bj8-Qg!_jOewn z!_PP34&eJSaOD|eSR8=D9uyC^L1_-nPSD<$*9<@ZBcD5uY$xc>hQ|y)|37E=`QWj` z&xfG7TO|4a&1@I{Hf(`x$VV zE6)xZ>%!Cna!)TKZugY1;nvrMM_(FleOticz{>Ekfr%jm%;seHxPX}jo295DP0@dTn3_rnpTa_{666987 zyFqRRt$Er4N(16hed3tw}9GttPCG>LF2|q=^11nXin$V1eDeZP5kc+^$WE91~%85;pYQ) zho29j--Di1*S zHG#_v=v>OzI}B4mcN>86;aLubkQdSp;B%}&?McwSS@53HY=)mN@)>@D?jL)Y@9;Bf zH^UTUbzn81`zBZ&ermw>opOWjgo2Kp^D}_QDq!t&rI!sskJK4S$mDb*2nDUa@;pZz*KTX~N z)Xw_}ii^4b|BL^v4qN#rKXm2)!>r&k^FK5D#XtE{EB{tYuY|SpA1!Ct`8b^6=aXoL zpHJf%!2J+Vz4a1w-`Qk_pP)4a515(ZWqUWsKF~fjZ-<``ybstuFb0+HoUdW~&;M3O zul$oAwemkRJJ?R}+z2!CL?zHVLD0Dtpz_=ul$KG|y;$zB6Ljy+3rIWaCumFn+((4+ zVSD~K4tCB0$$`{^&2|RmapsASlO29ONp}FR3G8J7ogV=$H|(+41v=luAJo5e_z7xf zX)rQudExEwljEp^B?qIN5Qi*-PzM8pi3ejt5aFu$_h$TtgkgUw$6G9 zK4ZZF+@}GjSw`WBpgaQF%X|VfJ`ZYxENA!$8@pEOZwz|m&am?_3-m4>b%vjrSN}~1 z&zp-o!0*#~c8or zeEmS*;panRPz?@?em>!boJaL=zXQtNKs%5>g+X_+IQ)Fg?eO!JH)wCG z!%z6WYj%d8u)Xu(cmVBL2Za~NUGqVG7tp?Pho7$wL+;jrxeM$L(3~$jDD0s7uGt-a zJ_Yruq4)2A)?dTsl4P#_n+~e4KzE&j_Q-?oIR(v&fbWAj&G7T#d4`{Q#~7x7_V>f~ z2HGnBpAI_P0X=X1Kg@LTZ#5UzJ%A5EbI>4nfyQD$bpmLf@-PEDAJ4pvxPRq=`T^Sq z{E&PM+HVi)hsz&iu!Pv@wetUACU9N`jhQ?E`Ry>n#K+POKcC2h)-piOS9tjk_kg9k2ah{4b4&#F@n32k*0jC?t+C{G1dR_u_Njx;*JEo4di|N< zr}l(~px3V%A>)JZ8KHFo-^ACy8Gd?$)|mZg`1uNS4x%*UPtcw}SRWL8pBboL1g+Nt z-@67~V+PvyE$#@uw^);j0kTh>AG!xenDOT;e#f7$k{Q5fc7X0Hdj%S=Rc3_jQ%?u& zjRmdOW1sl=Fw4YCH$iv8JAl_Df%d6`&cXui&jyW0f$sGJ^PyunYgiaUSU}|(XuViG z!_Qn$T~!a6lLoa-Ky@H!FF5#Kr)UO59Sb_E50p<{GyHr7J+BXRZ#wAg8(2Q^VgQYo zF^D_`-G8a?`17H$<4>kZ4MC3?A?4U{kUPUcc?dEl*vtZT3uv4mp5dn#$X%dyLG_Ti zbkKcZV0ZW2Jm?tpfmkmnKS+b-G_(a4$#?5=8$o9B_ww&1-S!M7eK?L z0p<>9m}sE8!x?(dl{=C{fPbVaI zG=tpXj0g`7Mre3|&SZ;+?$L&_!Sxd~oL{82Nx)uLFU;*#?Qg| z0U8E)^M^KC{*Z@^g}+pWrU!MT^nfjYK=&DAq)X5`8R)tl$?uMH3TU$LCV4wkl(=js6cty;S;E? zLK(N0WherPf%5kw(EN9`!%t8?e|nf@;$zUh+W8JYztmyoZ(M3iN-@>`X9l$`*jIx4 z`=B`YI0Ile1okGyFWk@MAluZv?u(6|_DJlsC0OIR3a&b*cwrVuZI5C9to0y0hJCZvGBSMhVC?8PwN(!44XeXApY9%xL*vodLW?4zyMdIn4eyGhKWHI{yze4+Cw> zf$m;>0XqK=v|g5(6FkPO>BukL%@2#u(~M9vK=&bAJAlW)vsf8^W-&tMyg+NmV0;k! ze={VGUxCU~P~QkN&i$BileXZ*PujKKvvU|ZySx9oPR{=8)7`_~5CpnQQJazbb2ynyCGjNbFPAkfz-W(`A6U3=Nn@Ouzzw`A?-_$ zKR|4dA3SeY#&V^RIfz&j8MQZ)!Pb`!Vvo)@0;+4ccSHxv_KBD^T2n#<@Xx z2E-O;_zAf~_2evF#;Q+Uf?cz88JRx5Ri7{Q)|_FdmtoH=Usi^XTzw8dKFBlt^s3DN z;iYI^?&;R4F*;IsqE572vuL1Fqz z-Qg$5PoQ%FLE#5d4=VFO;Rs@b#6WC#m}*1SgU%3CcKG?h++pWOamZXG=zKxWj|?9{ zWe&)ndJGLg=M+!Q(r2vt1j_U81p8(wGBSNUXV^dM94o`ewTuow*YYxSgU(%B$H>=p zR`KGjbAKH#KVTNrddRGx^?;dC>zwL=S%yqipVkTX&3Y@?J4=9xq3E1o|E#rw{jh0{-rQvECm!srx_SRK;=KEPW@Z$vhu$( z1HIhmX5@mdUxTbueZ>tbj~PF57VF)pfv)_;4{8|J_hYAw|4jm z8pBB0#xMmm*AALQu6P#+28Zg4x1^YsEIhLFdgHOrv-QQhGugCfJkM~@jN zg53ZbXR(L&mz)`XatJpDz367x2}(mR`jOn}4RxnK!_VAp3{$}Cok43^I6-YB&esnZ z7(zhpG)TG&S@|bFc;$a*$haqD90OGhWh@l5N28o!=OcTDpO2jxem-#r%{7AVwT7Iv z^$K(@bulEa9~y(k7?|Mk?S7qM3i$4DW`-@G`7qF&gbJg>&nNou^~MvxZ3oc04NzPl zjqN9iHU=p(Hw5W|(kiIV)Q7g+p>;fXeAD0I=Yp+}b7w(gGV+WJKS5_sfX>5y1)bXm zr@_apa5pJ|(jdsZa)+I-jywE(rOfbCi_zgHDE-0H9q8;QZBQO&FbAb6(Ao%ix&xK# zptVAvb^r1VKf&n^bPus2!$eTq?*(XY9H<=J4H{1a)tjsnL30rB_(U4d1E;%SMo78~ zXGEmC_0ag-3|d>l0-slcrMvIf7^Z;s1AxYy9`QT;d@Stn^9iUeBkl0>*j8wolm@ls zA?ftRHE6m6xf^t6G$Sp_o>tN+6JGeaEiR;X+7vc^(LHZv{ zGyHr4x<{LdVS-|;D|l?1{}*Up4pFZDKMY#4#JBQ+IK$6}(hNTz$usju;ZAc&D{uXGSXLtAss!PCXxY6<$DBXhM6RCav zNET8bEI9vfI>^1CxpvUK)7|V1L2sD3wYYiD%mTGTxf!|Pbr7h$fb5lMn59vv_2X|f z!ma_9RKc6}?{Cwul@DsGJ1JuR?)%P!} zL1)l|(m4}6>@7iI58h*S!1jSUXzZ2Y<13V~4qW*sKVaqmW){fUD`>x%K4_gf)5OQ# z4nLoO<{6-89(MiwKOHnz51wDu28AuEUQn6zf{|g%BTyL(GRGLz9EQ*Tr-SDC!1}>+ z?P&TzYZyN=eB=hr*Xuj{1kL?};+>KAC>)Q&1TWTE`CR18Rf&YhANI{TWcX)4>j2+x{9nKLWa^9XwV5 zDgzikg4)QSG6=K=4OBOQ(h}&7^bF=7+uulo&VGcnvtElk{Cvp{nr{K=L$nFF8M(V& zGc)|;P(3>f)Yn)Gw!3?lm*SaOJ&cSWy$ri&aX{M*p!qh?m^R2=Fnb^U|1bUkw9mjRZnPPG5?ogSowvo7c2-@5toa1by+YFt=p1EGoe8S{KyeucI?Elj z1_Lw)?u?mc{{DcR0SG=PQyDY{$pG0u2bu%=$nX)=_XEw#gVGKt&d}pJ4HVb%(6i#? zA^O2{V#bg*B1RlbGyGh^%CH5rt_QS73DmdKQan8i)IZAshi~UBFII++ptc{VeF(Z& z=oNUr2oz5YA76s^X@SPP9e#q^kf3(YOLoW|5}paorww>D}3n8 zG|`HgVG1Z*A7IHJC~Ze*KmCz6!_UY53_qU)GyHrS&H!Gg30m(3I^z?xhXZ|H)f5z` z-pF&R=;Z-w`vp|KfYxL_Wk$?>g4Rud)?2iJ;udsXKWMHMJpYNR7o-o=&j+2M4GL>b z(0(~%@EW^rP#OLZ)ZWEnuKC~p(?R=E!TH-7RL-E93z|a(wSitaL*}75py>!a=IZS5 z^9eKa#7D^vKOd(%{48z+o!bJPqXnl z6Zuu({wk=y09xM6wWD7NL)S`!&cg?tx5~^A0vfk@qwVk$w8jgxwhUaZfcpHb zh%$p$^*p$&c+bfAajjwZthJ1MU2j3_z@TLY2ei!Kc}hvKPX>;+%L}X^MSC# zPtY7?Q&eLRGkZhOjm)DTpA_TTgupz%Ra|EMza z2Ph4K^I>-#&1QL-4>YP<@8nz68~Aps?a#pHI=-D%}j=y=D&%Bibr_S0Me52kr-KALv8cDsNEQ zD#0uN+_{vgfr{}jm>p1 zFqnboH$Zctp!OSR>=?8rK^oMaWSaOm+TrJuctm?rHwWz zX7~xqM{qZQ`hcLk0-Cpn?z3@9g}CAE8PvQ2T9c{?+FPs$89#xvT`~9hg4_UFM-MIw z!0WzH!|cB^Xnm0M%D>ez7<<7%YXm`cH)w3*WioUfRWqV5(Rvv&KlQ-)fb9e623v5S z)R`IHC#?m^gXX$kH642Q* zpgycK>qJoggNHlljxkWUuZNDABt!eI>5QQL5+67~V<&L4aYN2w29+OAni(gGZvvg=2r2tuVx31S(%}8W1zgk z3_2ScRHw(R{F5KO^1m~5{T4W#po+oQZ8URS1l_6hFqq-zqi}|wkE0oWK0#YU_9_^% zb{(`X{*67uPacMbNpGwfe!iZ~@blGt2Jn7X^tR9^(3z^BF(%L*K+rX2ujV`ad<9z5 z2pXI5X88Hi+2Q94cgQ-PSD>~FsN4Y0WpKXs5?}}cr76%I3!w5FH17vaSImeplA9nq zKzmA7JN)E;rb$pabOMwvLF*io9e%z{clh}Vw5RAdWbEg`V|IADJPFbd8slSk#28z_ znl9ZLz-OU>)1^9eOa(L-2}+lscFA|>SjunE*czzK!VVs5fye!0=or~^Xu7-%O_$e^ z;{H7}?mvV2nrst6aae(4K7$ zlr;|jof$5I&P)gC^8l^;1FhRaTKBgCy6z9ukNWS-0PcH(+CDHgvEwbE^_Zac7&yK2 zGyHs=4H~y&_=&CTG`qww1=Qw(m7U=681V*MP=6L)pMb(aA2QaN1-jP-baxRbE-EvB zfXbCe#tuIpgTes1zT?C%$a>=ipgsV2?J!~t100sZ3_o9j!U&wd5pvktfuJ@Ws7(So z69c3dG=_p+k73kbpt2TJRw1?Zl=2#b4l_3d*`EG49o~no%=`gbmjS9nLG4LU{|i(< zJp|RA;Pwy5&ye*j8K5=-zr#<^I4CGiP}+mYb(b;2Pf#BQ*3JRfG1d-0UxUUl85$3xw0uw=HRySzP z*L;SbrN4oOH}LrF*2kcI zu%JG?yu;5&hgl|uUSOC48q)>Y2U_z5IxFOXGc&lJg5A3@^CD<(ox{(^p!v4=1GW#$ z8*D*)upi|+{QL*%=SegCbO7ZKY0y4NW=qgLB(QbUf2&dJ1Mqr0P<(^txD8He;-hSbpO5n$ezJqc5kU79g7#`hL-RDKoyX1a z6P!Om`!t)GEK&D6qS_D5%UePH!57Xa!1kC}w1l_v=-MjsOnFBu7XLk{F-?qcg2eS{@ zK4^xnL1cxjK}21H!i7>+f$mj-tFngfP4n7+iRIWcPN9@4>&0T0+WSH`> z++io^+^Pr8Y!gBIu2nBGOab-BUxM~tA7=RZA9NS&Vb+QNcQgF_54y`0nioL#!Gh0_ zIu4rOaQOM~IH+FWnD~g<@#kZ9$DfBlsenqvrT*n-FpZ&Z#%=!2b&#!KHLu4bHFk2C1|YC8?+A{)vu30dtie>Yq>clK4y0O z`2=*Xs51M+a?lwZpgaCR_AX}l`F}ZRuLjG+|Dba>=7aV)uulZ7YX;j3-CGE@7irD( zBW8|?r$P3bW7-SaKl_9k;ZIPwX@TrChWd3f!%xuK{1?tF6aRNJ{QM6(KM&+r&^@Xk zzk=4KP6n;*ZwLanVpVeo(9V!^jFH!Rah_+G0vf-Bj9=hh>y-hT zALe)Xd4iE)3uyiWUp%B?34eU*L3>{!vFL%9f6W>fA1r44`EWVo&qu2ne?DH%`18qT zh#x`s=YZl8)Lwe98+vB;en#*;VlUP^{(QL_bY=|;_)gge%*yaG@#lHaUh_k?4~&~^ zA1Et9&WAQPssdag^BM#VYl4z=Syb!iT@un zgV(*hdd~dw|7+%-+@N~?J@e21pP7HY{?7dK|8M4>uRwQw-e&&E$=DF|@;>v=2k#Hs zK45M_*`LV4&0zLoG31PHP+Mdn8$-y;#g2$`xu!FM@3jM`fkuIeFD^6x>;R>K>&!nN zTz3BX@VfKQCc%cF#mtbkd`u_*O@A>RVIF9oJSe48JbmpHgCOiLp0XmC*y7N!aIXs}V zR{!@i|9tTnac1uSc4*wyL*ou~<|-)Nv@`#F(G88ee&(MKx}ASM?1#i1BPj0D9e+N| zcKnGRcc8NxpE4^?e4Om^^GUkPPf)&v%{gR(^d&R?RA6D)@*>&s=l^o%pD(JJf4(Sp z{s}r)|3$Sk_za-``OH867c>8S!7M%Te=_sW|LM#>|7SzpnGAJjIy8-CGyi;%4|QiT z^UnwQ&OaX(L)>}&GF?5zqYd zMYQwJ7ohWj;+=oK0IhWoX8!p7#){Z~_OEdp`A{C@hE-9pD#i8@q*ThGbh3KTf7uz1l8|mFG2UA zF)LZVc#I^+&G-{E4+D||&0m1p7B4{OBXNW75Mu=2Bld!s@#hm}<%y4yU4A|W<(ik6SVpVe1;F`j2_UK*Jp;GFWg;zg2op>eVh(C$oV+`AG7@Y|D5IL%g1UH|KDf% z`N~;w;;Z{0J_}^b{5i|dSC3tOzI^WTlbeYFa%R(M7RZ@R=UE_oP8M@Q_M9x|1oh7^ zWH<6ne0`k-vghPB%gIALct&1Ql0&!KhFtNWnyOqc_IcMiEw4OZ9^7GYUm!B_=yZn5`%=+^MJ1b^AdEMdX17_Es57}K&_F|=g z+;nkIAq-P`g3*eS!KM3?iWM_?I9z9Ea|KI1P3KSptG<+ zbA#YBl%RXCKxZl5hVC(evcYq6(C`7B0|ZOY8lbr!(3w}4nSTDi&h+!eWzb#YpmThj zz~{{WKh5;>|9Q~8526$Q?`Qh?|1i_f|Hq;EZ9g=>9fsz&<4iwaoQCGN^GrV3Qw6VZwPp=YK2 zUk$Z;G1P9*`DviMzMARhi}g^uH#7Zwu-@tC!_5%8zr6oH{lR*NpASLjb)wk~Y9oN^ zxGA8zVm8yyhx3_!zL@Rw^986M4?6FDHN#I0P#w400eoKz=zf+LlbyhKIKP+!I!h-O~bcXFJnR(ETi+wJF0xdr=Jgt zA#PjmK{Co*IW9BpDUSf_~&e@=|OTqiEiWz<)*J&r% zKy$uI;4(y3Ozgi(SC=WPm)3Rr-Rl4F-!!V{{*T>K>PAv>$`x@gaYr22i*_j4mz_Ka`y0I zmWH4yAhSSc?q@sv1g*6N)$<&TTwS2OyDJzt%s^uBdKfe=0UD3+XZUFXDwmXz`~+PG z%mF%&0u&FRb&b|gKY`9VLOQ>Akwin#qjH9w%FumaPwW|f7J=LWn%4l$Rhc{dd{pkR z6SS@pcx*wJSwLP7zFcFkLU~T^_P@2_-<`K}?5%m1y7urrg!Q(9YPT(^s{=@FLSu8LS zbnhYP-Wl*+H=s5(_#Q;Xi7!ES6@u~z^zIvQ9znYM2GqB`@eVZi@9^`XGM0RttT6Gv zvZ5tQ`yVvE;H)@t!u|i#LHpUjeH75RHb2wP7oc;H`JH~g0FMhf{RFKA0o_{;zRTt? z;_hBzQYFO&ihbzK8CvU zIV1QkOt3qV?z929vjyZ%*qMlE2uZzOur^^wSJeUabe!BThg6A7}ab|1`_bm&|Gt{~rdmi&%cXJPvI~o@V*^ z>bT3#m#4w)NXXv)_0V?YW@tMy8`_S{2e%_PfZLI~q3uXe8|OO9&zHAB*yZQT#Y{h6 zfa=V}pgPV8)Rvq0VlvZDPayipa&^*tJ^-l1!Cc%4`L40W21>T-K z?gYNa47|60y%V@!^rD*SCwL80JriWyrI`sd?gDAcfyP%r<6Em)e!g1n^7F-Nm!GfR zv;2JV8B05=+3Dwl_bxvles)1=PhJ4Iv)<_^c#M;k;Uj$SGU%R=b|%Q){%R-id8c4^ z6hqxnj^vK{(DvM7mY=WYyZn5y*yZP|?<_xGfZBBE<16J(KOcN|`T6j-3rd@E9mpNU z2zS8uE}!S2Y0x+5RS9n+!in9cI@)pVDiFJ`;^eD$2==Zn`^!Xw}5 z=Y!`iKOeqEZCCby+>woN2L~gxU3nN1H=uosFQ9C2yAm2sFTi&pGJJe-e7+QTEaSo7VZ~3(y^kpmsny)6f6V@y-{{@)JR0q5q-dpf4XQPJHWVTxZ3IG)5A&=A4j|V zd=l^S6O>P3^}#cczIY}`n<*Z2M!dY`i|3%RDd(S{yU<@e2aO3a{rrEM`RD)p%s*cw z%T4@$p84nh%gjIjUkBY8q&V^Ad8j)tL*03u`R9w$Lu+z`~%5s*VaoHEgL1QnVwl-)?hzUIY z3L2Mv(JVU=G;RtTmj#FCW~e(sW3$Q%;IY{k`=RbU%>47ge&?SL4@2Ck1#%~}{em8z z$nJcgtS}MeR#dcYi~evWlldI8e_)$ zBXiXB`A}H_+@6>F0@^D94NGmOpZ}euEkR?9FS4C~zEEcR`6A!>=L>bFpRlpX7mKAP zg2n+s7O^x)F2-8z?M6NZHe30z?^I!iW46xD@;rT^_S$K?v!`>`9E385;Vs6!rvKuAK!~$=bta6 znZWnVfyO3Z9G0B;-xR~szYw z6AV*cfXowy)}x0L!DDjZ@fc;a@fc8D@t+Yg9>WYBj{)5|s16$YgU$>52G0vX_Wfb2 zKaE*`zA(o!7V_Ki=L2KcpAXGZ$72{k?)wg%7hq*TjK_fLh5w+tf*3?zdW_2&zHEN*!2`166b>(7V!t|;R%`#^4Zj0gvmdh^LZj#&)m;Pf2N`tyG>>(7^qwI==#XZ`sB{rT##;>1_ctUq7I zvx4@*1-(pW{rM{1_2+xv!K^=DrL+Eg znGM3OKVkQjyu9uB^TmBfNE`7wBchE6x>qEfK-xaf2x%i;X8idopY`X=CmTIBf@k!VF~IeMU$d5t_C^W34ZyGw*zHIMMRu;v`EBM$K&SJ%H1l!Sm*zFaq68 z1`0<|eFtSceDQd-wzGLZfKbHv;KU! z9~zd2S%1FT@A~uQVWhBJ4GqintdO(zler<~L^?O5oM7ai_60FVG8&jmHp7Lw0HRly2s?Dvdhnxt08uR!w@tly&9C}py%v^^66s6pUR-I z0Z@Kf%=l9Q#0JeZg2r(`cb?35{P|)w<4^Eif3qEbzHkQh5wd=O=7e9WyFl)1oQ`D2 zWXGQ`!Sl+TkTdq7c7V^=huQ%?KXEoVOg_Gt&-fF5*B|(fHb`6+GBAjM;`;w&)}Q~U zqs1X8KY-#8lpjEGI2js;(^-GMn(X@X<#ePtEQiKnH8c)?L-WIbSbpH2__`SyhwZFC zU(IIy`Eou8yZ(F$z1!_&H|U-luzM$h?pJ~Lnc6{NLm&=8_o#u&`ew$TuNJfZe7PJN zhs};ZAJjYke6&~_9EW|NI0Tv34~;`*m!B`n8GpXCclr6U8Yz6s9e=*8MvKE@q&O^w z#$h?wy&qqI&MwLa-GKs)L(qLF>d-h$2KB|EahQ%|M>6O>aflt@J2ydbSj_kn9*4z@ zkoy|55q7}i5OjW2F(eLO90r*IE#Hb6Aah`#v$V{ee!c+R0U6Es6Et233Qrw(&^c@k zlm5SE{rUerf%5M)G``=n{(SY?_2AWC z3TFHHGMo+4PSSP+pH25D*$^C-`;RhAc>yxd92%CO@=u=eC%F7mhS&)%|KuHizElRK zNu=^m8Y%BcL-US2*u5WLh%^3t0lE)H7@Bv4k;*^NT`;inj~~enZpWXXxlmA=f#)4* zq`V^y%{#&fJK%W-H0LYr2tF4OUjB)*{roSD7KiBNpExuQrP+SI5_kLgQW_}^nW1sW z4vj-$XdH?o#UVd54u#o%zLIDA`BE8#-G07gW(41-{*oCqz6W;iM9{q@Aisg*@IUBo z76Ney+NS`@55F0HzEWrV`BEDihoJk+zk}8V8i3=_4-|(W^Vp$r2rB-G06Vt^Eb9Nr&DW0^X+vnlojDu0aRwi7F?M&OqyhLFo*% zcDSDH=gVejI@=F9clXg@BXBy~a)e>Z3y^uIp>y2Oau;WxYCCj}8`h@+-JuQYQ>};2 z?Sk&$2Ax?0S__7)Pu0)%^TlK~%sKAO4nH6CyZwAP*$rh(ay7_(>p|%olD6P;+@Lym zJ9LhFwZl(P+w0|Gs2f0ca>Lw!txq+b?dOZxSlqDO;pc;ky~bZ0ko zj25L&wVmN7xK9Oh!)&M<=7ZA36UgBo{`GOysmxP&rKHzu$`A`^=m!e<%pZ)+gFUpLX zmtKI*0tM|mh-dtH`0sylaNgR?_VfRCHvIj&&Cv3EJKN7!o85lC-0t@CH6z0Z@YuzC zXg*ua2I=2<^Fr!mf8L#7HK6|8YBos!Zav%2SG(DMzT6MOZs7ZBKy#kpdC-1v`kDy3 z#|B=WgYLQ54asLO85urk3UW_;i9U7#TJH_YXU(9!A8bEg9*5?$W`~~->K%SQdTavD zXSWVBOaYyN46+YA2LR1y;Qrlr2F&)&cgVVEP#A&EeuDS!Kx@H4Yru;cApN`V4v6** zH~Y{3{OtJKH{9%y_6&D;Eu>21TOa6(knb{%j8+P`e zuY}ouz7z*x_n$AJ=hnOgor#ram21Dyc(0RtJ3?E;B?sfp3*8;i=9dwTxXl@nOzXR=Qgtc!#cc#PcPy?Oq=nk<1 z-o6P&svCo$btCAkVyGSPx)HR0IT&*0GrWCspY7-W#{}9p_o4aWG272q_uYQJe2kPI zPDA7HJTwj$L*sBcQXF1~wr_5;{e1PD?dQwaAnXP{W1rx8zRwBd2hbirP#l8J^L@|u z^W|q~elT|U2|Aw7s}!jVe9z*zi0XhE^D7N{d@@;|9=fylcF&3C3O8Ccs}?$ z)6WN=oqj(2?gXCqVR#O@9|f{c6n!ih+!uN*W(iso_~O3PPtcys7mp$Lri0cufz}MZ za2A^gTi5jeGSvRlQ2WnA?Z3?Q^Tl;0$lAf%Og|r7cl!D8HpKo1&p>C%JN$gej@fR4 z&q1?0T>S6MeDQ%a^UsI!%s(Hwv+aDW&iwOg6vUHXG6?Gi!=W` zdzfL$Lv^>EkHnpSK5#aicoL*f+8I9A$;i(T@>1FvGSAA*44G%;X9n*fc)`f<0lYRx zne8Wd4}m({&j-qGKOd^Q{bbT?0G~Gi+MDrl&%fy}_#tMlU}D(vg4_8g$V~7YB|Dl~ z(onPH*?vBdcKi8I9%2^gUUHCG_dsT`L(BrLGd#%55c0p-!1BL1+s_xmZa-gu(v`T| z&ljM&nw#zCe|}I~!eHWmX11UI*+Kmkqlqt>LFI_y#Fy-BKVNXO{RHo^;b;5#fZOfo zLw>iPkC=@o=7Zu8x{mfgyTio)&dezDhbVsd&4d~rzgZ#S@t^hQgWs+{AO3g!nS>M` zYe9ba4V^#bWcc`y8FKdDi)MYx|KC}`V+Y{1t>0aLzW5GW&k7mqc)_ec@&9AipZ}k; z{(PxyH1XwQ(0G^O#Fx)mf4+Fl3h~E#)}IevyZ(Im-WBW*TaZ7Xc>}9Ipm7b~FL0j~ zvR?oi=ioSc4xL8^t*ZsaIj9XgpAE8~VKLj!SM%L|zF6$`^VM>;pD$K}!do77Kf`OM zpAVM1{d~CE4P`&WuY;g;h7(_&XZ`u&GBixCv;KT= z+4bkc>yR+{@$~=n2lt(RK78!-6I+-(kaqt0nAv#Z!(_LgkJ8qHo~ytwW3^Z#L8%NP4uf47J>-7ZpD#dbCO5PG z{J$OKPTh(BSF`^7zaAQQtD$kXp7rO8%}{r4XZ`tLv+K`?+ac~e2Xg0mr=JfmV|V9^ z_0TY4*0ub}|H6FYiP9i`eSzP5Gv;KV0?E3Rz zJ0wq@dh&nzgLSm?4sx^BM9@6r|9GgI zL350tvNoRe=Zj>ho6}i;K1g=``7j;g=D8p@L)QmmD{Ei8cY&1i&03bAdCV8Vu0LO- zGyQxK?)vjZHq+1l-mE|W`-93|t%?7gS%3a_huZB74KH`rpD(-Y~4!CJccO`l9_%!0EJI7 zsEpUN1kX8JyZ(F;&Ghqyz3a~x@k~Ge8?*lW51J2m)|~iXoAu{^eW)9?p>71t5gS9@ zXwC|sBL}rJLP2hXu4Bd)KA^hj3A6FUN6BtKAE&$he5hLFiZbiZhw7kk$+Ud2 zoMq<=byvvRB#>LfL2lKsd?C*YUSsgWo9X8ZdDovW{F#2j)753aS(>ORh;$b17X*n55*zjsReQ?Z2b?mHqml$T$=x9*0B5!-ml^M^95*aGP~=~ z7w$|y|NmzB`5&}@p;>+6|IaKx|9@wJv|~VfO+e`gx*iS`4=?_+!1pwO!igJXw=-mY zGq!Mgp=>nqg*nqt@ct5grk^jpL30c6cG(4RJM}dSq+Rx&<>!OfEclqh0+Ykgg zZyVIMbl>%F`b%S{pP(>*Xzm2Q{|hw6sKLna6FCm@K;i$G<>y1tx;f@_%NOM=J6}9^ z`T4>g+8(e6g}<8Ri~B4;U)**9ug7_DAGD7P)NWz<`Tsi0&lk>W6G3Y_|DT730cd?E zC=AZC{Cshl1=5zg&hqoYWtX21ue*TTa;F}H&N+4Z`4F`32V3};!@^(960~OY1!(^a zXdUu#7x3Dk|GQa!{@>5?^F_1j#Q&RFe*WJMwRs`QWfWYOCG-wT!Dkv?3*G9eot!)Oa*A!;@`F}Rc&;OwD%4U^`|0lEj z{68J)?#WPhgT@hOL)|@}<>!OhE>|3T|{yIp?1 zU&u&kl&Oh{*Pw)`9B`&w`i!};#q#aNQU|?o#p3)WS5^0 z(;_1;JTTcA1%>MJgI{VL8${=hs@s&FJ z&zIWJaW{STpRcstf4E0%h!xQU%Y4h`SP{n&lm5Zb5fx7Jg~Wf=Z-&L7{kZiE`Y}{(c6BY zHRy{$<4B)U94`=`RKbrmLYh|N}ufy4YzKUl5`LY`tp8f1UUv<0xeA$l_p5@T+tY(MI z)Bc8r=YLpu@=tu-3?0X8XaD(XGW*Y$(?Qt%=gZTKKVN{>?3{M|`Qkh@JdcCYD6}mN zT3a)jKzM@Ixq!m+Fyqfxv)O;XoDU7p!;U{6><7(xTZ6+h6cnBy^Ug!U6Es%v!rkpB z=&T0NIhUX{GoW!V@EFy0NATJi5Fb1a25Q4@X8frFYBz$~keeBQg6=&6t$P8D7ra={ z_!D%l!;967KQ%z(V4(9IK>K~cbIe&kUMvQ!HGu5>dAS_oKd?QE9e=(At#^Tqg+c8B zuXTXh175EJS~tVW@DXIsGtl@QXxs*L*2HGVpD!*m{wxOFu_^5g?i>A&XaD&>88t3n zf#OlwXd*Z+MILy!+3W$w+bO42?^7Xk1Q)#^rRRxb%m{Wib2CSLy6OUuJ`_ z`_GrN8GnM-)4T+&)0q#AOX%7h@R;;;$Dc3K3B+YTm;yRK0%RX}d>`a@MhEb@4WKmyptUogxC4iAyW>yL8X6EE9+%BX zaoG%w%XYAvKfVCn`&IAw^F=i@E~_2E^EQxkPqTi!C}sq=12ikMe!MJ4ipyfhpD#h{ zUXbIm89Mh4ipyr`+&gIf3@9$^8Gpj#5_A_7>fEI|GB*>){=LK1?T2W^ZTz`F}T_GJ88TUG8T8`D(lS&zHNA(&b`kx?Bz|vxE5|Wp+3} zqRd_oEweYX|9rKd{pZWWAngA0Wi%uBjD?rcj^K4aptcuioed~GfYW8T;>m@b;qACwLxnhpz}|lvQ!x3@;Or8I1i1>%h0%74b2`92ad~9P+Wq{P1uxz^{Cx460aE{h*1&-31XhQip!?8XJZ30P%9l+;}yl@7G9k|T)U|=wl zXJ8Qd->e9|^N;1{3uBj`FK#pZd|~eL^TmD8S{jz0|Mfw8qZB9pS7!P7UmaTBDnrX# zb(Wtmw4vp#KFiMs+AcpI>O;!gIMBH9ZHJ!^?>k^^Bd>tg7cW5TF0X^uY%~PD0H2HK z@bkrG2k@F6P}!Ho%MkM9JoxOa4WKg!U+iW8jl)6qMN32bwDK%JA4t3Wd?@eov&pz2 z2y|`-hXUvxb`GtH+x|@lo#FUmx5H1+`GufykEe$jej<;3JlGF9vlVg|@~c@4Q$Y7m zKLMR9Anp7UHukUqbbg62%g=}6pgvE6<%@pCoiD^)e!e&j(#x>r#c9yFYYLVx_*s6w z;CA`>Vl%_f7yO{J3mATa_Idqh2i05h6G3NL{Rf?81saR~4LU!?aN^7V%s*c+L&K4s z<>v!tm!A*WA>qga3P16&ll?%z~^a! z_K>}Rp0oA;IcPr#X#NChH)wCyYi3BF`#tl|2d|xfK70>4v&DGgThN}{)eb*F_giDN z`#d?LkC^3GrGUb( z7#e=XpzxEm1nq}=u^V(w73fZP=bta~L1(Wr{{-!$d*LiQ5p?F*|Mk!`wHg|Jp#5!| zp=oM6^UnvHoqs;u4oOoHpzzCf`1vp&d-#FIB0*{9^z;AIUo3X``2e(Dgn{FAHt4K` zbcdfW!E3HKUo){XOhirxps_*Fxkgh#bAHKCKO}?Zpk*yVXPv!R4BEHI@bkrT&{>{p!pta4#@gIdyb#4tUZ3dvqu{gpRc?*e!leQ0QJMSJ_Oxu;tsw;ZlaR{Be!K8ISh(`7quCWv*ut$bHtJd;~co9KJ>nRChXq>Kg_T&|L>$H|Rs% z06O0R<_2tYJjonCU!-Gk185yfvd7Pd=^iL^JdGeXfX)kMgt!5|Mi3ev;5CBg4v_Lf z9qII{GEc8q| zaG6}s{PRJz^UsI%ko@R;@Behron{X~=R#l`8@6|V)RE58mY_52!23n{86f*bg&BUr z_lq8unh4)33aXz$dqhEYL-&Y+?MB`s%4|GQ1!OnB!%xsXidgGN(B1RU^?Bev$ZUq6 zUjP1!gX+H*%~F=2{i)#nprCsV!kxiuf{PUqdBrF&}?tz^Lfh8>9YjB)xFFq(|`uVV$>F1+*rk{^N=LRq|OnT9d zbQVN66L`MuMZMF{m!LiV&^gWr&1MrHfcDk%K<@AR3Ql7tko7j%&9)B~n@)TX&h!&} z&hc^<#F`s_rk@{nF-&>n?*uyEap!}>CKDe-GyQyxEcV!V;)8gmpU;rRn2jfb=As@V zizypTe2~uc^Uf}YDG!&s?EG)f_Vd3p8+aYhgKVasu=^RV>|&VmHr(mwn`oz>uj8G5 zzDjob`7+(<=ZkEopHK3ge!kUa`}qd6hr^id=PPrzpD(T1e!j40`?-RlA?O9jJbSmF z51rk9KDzAo^YL}JpZVZAlIbS{=sv7s(73&!F3MErr>orFAtkce96uB^W|gXi7)vKYwT8wxZhWAF6yg*DU9&j0;Ept^ud zh#};KwbM@yPKJ*T%uu!G8PGm+=)HJhpmun<)6XZ`PCp;$JHf->>(&415B{_Me8|l9^TmJHpD#e?6tP=l{j}mM?y@{(J#iLj>9v{@WEi4+YvY_5U;L&j*L~CO(iyjT0|WoXA7t z^c&!mQAHHV&`Qkk*B#nT~d++-5;b+&Mpg2(g#R+WBxHDRu z7=zbgYy^jovC~h`T?n9aE40D=Fg;7~nx4z9kUiqpUBUB1u=PC;7VA!YAdKo}S&*BB zp>Ey|b@OhhoA-nEdmB%D3EJBUD$79YcTPjye4h2^gVU}*AD)M}`STr6`3c=Wj_zhq zyn)td+cW*l1=aJ`PVltE&B_q+KUvo@1Jsw>%=+`idROqg(TmNlKS6U?pmjN*bw3Z9 zbtXPwM|JzVoeWc6utVJrT9X6H1E4*OpgaKDUkD0s&>lmO+ZVI`e6bwr_SLLEA1rtM z`EWJF?MFav=XUz}kRLM-ys~!s=^@B4(UYMeNVAq}wx%e<#FyV0e}c}n0`(WbY4ATI zY8w0vJ{wsJbe2yuC=LF0{Q0Qd>F3k`jtF(kjH_;40WBdtP%K%y{@qk%t;)C0$el7s{`8L$gpmhwOcn7U(0L8mE)X)CVdHG=0 zpD)6p@gB|k^Fg@l&xg^Fcy|N&`M%@NhmSG+{19}$8z|j!GE4-`JAmRDUd}u=o(QUY zL1&0uss-&SVuY0C*ByWUKa8}-0W{|WTH|n@5x&OZ!DEey500by#|Gq|<52&|L*q~x z8i(po|A5v)fZ`Ck76KfH$ZH{*%_a(g{Bzpz=fm@u{y}j+GsOL%^b1?7@o_4{lm~~Q z{y6OT^Z#NE%NNqDKVOKu{(J%2V=e9a^TmEf@OlT(8i)sn)h9mKj_MCCkUv24NuWCE zHw&cv`wu#^(|F=bW~e{dq45Ge4-)JTVb-4y_+5WK6o$mhgWLb7KiKW~^WlC1{=l;4 zWIxCso1y;L3_2%P-SP!!UBqY5*+q;$Uwn7@37T8_|C;6Jf6zLH#cC5DEJyXnjU5bA zK<7Y%>sHX&PN4J!I^PMDzCdS?g36W0&~Yr#8iv;_ka8Sk9&}v)_@E!vZwoxZT_(7FYX-$3ga zKz`c|IwQ+?;>-O|zk$vYJr4ETX_lW4j=TJPc-jSAN0o#8Hres#!|9lQ1J&CaJfQn# zoqnREyTzsxLH+V7kUzSi{^$njSG5G6lfByI=L^vM5NKUPJLAv)i&=jDUk;i#SDE;r z9@QWDAb-?D{m~CiYoPTEAb)_?H-O@3Hq;-WwGWG-{s5T=JsTVpN3I}$G&}x$*bZ_B zYPpB(_J^Q$CNtxzM~h7-22}l@{-7G_{%Xgc|CLoNUv#tle9`Xm6EtV`0<;FAoDsa% z;eRt|4oP|9gM3u?+k@Pn4|RVw)cyI;yiyE}hjOU>9qf!{vaFbe$ZSQv$Ew2&^m@>=v-Mkbgm4#rU7(@=Yx1u z_w$3?9}jiEJJkK&Q1|;o-5(5fe>ls}7tv7n$Fux=5bg5wVLZhBPj4a3siCzSki#FA z2SD!EuLGU^4RwFC71yubXvIm=Jb93SX>xCj2I?!Uhs zH1+^>KWHo(ln+2-)1dUD4Ryah)cwXRKVO(b-EYnE^MSd`&xh6!_iqKcKiKi-L(o~` zc-#+4_n@(*N6JPM4^;l2{=ggRe$d(8hZQVe$g})>A?*SgW0!aN2|5G(zc9+6 z&xfC#!R1gW$of ztseoM0mb+eHm>_%vFyYL@~H0j2e}`#&mH7`(Ai(0@ZSw}Kj^*&Q2BEh>VD9D4yU2+ zKhOO0!D;8856?r~uL^R%vg6N(>X`W#-Te!>~erZrWAZz(zGxR6Tja4KmCEQ4^{iGoZAMpKW89^5Q>eyw`N%OVFJH zAU}fc8UXn*ADYHMV?!W6LdS-{encJ{YBrm=2joX)$Da?`G5u)Bz##JIvLn`d?f}RS zzZoEH!`}`+|38+pe31;gZ@~HI3(%Zevhz>SoFHiY1~g{$fLUtdgZHR@*b4FkXfHk} zoq@(~Kz;z-KLGLr=>7pvJo!V@Supd@7va!!7R~(gLAdkJhtZI9)(!H*XNR8;zk}wO z@YHjlaTicMr))HFTE+kA4_-sv{~9!wFKPM09&`_Z^H0z`Blxa@=M3Qc2mYHg|9tRR zV&a4QsP1nCx&J;i4&3)>-bJ%1eD4)M-`ak`_ZK&ICJN*2=Si&Y0dxXFE=~!Nb7sF2u76b^UH=Nm!y4uJM6K3FU^5j4jK8vBE}@$*)ODWJI=NShoQ7ohtH zKjjMuo>$9?a;IY+G7K9Kj^%7P+0`p7jzuz{?kl9A3*mJfy&XDAoovq`1ufY z7CD;xUnINz1dq3i&zIt4Xb5^K&$!b=9eSSv)^(&t6Txdq7n|Z-OL`i%AD$n&_5#aV zQm`8IwWQXN^`0;7-G9CW-DB3x@be{T-+MQ>??3Sc=nh-hTGD2RpD(N-YcIh2ok08H zjoBglh|EFjQr&;P0^NIN?*8*-J?PA9_Mb1^p=&Sd9ezHj2CcoYnE1HaY@*l}hAE&q z&==j%J>1YaCD0nP7w;K%zIa?@`7*f-v5xdT(th}2$ovJUZx7pd3!1BZ0vdaKkF+0t zGW*Z}pmm*(ttP_OAie^HVLWtQE@(~SWav7U>7aF>?mu5ncmD|vC(yZw_0X_vhOT4b zhOT4b=idod13K@l8@i4Kv<`JPWUc4R`R+eorZfC}k<9?UoAyOEG%S-L>q)@tSdtxn zzL-rQETb8Iz66D3Jj2gdi`jp^Tn-J(cn9#k@{b-{gTwOhW`-%CdksPMf!7{__9+E3 zfX^;^84j@%ytV{-<~nF>7`%q1+vz80-Vl7=Sv!OcKJP3T?B0(rVCRd2_Pc}Dkh+7) zDd<`xd!+R%&PaCHJAm)}1=-OFn!|?L0bV}}wFA6<)E!|5d@nU@|9w8gPxyZLboQVB zLF+k@;}A5z3W`HeT!P{-9U6z(p!J`ivj~vl&>I?u{?IsF3|&9EoDUI);m|mYX8-vr zAF{^tWwHCum!NastwC`BO7~#*PJ98n!x)wyKxe(@6Np1?kbcm5Z-$?*%GrOutcJ#+ zzQfN4+Mv5etiW*?1d2nDdDhVU09psE%m6;?;wAL{QE(iB?%o5>@j=&=fx=fFx*r}C zzVguh@SuC7L2EiecNT;8z=QU?gW?c$moRJ%Fh9dj(D)#D-6-_lb+8@$4nJRl?g)jg zCxhAnk3)Ir8YIx3d8i%mIE3xLhn}?$E9W>E8H8TQGwysL@3`}Yv#90&^-MostcL7I z2c3rvJ|`V|x5a~Gk%``xjY@TXWe+>%h{kk>qZk_g7y+F zhL+3AnSMT444Q+2)GNl=t+8KX7Xy$_NQ&-;t z8n-)O`(Sm0?SsXf;63Ub?2tJ%HIUyR^Y|aZ`4V(y1uMhGE+&SM|N5XYNl;&zbK-w( z(3(%qi7&Mof4%_UozxKY!k7`fKJlTkMr-V8q%GBAWZ z0Nqd7%r&u>5p>5OXpR;%KMpEC7=Fq#GW=Wt+7GJh3a%?bcN)LUcR<;zv=X%E7A(*C zx)&5ypuQC7%&=yTiT{P6VFl`Ei9_8l&G_?yxZ}@<(vYy)0CGQLLlCyGdKm8T^8x6d z(`K%TkAoe5J_!e{sg++f4YVG_p5bQ#6T_DO+@Nt*(E3S^iT~N5_OUbm1l{)puABH7 ze?H)L{P~a{V&9Z&|EE8&2epe);{_ZCoD3h|g6@kBhTLTdS~CIOA8QS{YvTkcEI{{C z{AYlS-7_(4H>P+5^y95e-F#iC{C0 z(aih~HS;&a&j;Tfem?x|@RMma!pz+uGmT+p)`QLb|DNIJe^B4ZnSJ8_*Pyi|oD*Sp zGlBgMy4(D{!_SAG9l+@_6y$ei`Bms?@V z_Zfb^Sj;x@|8=OJt~2}ut&;@%=|02H2heqnAiWA8KY{MiK+9(jogrz*gNfk+$3r(u z4n~H;7wq$;o;7n#d=l*V^J%!_Pf&aNF|+(CGtfE;P=5y0*GYD>eBsWp6TBu;o#AH& zD2*Lw`1v2a?vQQb|HDu>9cK9X;y45N+zil~#0SS6em*=63FqHeL3`)0q%n7gogNGf z=Gy=Ni@$US!P+zv0YvNhZ zn4vf{K0s?4L2E0a_ZPnenGag;xE^Z$W`>^+p!XSp%-;htUmVl#q{PQ1&>b6#8Gb$l z^>>(EEnmnp?0m7@;V0(3?fJV{TF{>@38X)8zc^%G;>XS6zur(ak%48 zP#nnDgT`8*Vbjm>^Z#UqpRoIm!R`RvEz}Qn$7F_|5BeQ`KAa3m7o{L~fa^TevIk#W zvzCMEN~nF!3_t&a`Uj7hC;kVWc?F6K(E7t>sC~$H8#i-Jj0D*SIu`~luK$;V*8ed4 ze9_E2@qaNiJ%jEWDuc56Q{EAi}`VFzLTDoSUz70+$M2n*a^xH zp!5woTN$*r0d5XRoioGEQw$6tptjEn7Fb<@WELY6!YpTooiCjoc49RPq|P2;76&%7 z8j;MhXW04D9*0>Vb=F8`v0`%<3&LI23_D+1<1mYn<>L!;gjpHb+{MU-Fw2}_=Sy>3 zX0d&IVT@!JGd6c|Aj~pm*!j{JmsuPiLH9?)!k&W(n^`;vv-BBuzSPHM7SG2Q+6Z@f zU^R;mVU{+-&X?M_%;Nj_LLFfiXgvg^{eYY%1Q2GaGwgh+j>{~8k1v!FW_iHdBFJV* zAk0!`*!fZ!mst{^bE)8I6|_eS(_IP(v*a0ezLdvhmcqvu(g=5PV0D)P!YpZqoiC+v znPu?tg*d{j6AW15k<|fVmN>)Cm*P0g0;v;*n8nS&Aku-wEY5}|@Y*MM{uXA~`BE5R zo&qDZoM>nYdd1A4#Q`cW7`a}*;76DX8XH6pJ5GjXRCDBkQaD?}-*c~qZKg@UW1vAG)(EWnXRx|v3yq@7F zXe{;Nc2Jvv;pfx+3_qV7X86en8q--1xlix)YKNb%_B;H1bJ*eM8_+&2bH<;qm^miC zVdh%(WA2c`ECU73GP2@dbnXhPJ0 z+5|7>JN$gT*x_duqr=Z^R)?Rj=X3siHJkJ219pdr3=Z5AA53TX2^wEiU(6Z0b51h1GY+nAU7SbW%g{bWpZt?Wpr$@Ww33rW$--$R>#566a*Ttec;SJ zv10?n6mVN=y~EF^(;a?3$@l#EINS5*BW8K6-8cSEf5^fvmLp9>fmwt)NqYJ)uJ zXZR@w+NZJJ;peN(4nJRRcli05nRC_adIs=bwb#sCt6n!V`~=-Gr^(3G4f7{xF9PV! zJn+5Mpgo!0ka&QN3qtlAaK1jp2@Q*Sho7&i9e%!S2H$xIKEqs_k?XbQ#;#dl`?5iH zaJ~lHmk$~%0);KtYb{oWiCm0auQ|7N&H~x@vY6o~Xx{?J{h+(=UVzTI1nmicj<hLq0k>j;jW%dv4+EcT2YPn{=On3bGD%tU; z7bDMVO-AlruR!O#gU)vct#vDB`1$nzfAJ^P;C)9II2eT|g6_dS0lG^IG?yOl_!D%0 zHHQOakI^H;hM>g^4MAlq|4n}Z@^iA|PtCUulU_M6y?-3~urLC5)CL_7Qh z->ujVO`o7M*g^Y7LHjtJ8Gk->cl`MPv`-A`x5La0L0>@r0^JSi%smmdukxY4qW%$U=i)02UOqe-Vy|QNbsinv;@s&NpPfbpTpRbrXSG|IcGj?%9)W5KH z_<53%;ew_k_r#aGIe)%nYY2L|pY!L--JU;R?f3lon%!X{`0NC8hM%vFbN+mJnDb`` zjFa44`z#`T7k5!n~Kx5V2gSzn(ce{Cr~V@DtQ8Wn=}7_c;7yDr^jDW(K7P zwpBu)@N$Qk_1fCu=PP^YJ(j%O-I|QtufgeGn*rjMM&609^%;J?+RXX$<#woh*K;EL zu$uGd%hjGgU#*9_-H~tNYtT8G=Q)4AJk9y@1q0OWAp5k@+^OyG^C@V2*4W`EvOAff zcVfR-@o)MIkUo7#9KBr3`SZnc&Yuq!d;Wa5-1Fzd>zqFyT;}}wb0))-7uP+1GJdSR z%=!J_bWm7<`VgS9CmA$1+z%-WKz$4F8u-I}C}T`d=Y!_K9Dcq8l{w7vt6qWTRi7~A zKd5f7eNf(D`=GeNR;!WWBNt0UkmA9vSuCs$KbaXp_ZzcM1eIkS*P&&ZI>S!}Mrc{4 z4&8f$W*6veV~{mXM5H1&gNj`TK$Syew8L8 z*REIh9e%#O4RRCjY7n36t;3|OOr0MZA5Toy{9AMRC9<3Np<~j*3_ov!%9ZsXe>(hp z1rlfE>IS(DG}izMhZoWgKSAz(_1xj-D{h9LPhUIyWMSm&e!|WGy2~6=#$1M$J=Yn) zbD$3{JN#_of{X)Mt@t6FAAQ}O z|I@LhW7M{a_Qeb?z;2QanMbz&>Jn1jm126V9m<%!kkVhu_Y%h1IZC{8R~$1vsfX{VpB z&O7~ldD-dblj}}D|LgPo{BO+j6C9R|pnb+XKmV)q{QR%Y^YgVb&(BxtJU?G*^Zb0F z&jUGc)|lt#1AU*L4~>0(J~H}{r>4Qvcs{!8=x{4dV~3D*Vk6Cdn{ zgc%1XWL!M}6t?@Fe!gUPn5el>W8%y2+z|Fb^@%TkL)j12CcgX+WizTxe96oMQKP6j z@g+Ny?Wi*GB{!6vs66o{Ka}05H1VY{l)X@K;!AO!pD(0&erkZ$$b;M^?ep`YywA@^ z><$y18Z;-0fYKf43{B8pox|EF<>t%xPCs9~2A!`5DvLmE14x@Qlc6Dqk@w`RhufKc zK4o{9xU@lY;$vgqpHIwvA^v7igU{bvg2p3vL&N4h_s{>IxglyC*`Tm_4rPPF<~8@v7w@?t zVFPm4d+(nQKYPQ&=IjMfo`jwsg%&msw>x3?yMij*@4rCfMC+k`Kg|8}|8c0_AIMC6 z0J;O0SzZg4E>5jwm;#!6f~Sl5P!MW^-wm*@0+1)kl(jM z*&x5~hO$9^-_QN?#bK!5LGC*2{qx~*gx~u>eqWE>@2@~-dP36$Y;VKM#Y{gL8985L zO%Dz#@G#j53X|o~FqzK%^Z#sUm^4UFd@vt1J+y+tWIj@QD2BQp6ei_RHYiN0p=?l? z)I-^zFlmOeL1EGkWrM<`8_EWSNk5bg3X{p)KVM9Th6%`B)4hK_oQ((*Pf(aF#~vo2 zbF5!2cKZ49wbRen+ns*CKFss;^>Q9?pGK3B>-EcSo}Vud`}_pW2Xd&oT5>STfye(l z7#K`IV=OPGGyMdgYYEynHJ#}v`2PCIOg}pq7`A}#>FsCwX$v~5^fhRH(qSS8quNAJ zT?*RYWC|0X?etSqkzwM?d?xT*1+47=PE(9(6G3vStPVdp8ChR*Y;2tcIurB7ai5={ zJ$EM<88(3X8O2OLUlj8~+WVmU>dSe5J}CD6`LNvgr&51o(4+4xJ0C;$WIU;7`Wd{yU3NaHcY^dkyP1B1?@7<*{rMuF_veFb-=7cjeSaQi zYY6gM_HX)2(7nIyPCp-ZgUXqPAf{T**(<*Mn+|R-^@GlW1MQUq-FeQi<$pH!&;R+* z^r9dI-hT&P=L0QUf35-D|BRGg+@Wy`N-y3}HYmOLL)oD85)5U7(n~m$4N5Q3P&O#N z#6#Jj^pXr^gVIYn_s34HD)I6Xu=fzO+?gT*_j?pIWWrw22bcrr9SSYt^KimI6D!5=jL?ep_R zFcYZ#1xXK}J$$hA06I?+Jw5az(!;f-(6nIf^z$WX-=DM7&qw_(JD+TarUh@@Y2oH9b zP7~@*;BzKX(uAW5W}484rU`Z|X~IzjGfhZ?@}SSp7xGAHf*Yxf0G$3b3xdkH1QeA2BnGbP&Oz{ z{D!hYY2rVW4N4Qt(6|Ss33ezOlqR^LY*3ou=l=OZ7@8(P?h^L?`A{5@CN`e~?d8Ls zCctfP2DOO~*&QY-HfT>gU)^g%PFW%T!hSbP?Q0c~ zXG7T_zt4xVL4IEhWrO^_9LfgyeKnK~^80!y8|3%RP&UZ#+qr(e*bVhN$X&a=em>lf z@Vf@c@9&{!$f31KUxM<=dr&>28Ba4lnn}pdMFzd4$V+DC>+|MY*09KbNzhL z4-E&9yZXI;KAemQhi7O1Pk-H}s%h`HnL|g1I%wwUWDXc>E% z@h9laMbQ37aJ`$%_49u^G`&0!ocLfhYI>Qr3e=xLN-y@%xCNybXDAz#UfiK*vFCM0$w=r5Dg%N-Sjt zD80N4_W21ub9AXAW_nnRlpbLB-_D1o2k70q;CdGn@1XS1s02?B;I-7vVnOJ(=*fIcNNNGYC8h@ZPAr57O(u6dW4N4R8P&Oz{C_~wxG@%Yn#e~=6G->>g4<%C`+L(F zf1;#`g^HMIq8OScys@N-g^HMIBA)T*3u_2cS6~q;Zd)l?+or=K_NJsGzpkb52BC>@}1PN)zv)Y*3o`3}u7T z#CIqglqP;d*`PG>AIb)$31*};!Or#b1vfNJfZWCH_46S=B25H<(u6zqGy!gJB`71> zV%Cg5ok4R0){c<2Q-jh(du09s#fjF}|4)Bvjn)o(0Bz4Xs7wTp!zrjv^veD}9kfpq zJcf9m^XLD^&^g-!yb~Xoqvj)fP?(t`*>>rgf*AKm8s`Qkn&q&)_5*L}~Q49l9qRuC9>o4nXq)W+3dmi;@HEp8bt}mK zlc8*o|EELQApg&XvO)fz4`qY=zZl8}`F}Z-4e~!|-U}2iApfuD{P|)t)c+uNZT9^6 za67{Phe3Nnjj{Xx!E?-ULU3Dtfg;534N4PFXF>Lqg5$oO^XLC=sNWg5Cq7U|jr#*2 zzk|+j1-ngS;>%>Hn?Zh0hq6I_&xW!=e$R)pL4GfWvO#_?hq6I_uZFTgey@kJL4I%M z{Q06C>UWU4+C6_h>_+>|?oK3FXE>O(Ak2j`&$8W6uHC{OGG`CSvR76Zw&Rj1INS%;;8ZN1oFE$Ql96Ax)bDgekdE{cVQ?S8{~IsC>!K=c_A)bGrkKmW5s{r-RrvELXP@5~^-gZ3N4;{84cqK>m5I-dwBzBfbN2a50QP&UZVyP<55 zpZ7!AAU_|5vO#`64rPPYCI`T0DQ4f6A4j-M~Cb3n>?kh`vX{Cs%Z175~=f&2{G zOHEFEGpJ3RlnEN+fckwk$It)kp?+6jLF~PT#&sZJ}tW8$te# zhq6KbPKL5U{!WLoLH^E$vO)gNhq6KbE{3u}{w{~ILH@4h`1zt9>Ti&{>OFowY)1H- z7vyiy-g7K*4)Qm8S_hSFvy1;vfAAUV-(ZfP|HGmFO<+XqPlx)K7vx{i{&ZM8>qFfJ z@~<(J4f3x!lnwH)HIxnVFX((zkY12~L1&SI*dYIc&Ljn~LH-4uBMM@J{0llyG#Kh% zkh`GgRf5ao2F-~VL3?#S!`5}6&V_>fi(amQ{0r8bpgi$b24uf`0%%NHo#W?!ZHT`g zJV%Y=3(FX$fbP17w_TW_{sH-!9m)pznH$Om`I#Te2KgCumOaQnAU}i7n+LH$eg>U8 z4`PG-3_2?w#0L3Und9dRb*P^~Zc_L7`A{1X$5TLl2JO$s6335l)!#_%w-u%Tr$2bi z@DuFs-|RpC|7ZXCV6h!yFF!P{CxQG8+RG1im&U}G*V!TI9OUoYP&UZl_n~Z%zaK-{ zAb*3-eFy0U`5SaLJBSVPH|UIZ5F6xg(7Ea$Hpt)K*?+$H%?>HgKyLc&{`28~cX)Xg z2J-h~>~W1A&)_&#P@VXInQ0ZcJa}Q>KY{$c9?Ay!doz>`^7nQq8{}`$T@WBYf&2}+uK~mc`5Sa^1BeasH|VYf z5F6z0)9gQAoQL`w!MOZYUe%Z_qtE zAiW@egYLosu|fWx4pjs4_iQK|uON* zHoCvTer-@f#P!K&(0xH5KY{!m4;2Ub8?<*ABo6X7=-wC*8|3e7s2Y&JLHmJ0;vjz)v;TZi4)r(4 zP37)CA66s$JqP4((An_B#y8mC(D+VJp136a|MUlkq5k$}|M}ma{pSN^%ZZ>f>yhVP zXMy~^AIaaK`=vl`1o>MV>UNO7LHALC#6kWB-5CX9gZvG;I|{@G`5UzVAH)Xv+a9VH zsfH|QRFP#A#x z4Z6=B#0L3Wn*HYsd8ogY*?&HecmMfN8R2gQkiT~m=WlRdtU(FV7l(~SEKr)p!?-P;vm0+?tcfdL4F6_0}o<@{QjQp=Znv5kTMhI%hKmVU*`}u&`bmD{MsBwOO3FwSJq&Qy; z^#{n`%b{$LzgI)qAb+oivO)gd3}u7-y&cL1`Fl5%4f6MXC>!MO!)!la9EbWFac)kl*W}Y>?lZp=^-f+o5cb-@Bn~ zkl*{+e!iFt^*hK-lihwkoR08&3drw^iHmb^xel(+p!N6yjfty4{m|LaI8SH$`9B*J z=SJXt63G5e0{MG7lE0myZUp(;9m)pz+Z)OT`P(1L2KhS}$_Dv69LfgyI~vLc`8yuU z2KhUg?dOYhsJ}sO0^L8FjqtY`$lsuIT(HDBIF7;ogqGtCniFLT{!a((`vA9Btl55o z&Z~Z~*kB@PKL)ZtH9-FCNAjmQ)J-6NN<-Nof67DIAb%=D*&u(aL)jpIYD3u|f9gZo zAb%P|*&u(Kv;BNw4fUrz+s_BqZa*K|BmDX17|7kk#V^?33~GommIURA450ojPDS)(!W>Y}_uYfc1o@jC$=}>;KVR@e{S9&xzuV7;!U%t_1Npm~1b>6p=fcV|2DOP_ zLH*8VsK252)<1ZxJMlq1s=wEO{9TU}-=K4wLGA^`H|XqU5F6z0<4`|={0+M29V8C& zH|Xwn5F6z0%TP5Se_w~PLH-7vXAM#Vif_<;@{d^|W%zT}pAR0p{(Sh{6<&rHfc)J| zg1?c=@C6zZw}bp$4fXeS)}Q}(gYI$GnfRa_)!%s_f0rZq8*~OV$c-R>gU*2lu|fU@ zodpeIgZvFT4;sV<`FkniDnh|4)BV4E1L>>rc>q*AJAnCq4k3`+?N|Fah}!v?mGd z4vmQ~)1ht!`7;~J2Kf_o{xe7o$e*Ayph0YqKSAd}gV-Q{g3f{lu|fU>-JK0$gZ$YH zH3#HR(EZxoP=EHb{(R8w`txBw!k<5mg4~VWpXlvyu)mShwSwwIdr>Y} z=Rt$mAb$r#^@98z4rPP<9nJdlMLg8s$*eyg#Jm1{n2hlEE|9;o$@F)F(nLm(zmuW< zhTeJoAX#JLgLu?*y#wU$cqD&=?wAI-9prCesCz;F7KgGy{+5QaLH-7vAq`Rw@;B%l zX%HLaZ_ruNAU4R~p!1|bY>>a9XG(+Dmm{Ak4I1Zd(41HU@;B%n94z$|dfNot9)-<~ zH7HHw0HyJ0sGr$ce}eAJe!#3g@j*DMpQ}NB4oC7c=zL|6`#^qv&H^dNL4JM>WrO_u z9?Ay!8FU9WNIl5UpnI`FY>=Np=TL*#AU}i7q6V=+er9I<`GOr9*W9c>AF#Xre8`Q6 zYkQENqe+Ns>Y}=P`rWAb*3-WCpQ8{yvQ4@8eK5$lstlut91-{s!HP4Pt}*eHp3-JvRc{`Q8(_j;C}pnI|(IIB#2;Ew9= z{|gzWfcK4o+z1*c?S{G$g@gV-Q{gU)pZu|e?-I@=k<2KjqFR4>Ti zi=k|gzn4SVAb+oB`3X8>8l1*Av;2Ip-sR`R%?N)VJ_0(E7rVb-Zg=_#+GEXF%Q+is zdI!xJ`!P&;;0*P5GvvCZZ_ruMAU4R~pu4p}Y>>a9_iKaw-Hvp>HZ*Uyg8c1_ z+uxwQ*Es!sKz$-3$lumbe}}XD1l@!EpjmO^19Mb=H-r2Qx~B;2E{%yVjiLSn`P&@I z2Kn0>$_DuxbT=zVJ;>kAP;rpILFY|_#6kY{hKhsy4LWxkBo6X-Fw4&u;m~v*&GPd> zxXaIn(TMnV2l?9?yT7s4VaQ`D2h=C}C;y-Rz!>UpZO9#m50n)qKF~+?w=2ls`bgy( z=xkBw?($0p zod=ET@6!tyro50x@;B%{JCL71{@x6AFUa4Zv!X%bAb*3-iw3bl{sx^H4Pt}*4LUa( z#0L5MI8-ml-=Mn%LE<2PL+=*^$1})Hmz{q;yzUGy$NNG42Hll~rOpPeuf-bA3aS%% zLGdgN_3v`#pP;+>9x%&Hd?1eM-+qvP#gY8m40R{SzwJ;q$iLlCHpsvIP&UZFpfjgI zegXLxbnY~W4e~GO>}e1iJ3A#t@!D6Y25BO329SHI_Xg@C4T^bW#hC}@X@;B(NFOWFM-|>Y}=TL*xfcy4pxQ(l11dj#8~G4UnnJZBIa zH}ILH+=pLxm;&;CqFcH7`C0X8iduobl(QXvUw9L3eH^GyZ&<&IrDX{6(_k zPtbb4m(V*^9voJi_`sbJz884je1<6x+7H=2$ZxWJ@K_aom%zhzCd9pJ){H-A&1aYb zI)~w5yVK4G%&HToA@h}0CQd@;J1bA@L*^$dP3%JEH!DtTL*_45nAikz2k6d%aL1po zKzEe4JMDbx?g-vr2RbVRcD9G&U&qN0y%~Q#zU}h!$$b~_nRYWkV`ct~KO0yWw*2R3 z`3brk;X$)JVqG2d%*#wr{DRiiJyxCg5>#g}t4@3gsxOpPCcXsUm8%TCEB9rx(!`gb z`x2TJC%y#L$%_>xzT{^43BG$5bk4mn%g+b=Ewx`4Z&* z^Pn@vRVTi@3_4?6W#Y^0pu78&C%y#LsUY`*>Qj*WL3Js}{m^@OUx3_?d=KwowTavy z_k-5AF{8Twp||7Dr^s$rM(p#n2Dw=q8s^8D!S^9NaF#`^XM?(#2jphZdNz=oS3}(l zs{cS?4yyZ{l_$Og)q5Z}gX%nxn?dy*$jyhDf4%_Sj{tJ>Y382~jywN+c-k2p=JyVQ z>TVoi9*rZ+oe}$ExIyk$hPr<-^UwdwnSVY|mO-pZgS!9DJW$;Y4RcW41xhoZdJE)! zP@M&GKd8O}xgS(lf!q(Or$FwX&;0WRsBQweA7uVw=bsOkL)^a({;6V+3{kT9Dg8_q2n;9#qeO z+zzT^KyC-sFCe#r>K2gOLG=pA?d8lrUxM6T&HVF4J@Zd+dI6bV@BH&&GsNxnAh(0o zhM~C~bk74ydTB=NMOhDWGe6YL(ab;p$AijX$%zlRQQh1Cax*tHyg_vV$jzX70OV#+ z9RPAO=xzg$n?ZLQfZQAmb#plL&lk~9H-pTNcK-P=9^&R8kem52(+h^17c0Q`&oqJD z%no(4IrGo|*33U29F_o$KmP=eMM1+k802PVsGC9MJIKwT`wT#C2Hj@>ax>^Y1CX0R zbtA~lpn4G$&c@6?UzkJP3^L!``R7Axh?`YGZU)^effmj$LFG!c#bd;tQxllje+S6Em)i`edypSv*>C!u;pdCPF5vqtRxmO^&il9z zx?h3yC-}Uf#|%GT$g}=@Anp3|p}Z?(|M7W7_i<-zBI zoyQ$6Po{zP0zu9t0i90*3l}F)xGV18n}ox1!4ozJ!cwqG4|-Y6_wKxdw!hl@EPT-JfY1e8`l^IMZa z_qsd$d}Qvp^NBZff7E>3VKRT(zv-_)`3f}m3Az`2xdY0cnBPzSO@EQ?@)LBP)(dtl zX{H@1Y(Qt0wj+fND1A7i?I8n+bwk4@8!c>{vFslMoqL)Ox&sZIW+3~=Kwf2%Bo$VG{uh8_?NfpgR?sQNw1-lYi46 zgW3tn3_l;5r2g5aP-z;4$syxc}21g3bzyclh}<*#X|3 z1C0-HgVy4tGeFvN!puMai!=Xxuvi>1E(|Sqzs_Np0y%ARTnKJ8F9f zrEXiSF!3R?>cmIR$`kK{))fRp-TR*D=l{=4KOZ!UA;xo|?mY=|FK9d$R3Bf4y7xNh z{CJg#FG2T}fZPkZuLR^?(0wH!_daKW)W@%xe!h6m1gVcf=D&CP`S7#TPf+`FHpso8 zaapu_0>!<_N)Y!xR-L#!4m6$#b?<4Wpa0J@{d|xtiWrB5x_2(fy`b~EK<-@+buZ|C z5>WVVXZraP;GyQzvEP@z6g}S#8`OBStK3olPuQSNKpm9(<;rlQdw4RJ{)uYF% z6Qe=t!5Zq`W~QJ2+nIhoP!>jvdqUmo3UV)K+!N&9bf|l?q3IzX8otF$Kf(Qxa;Bdz zLGG=Fy0@O`C-{61P}>q@ezVihhwTveii6w>8o$KjUQqsg*sM75(PD*(%AoKyhPpSN z>F57srk@X(g%IPFQ1?oL+zT471i9B4>RxxKd%dCV^@qAQ80y||sC%P9XIwzT7i50C z)6a*=5cj^`2O2NMpB|9I*9vWJ?LF0QMw_b<3^)}S4_ZcDO!eh`G zlu8pp_W*;_?Q76o1qu^ig6=N<%m^vRK<0mT{0Tbi0OZz8kXxnkr-Mh}e8#j2ly*yF zLHEl+-3z)$_cG}I3tq&y9MrwpAoqgCC;$x}_fK7SMiX z&^~5Rx&)cu?)dXzHze%d?FH=@kze&6%`Nb8t;6gWpVc$`eB8|N^ATt*PdDgnd4``) zCo}wfG97v*BIr!hZik<*L1)2EcKG>by2H;mpmX}ZGyHtT%r@}>GuJB6x&hc3y${nH zY#$_Jp3(cbyutQSaf9u{{07?x*$uX@vKf9ps6GHz`wDa}DD?bTFuNFJHs`8W<&g7i z!Dob4GyLRW)`zb(E0qk8Nl~HfX-WFvTO)?q|UI@nYkfo+2nuIUvoSBeAVsn z^GUG7&qwMGptH@v=lQ?UcKF%zvG(#CeTJXenK?gR%QHai6m!SCThsF&%#6Ix(p3Km=nUB<0nau#cp8|A7bdyy>&|$`gAg9UyroRG}E$j|I zLG%5v^F2XkgYwdgaE70m|No0Wgr@rk$Nx`9&lB+S0(`zV*TrY^8Gb%q%<%IOXie{G z&|Mu2Kc8-9`1xczB+b15_3t)A&Psg++A}E+-IwUVKJfvljA;j*0eirfk@bM>!|E2> z2jwlc44emS8F>%bG6^2AWfnbP`?$Ns_ECF_?Zf64+XwY6wh#J`fYl++&Ssyu6LhBS zYRDPlp!-6ec7x6nmS6SiIm6Fak3nS!$EsKTp!@<7=Unw_G9;fdGIDmmU}jwPVmiam zC+|IeK7Q>1K5zT}L1vG~*3TGrtZ`PSdz=bPmYKfz~o7emS$P-S6;fqPtZMOT(u`>bJudt2Jh>73<@jm)f|jmyFh0EzjzMuGpOtar`ddlp9er^ zd)I@`p@sV4G}LeB8GeGsTR`W*!p`s7$p7#V6=j~JOSnN^$tHdSsi}91l|9{=>Qp{(*}(Nf%7pWKJ-CjdJI1w9(VZp;IP9_Cg+Br zN9hbZLHXHl(!c31wHbHW% zo)|%Cmh<%sb%_5#{ec(C44|{o5odsd%z&K%E)G2dTpH;NaCvB0LC7&MJ?Yk-KVR8H&(UV&n)q56RHt$NeCdpI1~{nQEDv!L{0wj;G58ta@(w?r zK+k+eK3f}h2Dsp)f74%p?&Xt*)El64r9tfgFXS`8*hpgr{< z_v&+k&Pay%L7VgEOKs1euk@jAcjTJ*nxEn4E6~1qZ=^H8LH4mj+zxjqyTi|?pgM{l z`x)TRCqmuH4azs5x{>qe3w6$)50pKBK2-Po`7oUG=YwF*pFf&FV>ysBz&Rd3&j4?C z0N=HgbPRT0GHN*oFZ-Q^FTP+FoCwOx;Qe{G8Gb&x&+zl{V}_qko`cSvX88H=wZl(X z{(Tt?I%5#j#}%9i+WQ1M7dd(c!xYdxSnzX^l?5g~0JSBU<+UExGa}|gw=?_M2fJr^@t&OZ>NLYoMNWo^kCmN%K2di9&u=Ci_&*(V|F8lx!E~m0r=R;k>jXD5`~izkUfCn_kcG6Lc5T3(%faP#i$TUaofd`2uui`E-V#FK2`5Vfj_B z=7aJ#Bz=PFs~6knOa1R>{P}+}5qK;fBz7D+-ki^XI(MTifO!^CGsDjppz|Etk;;D17;`ccq+Tdz`1v9o zG;Zkh^I^IZWbWoWV!ZkEgn!dtPj~qF3bZ!87*g*)`tGpvNxuVR-liTp-V7ZVdJygO z^I^Obc;05ugn!dPZQmE5wn?+Y&j;C76FnDOWTaK@kiqe1;_fr&4JLH%t0 zi7&&Uc`%ys=Zko#JCYfHK8Sbx`7jyc4hfJuKx>oH-0_rI5MHJ{Oy-*i-rMfXKT##} z|MUmpP&arp{`?O*Z|X7U#Q*k;KmR*3{`~I_b%Q8uAU!75Vcl`MRv~B`)7K|{<&lln>KOZp5Pkiv2;U}z3_H8P|ln300Y#)4Xw0)o~ zHxYCe1!#=_;d!L?*nNhdpQbWQd34|5=fm@$_L%I%cgXx?nTfBE`OVT3pCR)XOHF)) z%s(tS@gB(D#|}SV{&x8J;=JQd(A_1V`-H&j&)$RDmd-z)Ja-1S&whZ$GCwo?bO4R< z8#Dj>Z_W%^Cj#oXg7#{$LE`7+RE8E30f!8EIsih zXr0JnDaabi!;%wU>NEd*Va)s!bcY>ioyY@Y=bsPFok3#)6X$}$9dw?Fvm#0x4z%Xs z#cxo#2|Xv4S$^W<#}M~|)@Z@jot*-?`#RL!uzA+Q;u9Z$`ou`?o(*#MWl-B)4l=(A zayMvx736Nv{3^)Zp!rphyFv4-Aa_IOSHbQ^o?m5_pO_DF_jOP{MRhma%|GieKSg$P zvJ8Ap&Rme2&qLk(nd#^M@1Xec{=YiaO8tP{7+^X!vm*BZonTapK zbF0!5UxMdWr6#_74Z7P~a^g$S{OV^WNLYi+{p|Gf;ddu+SUZ8-e4Ye1H%r6aTmW+O zaj2UwGyVL39pq+FaNh%zmSJvo1iASz)XkuIRZuvC=2b!A44PL3h4XRHoR8GRm#3j_ zKF{>?#bv0QLFQg|`uXrW#Lc20Hy_91=JyVeHDCIaQFG7c>2Q33BstsGC{d_nb z65cyOZU>!DfFnP?JkIeK3euOd$q~{DGYLh=wcij18I<$?y7}~CpX8HL- zp5^BQX_uc55 zhKb-cQm{TqHq*}+`Ak0_WIO$QnD6w{nWG_SHpqSN9e#rPAP>OnT{yd6u6F(jTPqa+ zN;}7$f4%_E4KaMoWo8Hgjd_C766hX|SErqSg65Gx_i?bWGJJfJ4h?5V?ujpyS$@6% z-SwxA6uxZ2yB4~^RoOi+V_fivIMnm&1=&lM-yO*IM2)X|U%DX?ef$YW1yC`lv zEIIL^v+TsRAU8%s-RR8p^S?W2O@|<2jSn=B{+SFK7lM|Fpt*Wb9tF+SgUT1sTs^3K zF^A?+Yp5GRcUm|@^C;L{r=JhqA$jxy$c^Cs5o+CoQkEpkOaz7FBWKx(cS0e1HNkbe zGSkoh>L7OtAlCLk-FXS*PSDyOP*{TI=RxiS&Ci3}DGV)3#G&q#hPqRp34EsmxQ+yw ztL*gip*qB!%Rue~t?5B4OOV6zVX_Rk9~T7*OK)gcGBf@B&kk}UKVm%()Qu}aZUl{s zg4_t2j|aK&J*ZtRGx6nT(A=%`#FyVebGK3xUxL;kfXci7j6Yv6L&FkeF0<3mhwKnH z)`Hv!TE~OtMwGB@mY(r<)dcliSs~xVr!^74>SG*jk!H=2A$K3+QtY4xf3*Q4RR-Fd<+zx>!I!htup|n zP0%_6kUK$Rb0Bx_2aVl9-Fckx=YzwJKOY{4xKk74PSCm?G7jSc29RfYK#sO##S_pm8{m8$si6AU8tC z;lSw0{m8$oW=hK6G^<4@2!1MnIH*uFq$d^3aG2-+72 zawBN01r&~;F&K~=L2C>^ZUn6{0J#yg#sK8Tdd8nGnxWy?4qEr&`12v?40LAsiPyJ+ z`nZ_o5OTVN$M<5XiH}1d`}n|NnaubTG!FE@nG3N-2kOq7lR$d`pkk zoVXL@PHAX(LdRwvICCP_=Rn=L9^_8YoB}93!TosIi7&zZc$tYWjiLF+9GcIq8GpV6 zxzipr4ghthJ1Ac|g70btxw9GMPH>+Vwak3+9aL{S{ColGt1>ct>;=_Wn`hC_Daqs1C`mwxDnU?axAsKX|{lS^46F`wTxHK4$p&=sCmB z$FD(ix(q)-`T50bho7K%y_d->KVPJS_FgN3&lZIBdo3n`^7kRz2hvTp4;Cv-1dacL z>h6cjk@~%-8Gf2fVwm#iv;%0IeCLD1@)He^`H$r$>LBx(61li>+NKBztR;CiF&gWHX^;JqQB zeLRQdC%y#j<9RGM@g-;<53?M2AJ2>3%;5d-FZMJ4e6ZX3=fnNZKOZ$KPW-e5be^Ka z&;QNJD1BAX{3fVP48L>mFvHKM&59Er8@v2`V(#)27camvfSb4gKCGLFJ?RZROIFA zetF*+>^2Q-Zd(p@+i~ZguVH&3teJnluxI}Hz}oreLwo0+O!*B#kJK4=MtA+2j_w|C z-)=j!Z#Nz4F6jQH2hedTP~XW16M%xFI zq3Ibk#s*5ypfNU3dIpWLfzq=&^UoLB(Dba&{PTgf^UsI+ko0_FGstYratgUjdU#lV zB6$9US#IK$AW)wN>K5o28n{eimYDdUxzYAPJJcfS{1EnkI_SJ0aQXe4>F59dOwjUMeBy)hM%xF~ zP`7}`yX3*+UEuQQGiYtJ+{BmPnSQ?b4Z4%EA?U?_rk@XfJNuAffYvG@y9MNqkIj&N zBsgxM<7r@bFpExn5Zq|{AROur(3ly>9iTBYkUKzQW*~P!$IQU)Kprz|R-7meatEld zh!!3war0OXo@R~X|4#>#qpgXc3F>`2b2i5DKbAdqh6Lh}> zIBc4QCqA%lw0&R?bq{DS1So7kdm%vX0gc&#+ymVU0S+7Fy%5cc6R&{W1L~uqg$;82 zJY6@~%TR8#eV`6? z3uqq(C`>^6FhF4f8pi>J3FxlRV5nQdnZWmLJ`9J%Q9sBnp#Csgn1IqPs#_RW!Q$vT zs10Ec4IAj53ve7c3r>6>-e~(k8tNX<7!AlhpfMVddq86}AooD`Q-I?Lc|S$7;>2u_ zd+Z5^4J=P@1C1kq&J_ZM4RlNf?3QMMi4V9NZ6EMM-2xhS0l5V&^}*4?202_{?f{j!lR<7VhlUF`)6f6>(0Bsv@%Z0h`+ynh7VvnA z{KS`_JslvofcA8N+yYwP!3~Wkex{!fxSf7J1l^(8tT<5>&%-VAWKAn(m+R-DKL zato;6j}|Ui-LhC=qA$oT`p|H>&G_^GeMV?q#5eK5^9I`ouc2-MjqiZm0vg`|g$rnW z2jrIPpnLfkA$^Jaj6WaTcKrG9z9YCUy1()N^auKw;qvmZ16VzHtp!qD@PJuvVw^Sf zj3Q9jK*w~zVbjbz@xko|+Xwfd?g5S4fZPKbw*k2aG;RZO4|LoH95%?~HqD9?cZ1vm zn*T-%8<2ZI^VAsbc`P^43gjMjX!tKTdcYww>(82}O zr$TlEsE_x}3bGymTqjjC{`_ALOE26LA8c>1eXtwq4$$}zD1JcWL!kHpjSqp`0b0WY zx~C2_E?v*~^Fg&EXl))iy##~Y0a_P;<_?rR4Xpz}c{)A-vMvDZ7U*~oI82(kCO%l* zVEbS_)GeSfACOx>V?H3afW~}4Zh?;Zfa3;v%%@p#q5;S)ps^G*w_wdj%yJWLKyDF- zrW5G;9I#ssb549PzrpswVyIid<2dpYUxL=@fZPIFrvq{ebe#^^Ey(M1niVJVg4`mG zC7qzPFG1~>M~CGnN`l-1ItK}qR*V^c{x^rl5i{q+2a_9YA54e3MH!k_)S=}IXbcME z7JbH_FN~pS#hmfy17pXZ56vNI<<$nzUM?ctvRGl_H~;_BLFX@l<4BtECuqG0I9x#E zKJ5**54xdl0gdy3;s`X(0}2<=I1k7z;*39ENJHHs&-n9!wByf*@({Ni2f2kG(=DL2 zgrKns@EQ!*co%4$#eJmlE_S5xE@tp}*98to?up>D7(jDA`7A#lWV`%)nD6pa2|DM) z(Ee}wOJ>j-56GMkc)aUAmhrCpknuL~c-MXCco%f73fS+>>=PeUH`qR?hx#3~b_3*h z(3%dA-+wdwd-NeWe!i-9`1!is;pdxfho5hLGyHu0pW)|I zXVAVZR`9+o2gU=oj;sf46AEYux@>m+!<)>-s`t+Hr?t&(7ats-xO ztpaC*t%BqMusZNQqQeZ}`s6`;gYARp2HOYW4Yn^q>ngJueljwG*3Gc40?o}mIq&fE z@o9&j51d&ig7!r9Zv8*~1vA5{7sU)e8yF$`D8T!)Kzoy*YcfImWF9UD?L*{19jgNQ zD;v5_Z8gJBj)M-CFPPaZ!E5ZZA#w8xWDYaes#nnrKVQa!)`&sE1hhvAw6EX=XkURp z!_Qa23_o9nGyFWk`(ryu|Eq9^pRYmtpg?v6JN(oXJT;kv6_g&be{g){S_R%`<_=n~ z%CYK|H^Wa3UWSh^)aOfSGBSL830kYc*eS)q!C($H%iZDUYj202FF!METDj`Mr;OT@ zvwdngXLB&}bZ6Fb&gT1DbD96+$;mI6`BuGT=3n)ek$?3WM!sEZ8TnWDF!JrnX5@YC z#mMvPwK>DjSJn(aU)nQ(_h*63egT^Auy*+Q%HHAUYtWu0b%vj>v>ATB1nmnj#_lc+ zCaAlh`;9<2f_?LUxM}lR6_P0yaes(0ekwE`uu*J0Xrm|U@ble%hM(`2Gfq7CvESxh zI^)CxANy@|MHznT2r~TC=4JS)#mVqfgB6n29)a8e+KF1-%Og|rAXZrc%Hq+0i_nCe^d(89`WXA($4y^~znSOFGG)#K&n(61m$4)I_>oHCHTw$r=KsDYfWVMc;4p0uoEU)2SJs&5)59?3!FH#gFE2a&d{OSY6TF6ulVRdhX5ER87rXv^ zvfLHChAbU4j=G=eCj)2=*?*Rw|Cw2TK5$l__+UN6T^!Igeil8TH7ia(UoO_3_!4y9 z@nNlrFF|J=Kh~W15_HZnv*yH?pfiq@H736N&GPfbf0mysKy4zBdH-F0K4fn>owU0?Tq`h(S&etUS?=_hiygW?l5x8MK@kHt_oZfE)Ve>Z3?qUyv4^HJS+qnlyM zi}_GDg3c2Lxe;`hFvyLoS$@6*xp6(q&zB%KZf5!UVms80AoI4n{Cv0@;>L9#H!jBF z#_MQqe5?tdZx9E$aW>SAvsr%rpAT9;qB8NpbW}I42f1-N)Q#;dKVO2}2s%R< z$sjj^&Q1ooaXQP-7qg*m1erJ6<>$ls5I44h+&CN4jW4e|{RE{GQ2nQQ(82PhH0#b6 z@~k`mH)~ryc&s_`|6(o6hs?SYKW+Ozy@MUJKY~MxgXiQd4p1G$!14OUWTu}SZy7$m z;$jGSIoauF275yg6C>yAN9{}~@$>Mo7I@4`A2jFO4fS_D%g_JKEI%JOD^GmTjOy<~ zkiVOu{sx_k4DvVVOk|M1LFXZZ{0%w_8RYM3mY*-`q5cM$SMT!kVKc^-%XEv;6!In$H8BQ&5fSK2MPQs-f-!okt9EUoa@|Xij_?4oy4J z(6kfJ^7BP9)O}#{Tz)=GhqzB3 zz48Ay>(Bq7dpDZ(C;tD;`t$#H)}OBqYfXIhnf2$Z$C?vgf$r+~&H59(59dGY&sV=) zf4=vnVMDef_r%xtS%1D}YY2M%nDwW2Z$r@Q)7(3~85)9KpXc5QR>R0Q@%3xg zpWRFiL9gGl{(QyF_VXn_2)q3Rt%Z64S_c*E^z%iy6DS-fzVK%P?fHMr#mo@$(%wMmclCO&4?otWFnFy#fvyl|$UPr&VrY)cMShQb%(^QB(2v+R7)oNf7X zah4?qqh@vjBSXlGc9)$U3=C$VFnVDRiF;6;3u3>pcLJYb@&uF~+Ff>f@Ilo5PiFi1 zKb`I8%Vfie|Ml5^{x@cWgrPngBuqi~wi5SE~`TR>r{&GhpX=uV(3XUb6}!ff4)?P*a;3pd8eN*mBD+6UiUIEguHm}^z(%@(@$kkxV?t36+moxuzNqg z5C@&N;`H-{Fw;*C<{#T%2|N9K;q3a8qcZEq3((rHcvtYg;g|eKc5plWe8~^7qZ7#v zP`mX7)DCu#9l{7Zo`d2a)Q*#8`uRc{5|@Px3?iVo{%_9q^S?D(9D?!#C=NmS0ThSk z&^WYa`}xY;?dMBtq&Sp@#-Thk4xOQK=#CVJ>d-jUX8ZZdp6%yL(49!mZa-f#GyMeZ z#d*o>^z#L1?-eV<#25b=5&7Z2$Kh+npYS+* z&G-`>hmR3bQpPj$Ldqp}UQoF-AsbZ2x3fXY z_-?kJucov8d^sD0-G0LM%Dz18`18eaaQsbtu^$rm;4*%{-tGAF!FEuZHU_8ZFYOFdUVzLy&WKsYr!!-g@#)TpGJZWHxPAwh z@u0o9>m9-8{ea8(bZ0~v|D5gTf6(1}_{#X_(6D^X_Vd+qx1TRxBZcKyLLF* z_XNTcv?dW0ma`duzWUDg^W|@7Sk89*`2ak=Yz7X?g`ltmnYSDomY^~ow7wBk#!rUW z2`(S{9e=)@49UCjGQJzBeCURj5B=b{|M&uQZc)1rjBj>Cl<}Z7h_Eug9?6bs z$Dc3jA$Gvahi;_up&MF0G$ZVQmk-^HKVNi1;u2oQ?`He?A9PP3avY+U@w=gMxS#Fk ztKDutU+zbW!{yL8Tn&xGXlNY9BgNrnXdG?_)%|QgUmgcxx1TSI8GpV2t+_0A{Q06B z?B0nl@*#c&=ZAd9pDzv*h(pl+Sx_8iGyZ&an(Zg({z!0}C)@GogLKEAkCaWpacBUF zLy&pp&^QE@@$rm5UxLc`WQd*MIE;7v`7#+2zVJAVMvB8|XdK3a-TU!HI3xJ{?H9q& zGCmloj0dmZgqHFCNOpKT{(R{Vu>&55(MWL^4UNNKgdOlW1ntWOo$CoYe`__!4Ae5d z{oj9a(EbACzA>o3BxTAlP}$@dExB%^ChVL&dB-Nmw_Qf znwdf5RkqX5m(CFXyf9`2w>?4oGr?n{pt%58{bdg^M-kLkbawm+)>rNNlY^1#H5V(x zM-GOEmq6!?=rJ&eJO=IOw0HdZ+Su{u8)wI#@5~*4a&R;Rb+R`Ey=CUqTF=P%k>ewH zym8ejUYE-!R8P#}_{hBKoZ|UeAUQ9?PB6`3*f(n}Bg4lGhK^Z1tPCGP=O8&Sa<5`! z+viJhF#Mau0qPI7&zI6-VED+v*eUfuAGEKM!5k#_LZ9*HD`&@_ zud|(gzR-94`Lf#eCuo1a7s%aj9VUU?4VMRvyCTWIQfK_B#mm+0$>;#;<4n|i>oCca zk>TeH&|HMN&CU*(;#>5+#n9A$@Sr8p+BH|EIqIg}u7#&zJIy zpt9}b3uRCkGkoj&2%PV=upD)B6e|muS zfU3Jf%a!aO9;~3X+nN(SK;t#atUp0+W2(&jfn0Zk=3+L2)&UDc>uh$GpZ~c*{WAH9 z5BO2*?6shL#Sg8sLFe6r`kSEh?m=}n=)8MSo&6tle!K?wy!#jI(0&=nJa(6#54j=z zvgTEwxf#ql8=Nk=U4Oo0XZ*>*$?)+7H(EF_L&Jd^l1@SUSza(R{(KEehwP3&Uoty_ z#{@y~@(N^5yz9>#R)&w7l{r5=Ss8x9#560je|T~-fXA9Z>qK9I?g|rT|M?$uZ!S_> z;We}7#MhwyAgC`W%ns?lh_nBECG7t5rMNq&{{m?z{D+o{%_1;gv;TZ455n$0UxLob{?7o}7y2JOHazjgcLqe;_q)T-7t-$F{MZRPF9KU% z5VW@zR4#r7`HB7KOLcZgU+}ZT&j;@vem;6^4lWm8wK7Zrt#JmO-wo~y9?nGc1+O#i zd~rC_^5x?UL|^c_Bch$~9I}55+)e!Ie4u_rHZ&~r*?+#ucK`V@A1N%u*&%(wXm&_na5pq8_rt=Hf8y(8c1T|^o&D#l zV)mae%R$)v=gZrWvz}hwcK8XNTLbkYt|Nuzb%&oXiV1|}dC>U}Za-gMX88H4n*Ar} z9&&IUbJ^kNgYynQA1$^5hvjroSc1&E&j4w2vAh0!aU8VQ+4bkk(-1qsbqwgdhSQ+A z9Hf54VFpA$;xGfGA8{NU_a9$?&NbTa06yCY+)mgH+M^B1^I1P$Y-afRQXN{yY)7&K zdS*9hA0xbuIn03QM;wNpVYC}z2fU6s3_5=a5|{9Hf<61s|De0Gk=qHNxC6x@C@w*9 zXb+7;XZD}3?A?F9bViCpZD<_oL*pY*uiV*xzVrrR_n)w{R$%9< zfX~2M4)H6vov<8qwi|&soDYq|#h^2X*nhqZhUSOGko|#=oGrm|s0NBdka_E&aj5M2 z6EvUklHC=2mJ296!Ep#W2WvK398N}x!^zM%oDL0N&|F8q1Ndxja2$fx39Ccnu$kfK zOKxZ!wnO{{wgWW((+;r%9*2{W;&3uF4!aR{z~c~fra9<*a?ttrk3nWIe0*_yzLW<8 zgPA613_u#(wwU+=bY9y;#*exz3?ctv_kt{zoA>}U?+TjpgZ9mg+Zd+2sCIz#%|Q2n zfXeyXpta_j6JLVv0RffspnE_-b|UCLQ_vm;*jxrH z$lajx+CXy|pu0an?gric0ji%s_gsP84Z7nBlA&=9+D`xqJJ9_k zps)koPXY=%(ETJJ_f2O0`C>ZMeIWCuJO6w*8{)nmko&-Aouh^wXq*u=?#L*>5Q6O1 z2h5N-hRvIN0_l&3h9~T9EM@75pmS}I-P;9nZ#2}sp#23P_k#8pfZPkZg9PMW&>bWo z_d@Tr0;kb>=ARF$oqs;8hqyNZY#(NLVvFmCh7404ghSmH&;0X$GHCt0)I`wTo5*fU z2DvR5>Ne2bA|SVc?iK;L4Rp5%$Zepzyg+V?X8!pi9vYS)^WvRg=ps^Q0ko){G!w#08k;aVR?O;$FkAs!rBdBk3^Ur^A z&=~c@#jZaeEqDD1nm>Exz%b>3I`hwm+RQ&+C`VdC$D)H?^fT;a0hMK!ognKZ`Wbe< z0L|z2JM4VftZn&%jbRIT-c=jqSKWy(H~oj49eCR5CpYLUzH--}ugh6~axpUe(jL+ zz69-G0EG$o4hT)i86}`F`Ooz81v4~EK;|(!|9r>}2@^k1n1I$fq2*Qhx&~*_=Tm3KpU*&R>OlQGZ$`xW27gBIeo0V%c?r75teoxVi)yx? z515T6!uIqzgWSGcAF_@?x!LxCvf)HfIrPvS>8>?(#-H{r3{xJuJMDa=?)dY8v%y4b zWPY;#L~~?*v))8wWd35^iTcR=!#WeSk@=6cC#oa!nYAY>BlDHDCdz}{3A!iE8Z?Fh zS?>gDTY=`*IC)RbdI{=7GcsJzd5$g`|MqRK6D1HdoY@KVHwCRjz9l9TcWH1`7g}+^S?Oj&j-os zhNa+$+qj`_ z<7fT(LKx~ckbThmik>hVO?>3+_Vcm3+s{1kx=hBO46F=WKlx%O&^^x}cU=d~H)~IPc^fp}tUd81Xzd0l z%%JNxz;{W4?0fF=^Wkey|KDh0Gbqf&F~baWA0TKP1vEayT+2E8F*_qlygx|RpZKs@ zZ=w}wUY8r{pWQ4!|L+IgcdY`NI|r}1;eh(55#%4xc~Bt#OlSG|66BxRERZw+y2lyh zAJCc$kbgjHE^h8YzECiXo2s_ez6;R$1ljf-7Y^L?uYotALJiyEdBwd zd2L7V`XSI-1<;*XFux(EXK=n%)|$uy^4EU`NIdnk{QN%|x-Q{6s7{mDg89oEh;V&kXWcJ=9;#(0Br^;{e4|H_Oi#{ZM~_ z?CW>=`EWACUy>ky{Ri!PM@`!(ZeOfB@!@0biI0>GCq7QrpLpco|LG4tL;V0-yYN_X z;)D07evktB;XTw3pt*dIA3*mmgZu!xa~b3Z(0$7wKY-UZ=uCVGUfZAzUE82N@g;a| zgVw~C(6tTVw1%>_!D!-(r6BiU`r+Yk(D?$0Jo4bN_QXtmhAE)4!oc~&oaN_#YtT5D z!o&y9QQiI;bhhkssM|qvRv@>7=Bz+&muC6-66AK!oyj1#gYHWPg}*v9{I#LsuMbUE z#w$W_}JO)=M#6gpWw6u4u7qQM_v9;2c2gI zc0V`E&;R_O^*r(u!F$F*{X1yB*bQ<&=p0i}z5v~a401o{E@Y7VLH8ho+z%Sx1GyhG zz6WwYXnYS;HiE|YK>30h>V9^XpD(zf?g!b&?eg;>Kg9i=Aoo8ecJucZ1vyI{yyjeo#LTeETSMnh?0I*B)im-=e7%_Mr#EPw!*aHtuRwD(huMCKba;$?iT>!EgRMzW(F zY6oa8w%zULi*C1{ukN$`eDN4z$7%+K5YSlq3xCI-Aa@&q*FP|bJl*W@^TB<$pAR3q z{ZvA-a}UVQ^`LeMXbm{SmKQMlmqYDejbwj4)c$6+pRelOe!ggS`}yiT+s_x55%$CV zxEeH`==SsBWw)PBNcJrN*|!{G9|t374g(U-pnE()?qvgoGw5Eq{gClkm_J_Z2d9aR zpmjYS>I`O&*d4*=X`+@DS`)$Z<%^+t3^rZ?I`?NjY98Cv$S?(bwlFA+13&^ZX8JO&=m(1DI;Xit0z9?#H*j%R3r&vgKeXMoFRl<^Fsi49BsPY11! zM{hrY(&0mAx1WzdW!z%jiC;kD7@)ffKy8?I=AZw&LE{+G6CX@Rb$1KM-P56EGwA#Q zkh?+S1E8`2G(G@wH)wnS}~A1WJy+9azUDQiuPbN)a5!DMK-!|p3xEIIK(KdSpfK<)>f zUkeI%P+uJ6eo$W=#`8%6=${Bv5lx_LYd|wRC_mI6f*vd9(_Mb20*)hwuVuzm(q}_i$ly^rd+ZKV` z1v(P~RJNrMI*I>HW=vaOuqC%kOScKG=~+5P83b$67qtrcWvI;5<5 z!OXA)eBK<${&=YU$w>BNE8B$Gf4&e$*bgt;k{y0N5O)9hP~07*Y|8}M7Z0%yqiic@ z_z5rD%8|-8(7E8{AU%+|Z_t=F69a?DkAMHgAG4$O3qfsA@P21yt%-)9ImT#ce$!|E z`QI2iCK8UC-zq@mEok2bD8GTmL_qlsG$sPdZ=f*|P<{iAiGcDO`1}VQ$Qi4k{02V% zK^t<$Dk#5!#;o+AChBQIH=%=K`Sl;h{F@yndv%G_&@^X*vv3K;w>Jw_j)a z`TsWP4ojpvA)#)U0J$A}hMeKVm!P{KL2d`#1qpIH=nMr=_=C<+0J$A>h61R(1D#n4 z3jfofee&89U!Diu!KXFx=O8n(DXlw)$ z{#p}1IYRc!gWbQH>F59TpgR|l?udlC{{<*bgU^;TocI!SwkOE_pmPpD?gyQ70CGR* zoCA>iL3c%h+z&d}6y$!;xu&4<8gxbjDE)x$i(CzLKghn-PCp;6hq!+m$o-%__Gn>` zT;DuU)|&Y6unxE_ea`Ry^as|^^k2{P^M5nw%u*r5osm%Y?*O?UvfCY_e0Msc#tfJxI+@^{tl4)!ROH#PJ9VEBLL)n&=~TXB>dj5AqoY%tjN#K<)?a zS4VUI3uZ{$7}W0K;9)RBX}28KnRv_-baounAL>j$|7(Np2|>DB66%jIkUzj@))`I& zt%n7VReE{b| zXgq-IQ+N9LP#Y2tDj9f8hL1jWN`&{=5u6JLVva0Iy@bWQ-s{m()Bd37ef1f3HAiU-j8TTncJ z&Wr@P|2yN)7rz-H`50v1Z^xex|AWp*Gn)8iA$05+&HeL0_j;k1LyL7MmS{6fc_0l9 zf7qRlptBc2`~8sm#NX-|rhx9@0go4g&t5bD-%SD@F9hx32e}`#9uwq#&>ntJJ^Y?|5W3ns@}{e$akxH1~tXI8nkM)F(cyGx350Xsry? z{jhTxA9Ew_q=bh5F_8N~=d**tA9P_PdU9ds6*-bB#dAumDh2d!rWxgT_1 zBgp-rwUHqAgU$v3xgUC7BiQ{Y=QSEloC0z`=#ENs_ZvI@L~*~f0eqj)UyvSdhM%B& zG5%MB&Q|1__<$X?9-anrKWLvI$o-&w@F4et_Q8YP584M03V+ZVK9Kv9q3I_bv>#l1 z;!DsTevtb?d-y@_hpsgQyB}m&~BNpfN1a8NRTy z_PAMoz5tDR9F_y0rw1FCkF8^v@__x2?SuD?whtc5!q16*=#O;P-fD)Qk#!7H9{M}( zd<5zXGRsbUu$kd!2(p;64ETI(e`GOd>4~5_guIZ&lBFg-*w66O6Coo?Z=FuMNGk^flAZ|L;L}zKBhH0J>8Ulpmq@gbIPu!(xY@FCT->Y6aEv zvf%ptrLxS#m!PwqoTVXmTqjFG+C0sYkaO4dq5wacKZ2fK||1DriLJea_Ai!lO2A7?neXd;{e?a1lk)5I-?rYuYS?a@bhIi z!%t3zhnGNOA55V2l=|-Aq4U?1$d93^ISe)6a*8A>laz6rRnP;R$vx z=-dZn_db@L7yxo_HPpS(v!Wh67M=)N-vOGt;()q$63D&f(D(8{=nQp`d%^82 z>4`7F?JOzCc~T(vg4hI zGQZsE=fi499Lj^j1bi+WYMwxGue0>ThsjbCA2mx(e9SC6@zf7U-=qPwzZlj&TP%n; z#~SKp1(2ITeG`zILG3Y+n?da{kefm6F_4=LG3Y+n?da{kei|HF>pL0x5p04 zP5d+;WItv+g8HzaFbAEdh@4j*g33~6##I|YVeJhKYkj7l|BXTY5&^{7)=+nUs$rM{ zx$ ztdD@)4L&~%HLS6@^^vpm#0z$ieh4_6q31z8NajbJaSe6vF_3#f{SZ(%zX#o`EDJe< z8{}Tl-YAfJL1#vR+zUE03glkUnNcA3LeGo>hcoh-QHSLw&H%X=)bD6Ub?>8i)UpVa zHb85MBS7H`yQ}^=EPjJxaYK<)?iFF@`GwF^P+2ek`9?gyQ{1ad#9T?leNs9gwhKd4;@ za{p|`pP>CVVE2Q}pYQnd;bKU53xM1Y>QA7%KivUb_TkEh=Rk9d%FuiWJ)h~pW27^( zq2Vq7ayO`70dhB}{ReV4sQm|WH>mvwayO{`2XZ&4{ReV4=nN;2yP;<|f!&RKhSOoW ziI3(%`w?jFMouTNG6R$k-`PUWa02H;=v`_LKxZbw`Vmm~KB4c zg3eF^xfirA1LR)No)M6HL1%u0+#3wqUjj|n(TqPIgggFx7!3*MZ6No8`VDCAebEl8 zj~G6J`k(N%QtHsPQlRsFK<9#}gX%JepD)4pQ%hTFFfnX-aNXf2$bXLx%S}|V_&@#S zWrv+Ft~=~RS(BuUv?fWJVdqQGdS_+mnxxwfKRwtOwmj~3K&jUrf!dv)+d$_Zf!qc<{|MwZ(E5Fl+n7Q9EXj$W{R=NaZsUgB>jicj z^1WV%Uf3ey`U1a`Y)rp$b3{zf#_8Q-J`uV?}_2>U))}JpAYft=N z&HD3IHS5op^{kM&&}P=3uj*ZYzHD{{&4oht&!<^s=!g3d(5u9vBPfAepsfTucov9d^wvHyl3L^Z>OIR&pZ8m0BX-G zYfqe83A)48=_klO@Scg+koAY4wX6p~^PwO<^c?v!EYP_+cITfjjx+r%0PWd%?etSa zkzwMC-Jr7(9Dcss&jgtpJ(5uqS%1D*&5AjH zaMsf!k*o?(3+ns(sSnvAt;bvEqd4+tK zTQ(!yvH<25XxM0?yJa;rT-GDG#UJXHVAh|n{9S*(2zLGX3Up4-Vk~Z1@AUJ*eAl0# zwWP@NsXj2btVXzngAp1}%#e5j&pSZbpf#8;pyBo6IOv=prk@y=L=Sb ztuK~4{p?_1*a}{^xfpUr0%#8V#bTzPFBUufe6gA3=l|_2KVNKi`T1ft)6W;%U4Fip z&-C;EYL=h>*F)DTp`Ec3R>d&o1?b+V-%dYYI%`gR30kj|tTFK=XuVRi`ox!@^-7D? zCcXr%S30aZ@#S)spD$KJ_g8_;Txf&2nmlLYb$ zXiXBxFU>4JU$jI00y4AR<>$k0m!Ci9{Ga}y+v(@Sey5-4etGiS>E|PN*Po9;{%BSQ zk2Qhz(=7#!Z#F~y(d_i|e>Tg{7x^qdUu3)dd;uDt&Ub-~Q8P3If&BqnqXar%r5x2C zA3=G)9LXP`bx0t8fYu>_{1MLb^Cie1pmj(fe?ZqEf!CQMtwTBv@<+AP&xfEhR?y-E z#UG2+;QlBE`J))>56~GV?kqoFc!SP5aRHwR{KDG>e8&_h{=ojQXZiWxndRpLXT^yR z(oy}fALNg8B!7U`Ac6b=T7v}g2k49ykUz{p`|wpKzO-if`NAF=A0RXBU4A}vcKJCK z^cbP=6#l{rs=Y^7Dl{Xg|Np&ljM(devRP=gGkRA~R zWrc|k!cqOv3-Sl(%wbr%VrTjJ666nV(3>i7!Ft2!Q+nT9XBe4{?^CFQlRV0GSEB zFDx1459s~C=>EXSBgq=zI05Ameo!6>hWaJg>F59d%s*c+gU-Zq{`tZiv^Ln~C+Hj( zxL>|A|NQ?Ov`#^O;sbY7zeIuj0y?J!<`>X@8jxR}Gyi-EiWAU!ERbJ7>#;z7`3$Px zp=*ypW`1}6`S7>%PXmx&yq$hN^vBF2Aa{Vrw4nD_f$M5}Q2FBY6Es)y!WeRf+W*U} zKmT86{rS>aZ{q*ctUv#sXZ`s)S!3es)2u&VooD^|@-p-soa?MVUtMdzPIbK4|O*)CLCc$+AZ}3r8AK&V#}fbe0SF{1ni+EueY~ zq>hil3>3bgwixLA8_;`|&_$wt&u3v3L6kIv)mfh79Oj zm=}<9UnYXikAb&~K=*H3!`Fym4^PmT04O}!nSQ{GPZdzu zf!YJ#8GkB**uTO1)IPrW%=q)gXV94rj6XF%=i$6}{0TN6e12ut571dFFNL9d=w2h) z^W5?0%hwQlz1=@qljTD!!p?TvyD`YS0V`$!Z4$B+-6JLL4h3sYh z&HD2d=zJ*9Sx&-kKS6V5p!>%_=fk{!oc}WM#chaR!Fl7hx@5N ziL?EDDUB4D*ByU8xa|1zk+c59CuIy%UVzMd3^^|WoHzJgf4(@)2);y|7<#S`*OOIH0v7 zxuErhzny+AW^nkqgave_rsl+lNM(G`Y|wojjF5KFX2+lZq3c6m+y>pP$@ufdednJq z)BM2krTjo%mombPob_Z^=VY9$D^)Xa|AUsA^1n30|YBJ`r?(C%F9p zUZbiy@#T5upD!*$%XpBPmz{q;yzcyS`z+A;gN{ERu6M-R4tk;Q^b<5+02-rdVsQA` z%mV7)YD@%;$E9b3*4IJ(v)B>5KM{1N(u?iRKVM8|{P|+H^UoKvk^Hls`RD)5pmn!0 z6CX@Q_0L+6eBuvjR>#-5h@%C%>p>{0TY_5FY1?)h0eXtU57a=Ktvr>Y-s%@A&gS zbYJ6($<9AtfaVaVJO2coSpq8a!Ep_}lj*@?>4^{WQNtz;6gK%tVFOxI2nrj}nnF<6 zfYua(>T~ekO4W(5yPCjlMWnl$Y(QaC?D+FxIcC^^{08?!v--q`&YBY+EmoTt?Dl{9 zgKVfjvK@c^&xhQv^djH+=Zj>hop=ASRpp>Yf{Gu`>;!))iDTp)iWL+++SZ)3sB)_As` zptIwU+a0e!ZH{L3iQsleJhW_0X8ZXn-tFhhWTdjy8(L5LL(gVf46P@Z!|F-CiLb+< zXEQ~!{d@&FpAK|xT(;ZKm!NZ8Ky%9Bjz3>SgUgSJ;4@tqq3aDn=end5C|f~ecc8M> zpYi7_&{=fFNM)h;tYEoe<|PI3u0U%^82b z0F8B;gU%y^h9~F@8CZB4gUWvb;Rzbg1BEB(jF#hUKVL%Eri0rZ`i?&zXoKeOO($A{ z!V_d3X#d>*|Ki}f>a)vF(3vTqvv6OkL&^hi9ir^`6SNlt-=VI+G%d!~fJ<<09(&^Q68PLxNgtK^||l{ms4 zcwGg$4-j;Ii#;Q1yQ7=!=l_1xxCFN$L3snz?&yZbWk1``SKV$uU-l#AjdEyQRzu_R zH#Bejhvg0aiLaZXaoNuH^VMXwpD#gYmrZvApS=P)cjYC!Aa}sy@;w8h4f&n{(uVvDUI+j2#cPJ2pgR#? zJZFHkAwlPrfX3=zZOHo!KVN=#ft;)O7&3ngwgxDY)}ODHGc8{^XIQ>=*06k~tclpO ze463si|;Ow^Fly-X!k?+&>n{FSw0TkvwR-pmWCkE{YX1X8K%774LSqd;pf}K4nN-< zcli1Gw8PI==N-Uqdr|H9^Sv-D#(rg(TZ2LFtakkQ!khW$e}CqmFT9<9g3cy+;qUwt zwD;o$v%D6#zH~;~gT5X*<_~Qf%>w0P&^>Ih{x4`BI;frj?L!CEm!P%pp!yQD_8rug zz_Aa#U4iSFo_uX8rk^ISUb%%vy-B1l@}c3d`vX zkp17YplKOL+i)Y(DHme?@q89(AkBzq4nc^wx6#+XZwN9+n9T6=CFl&3 z$>4N8@kKWzkATYn(0L}WA?3LzY_Ab|82~!x1XKpJGyHr7I>+xjQW?-HrmiLZK9!P+Qjog!;^pF zYh&n{HsCWF=s zfzDWF`1uNSR*pYpe*?IFOn3PCAQ`mB!E$0DC_F*t6+^-k)ZPG>si6BKK;=q2#9nZj z1Uf$hydEE^UmlKBriMey)M#)T`1m52;pdBBho3L}p=B!QehK6<)t%udyk8EwQ-TrN z{|Bw__J+(!!0X3wq%t)eTBbtpMgZ9ZFH^%Ae!d8I_z8+rlzurs`_KQvsBwwXFXxBG zr7-)?SN!fjUkW3|X&OXK>FpNb1GnAtnKjgr9LE#;q{|BQe3J-<5C;!=8rFw8GgP{2HjZ!jZ4rR zJ7_LX7}_rvXF&AJLFX^P>=AeP`BEBU4?Hf_k>XMv8kh12d*E@Y&hQg-R|hCAUzCIH z)?(NSst;cXL-OzoP`^!>;pYp`JsIlEKmUXFQ>Z)t1l^DGLfiT03w{RBd>Eu|K|bdK zHfIa1TbM!Z3U&uXzZ0;pfZa4nIM6 zV7*9p-1&4nsGAB4Wi;c@7x9ojBB;;!Al~uk!(>pKn`h#5P&k0@4n8b|GN1Hfx5H0HR)&vHn0Y2X zYIgkjxZUyR17+@sRSFDKKyt9PjVqZMLO^#)KV{~b2y@dzke`?tS1oY@jcq{P70mea zKd5h(%r)^pXiWsjUH*(eL47lD`5w;r^FgrV&xhd8W=GBAid-tF)c zWal$xo{3MI9e+M;cl-&nv--yW=?|7e?R01S`QMxI=L=@8iT|A$f4&6S3F>FLL&L(G z@#h0~$Da>D{W)fyi6J06mt)!q@-HJR!^DTP8GeGox6pU7cis=zP>wDuDePfzDN z`~=-&09qRZ3lGp(jpYQ;SPj%&)}Zq(7=ON4%sCNsFBaHc(0&#;EbJM7KCpKD`OqE` z7J49eEyi@$ya||#8^wn{ztG~&^y&%Jm#1Px@QaQH&8!F z85-s&_oDMm{5}<=7t^j6haJFY0fFY?Ux?3_%HU!!Lr!C$vzo#ABa2td?*d^^Hq>L`Z3+{ za5m^H0n|JYCeJYCK{qrmxfy?g)|k9d=9u`O9h%128GnNMSzvqk8Gk;c^!jwNi5oBW^tpdD)0e}=XZk`e7hHLC=^3+r`ZI^TB_IpAVTK zb}aze)sAV`D^Q;R6ut}%lm0{RTYTBfH}U^v#-IPMGyZ&inepc<(E7aFjF59N?=${< z1wGFk+`e?=p7?q{BjhZ{!;Fw~F}s-|Ydrdyp=~C&O?IP&x z^?HV%FFapX`SD-c*XilIU z)COhz`SLp>c#X$H&>h#spmQ;KCq8E8nW$0-Iqwc+A83sSs5}LwEv|zOmR_t3g|Ect zOTD_!03N47nIF23)DF#t)M4N-&Sv=e0@MaeXZZOB)DFGxu=50{9eUW|=WEb8kDxGh zX8QRbwB9vYU?S*_&;PE}y#Cqz3`p9vDC#!Qeo zg=`i`nC7!U!<2vGYilORoPs^m&sU(ewEj##U-~=2?+<$!@9-0JZx}dCqmjZCwC2#; z34GQl&M*btGX@INaL}D&Og~?SGeN>M+~MbgV27WNk_EwGdcJ^R3V01;GPLaiy0;zV zchFsG-q7}oKg4cuTNHF28L0io2yKgk&hT_+_^ApBzn?GM8Gb5(*r0YK==?BeP&>@w z=L>s=pB|t&BGB4bm>sY_zBy7G2HHjg+XY&8YK_!}f!YP0C%O+hUlQ7ev4^%{oEd&T zh0PPWGyDXt3kI$EE(OgKA?Fiurl0>oYlE@HsW=lPpGY(Pd?oJm^QAOWoc@O9lmCp6 zIAw;$DLYb}vP0vPo9X8((7I#Lyr(i~9+%TpD#gi3c7m@w1!z58mH=@eZvkvA06fg$7vKOPC@1wL*o>*9|TlJfZ|jd8mICQ zyTRcs?eOy@s2zwLr{YL)Dh`cPP;kRP<3@{9 zacH{~6sO|QIOPY2(MM356CS7H3_n48zd&&cTE7pQFIvIOUxb=cQU#Tl=`4`;X?}z4gU77!_45y>Gr;dVQ!Hed^1$8U=ZonMJD>PF z{CsrV;pgM~pu6lCgm#1GUV@?Fx1HhV|J|VSo^|4X&>6RnStq{S%m5xs0+*+|8Gb(4 z?(p*=s7-g6ZQ|$2u(khODD6?u{_2N^*(PRy)JPC_{J)&x=Sz_Nps^s(-Fl!fU(fLK!D@$} z4?*KqhuJ1x2H9^9>Jy;a4_On>Hu3Roho4XGgZAsNg6H5~+e7x^g4-PP8Gil;-3xh` zW#a$YP`hSB?$rbPbuq)w2lE|%K3ojScWe`Pfb6oywCiCwX#G9HE^s^RG3&%5M*pWj z0No!A^4DaBpZ}+W(k08p|NT(AKxflVhQvMStlI~Z9ezHX4zX)4$S&~x(5U`;747iz zb+`jKjey#S;P$99q@DO*pYi8wZN{Ik^cjD?G={bX%o%^aGIsp=(%cbLZ$Zw75Qmm= z($F%_nh8>G*)xIatqb7!1!YD^y`>I1r=9WVOVB!LchGzw5oMgSBdp%K06zQ18rl}H zXZ-of+VSTrP#Fh0M-NoSf#z=fp=|+J8Ml~Y;^V_?6BYA8>qJ0hDYT3O)rla#6I;gR zgZlr_GOifH2G?8o$~c%Eq?U0|yTJ7p)GqM)20UdPXe}eCtqhtA2lbO4MLYb&mX-?5 zKxGs(f3`FH{ND}gd$UaZ4{DQv@<%hnPtYDVaGLFA`1zpS;pf9{NIK#Mr6Xp{G%NG} zzxe-ZhM)gIZM((H6aSY((>Nj&;Rooe!g7HG7*&iUrlEKpXUrdmuWs|PQu~m%lQtF zw8bIuAoJWIY4ZiBEd*M7 z%m`WkuffP*_Wv-mB`AC!K*R8Fb;Qa)`Qa=7JF`tZz#M-KrU%q!0L_^@GD6QEZDzIv z#m9qUho7MKF@`=!+v4L|E{2eYpgT{!9e(nG)=KC@;_W3fhZd+$3%*wtl-EFGJ>Yv> z9e%!2cKG=kdf(~`afY9-r5S#{g0>U5*cn2efZ7S(4&Zgtnyd~#UkWq)1l>{O!N_od z1GLvNo8jjP@Lk6YKObZ}{Ct@2@beIVW6)#9hM=Pv|E9l^b^wnVf!i9DSwA=!IlD9% z8MgjsX14sF&Hx@8eVFd>6T?p+d*vN|YW}Rh%*F6;k`^P^>zCXN;Blstpm{uL2k`oJ zP&*kW{sOd50n{#GX7~v@w-j{G@+)>wK8M6TxSWCd{ow!q;^6#on91^gJi||L{S=Ss z4zQYLCd>cf4B$32C_kdR^?x(##XtEXEB{uDt^}Ry@X#J~mo7BDH#7YF586-qn0X>7 z?qAh2{CwHW0Cqd*Y@Juov&Fp`87^dl(t9>Ez2`Ih%ob`4di|IIlHQ*)K+-#-=)~9M z3_r6$>Aji(ybtyzC=X3{`1#V9;pYobdNp?V3A(!%6gDrQN8`1wHH;pZb~=85}q8K%4dnP(17 z@7AF99S9?(cZ@g=UHK>H&>+qNI0>I6>2=435u_yc`T6ptarLyP%=> z1HS}~$x1u?d?oMj^A%`JQW)Cy6=wk7+t9_r5b^|cCapD6nr25!)4|X*jTGlfB9JsK z07}y!{h)Nk?*N{o1f@?+My}VOvCu|P+Juzx6G41XntTCDkDzmGg(3Hoyo9>-DyZKA zO0VJ$KfM?lf;4$g%>tE8p!HDTyTY8AEdTp6{Cwc;@Dr4;|5l@h!+&Nb%m3~SKOZY#nfO8;a)0teb%vjhv>ARr)@S(n#F*jdLr{7F?VkgUQ$yQ!513gd zJ^+OoblkHaRKCeO{A7?kV9UVRVEaIsc_QdecF?}yhw6xSWp^IKln49{pt0ngPsAO5 zK5BOO`M4d@u2cn$b4o+&t$2o?|C2%Y8!%1$51Ri_W}f&m8g%9`q|ADe%<%I;JZP;H zq70h0cJ9mQY<%ZfD%W_ldGjhIu#mo=_ax+K{wC4w0mocN|dtqq47YE%D?(p-WxWmsya*aWU85@Fx z(*I3=3Ci=#koE#6!@o(Oyb3yZ5#1dx*umu!IRD@M|6g2zp&Y+Rya!*<_}l&p~@praS!v?fZDy@AUJfu=39r;>tfC z2s=z#hL zCx;Bf$F-ocs@&-($3%vYy3l<$;QNU3q4!~eoF4qB- z6NSmeiooT->*(^Ce)7TORLwu0Wq|DSIRVuNY8!*jtOW1J%ZIGz=3s0HdXdlc^9AUh z!)(wRet9j>K1xuT{~{ft26R6Yi2VX|mlkNx0<-xbPHell<}Y z?vH&D%ml9MH5DOc`zlcV6YTU8be2MA4ae*kpm<{B>;~;k@POU>c%BW?rn=1b^TB!O zIh0zBLCnkzK^zJVK~I@EwDQvaO$Ut|{y)z4^Z#kKpD&orCjJMXN6Pl|#c?*U+g_Yz z`}yFw+s}um5pL(6@PGOXko}T3R)uy${$=j3?WZIcVMzN1flrXmQvBqy7JPUWA4)w!o zwx17{yZwB)+U=(kTAVS0;!NG?=l}U^KmRXg`}yLq$;AJlHCVIRe!iFwb=zXLpAY7{ z{d~9>;kJ1ow}I>j#hE_S&l{jPGk5y=A4{Bp?;8cF^Je-v3#9I`@x%wxko_$W?OEXC zKMQj}XD>PZd|~gh6Fr}R@`x2EJe8S#9^hoy^1qzz=l^Q9pD&t?C;kWB!TZ>F;>%*T zpD)UxZU&uwU+(tvVKu_dh5i4hgY#B4+t2^`Y(HNp8&3q^L!8d`^F=mPUq0K<2ia~v zALb+UC4>A5iU-hn4xo4t2dzhk>^lL+18DCAdRpQ~iidb;JS4OId=T&U^I%7vWI1MYH{U5bpN#VKl;RHXyfw><5LfI5ZxV zal}Kn)6WcUhOH0VG1KgW$Ho(7L1%GuL&Mjb?dN}gP#76a{13Vx7ZkqkY(HOkL*3%f z_VaHI$n?Bpm2ik5wAL=9g^rY|q^cNueLE*~|4PR~?;rsvp1r9^$ ziJ(0#Q49WFwx17#-F`k4N9fxK@(U=OLFcA{ z!Wp_}22>`3(=lkD3wkacJ6JNe({rTcE)NS8ce?Iu^`t#v;S9sl;3=8k)tUv$12JI!*pZFiNckD6i&lk_3 z`d+jCeDK`$=fl?seW4&ffx;Vf4hbl{?}OHOLe>F;!~3=)W}SN-DZFp9Lh9W6tUn*z zcK!MAzAHxgJrNY%*ByVt_T;@t)|&|0kN5IC>(3XLp>Dg*`t!kM*PjosBiyD3avR8g zPmhWB&q;r+xNOa42LSa;(8-Oza2&HD4jeyE=gv;KUr-}UFi!w5h9 z?1kow&8$EFZ)g4aB3XCh|MjdtUqbhzgWFEqS${s*?E3TJc7(pyz0i6Vbgm32o=$`A zU`C23(0$D4`Qk8=|CdAkznT@k*B-r|RR_h>VaK2U=d=F&5897@SZCt@*^qMtUd)I3 zX)!B&Pdcn!cLd}%ko}-|It`7d%h==T1+)CB7oal+ok9Eh9e=)n?vLt{W(WbrA-pZO zobl(2$uKuF{(Lc=_2+}hu0J16cl~+DxH0HaJo8TExO=*p@#pvCf74$s2i*_s`14V` z^G=X?Pd7XMeA&(V^F=@F&j;PEKOgqH{#?x55cDSb-}Hy)9WmNPpuUuU-2dqhwnO8% znf2%YcGjOS9&1kood@v}RL9h_{(R944Ucx#pAVW{e?DwS#8m?}npg3gV2(X2i3 ze=+ONm&L3sbgG%QY>S%3ZqogwmAb0X-jotO3?bD;X%LFbCN{(R_;(8mk%Hz-a(=LdoE-DJm~ zp#56#I04;-jh^qik>bQ0>VIq2pAXDke?GLvj1x~#oOC<>{IAdY^S?33J(?5$YqS0Y z-Qn{>AL=$^)}IgbU4K3_M!4-+&;RK!K=y;;WHK~Prelwj7rUYR9`-Z-R0NHmfyzse zKG1ndAb)|@DKN8bjF`Al%amiX8id= zo%QDfW!Ik%)m?uknKlMJy3d4~Pm39U@+SYA{-)XS=j(XKpRbY~f4)q2{P`l=@#mxa zPCK6#JN|58W%$@#!#&%Jk-Pg9=pJ!t)}JrrS${r|cK!KK-u0(5b3@Rdq<_;NlsiJs zz{FBsAGUz(g9Eq2q4yTONYddoN%-Le8BGd^C34PP8vaR0!lBSHHe^a1>JQW4hdIqeHxA>4+n$8a{{X3gkAB{h)Y{hNc(L9ziVqAyE8#Ffu^g^c?CYq&ttAOi}aj z3|M>+%ESK9Jba(!=YP?usFHQ z^7H?7kiXR?{s-ONbe`qsi_1`b*I9l(xa{)t;dO*Q8IZq0aRQnn1;q*It_gRfIB~}k zC(cN5avbXa(=0z99C!Ko@HA$eM1bPN*%5qi)BnRPKVKYHo%nw@%g>j)S$@9Q4|UsN zmY)yyyZn537~!_B-Jp6Mnm4_napI374>v>AwKM({2K7;^G5biMb_%E;Y6_ZTw1cR+!{dOheY7pS|ov;2Ip+2!ZM?Fe_B?}n!To9A_pP)O};pHXhzI62R(ikbMXG6n!KFiMs zvt52ZoR1mSe-r;re`yTb+sg9u|8!6~P?`9@pXKLE==m<-Hq>;MpAROx{Cqea;kH>I zw}I>jrGIN^SleR{>zB<=pmDENT8xnSGSI%J*UTKNUQ09n1k>`2KVK;`{(QyEu?lpL zI_SPP(7Mvs(vCmh$b;tQA^Y@RXgmIVtMB;pEok2uGvm)U?2JEOgYE!lW%&4tpYi8Q z&>Br=oYtJw*>w)O!tht`AN42U_!@9=S0 zNIq?ch8@y*GfkF_L7?+nH-N(IyTi{{puK6o9l-N1AV0y}09qgV;y-Ba$MNS&VaK1Z z#T|dX2Cdb3&hYcqYlfd%f2%KhF*;0o^_~GdxA^ii!%q$-hOIB2JN!Jscw;+AFX+6{ zSDzhzzJBfS^9{S>&$rx;Ki^6-{(K|P`13U=tU%|SLD%1I1Jyy0yTLym6lVwlnbRSD zV>{^lPV{jVP@C*k^#AFgJD)mP5)^Fgu8&xhp*eY~JF11dXiGeE|- zKEX!)(m->(BD@MKIJY;VeHN1iSov7>;nu;Vx)- z;m-2&Kj=&!W~GUsvwL1Tv;2JF4%O$)^7Dba%g=}22z^^YegK8~%zRp%HPKlT{*&hld9Sp`~0q0Pws`qg%ZpP;=E zpu3Y44Ip#5FV-{s1dThtSnu%j1!ylHBj@WZF@_La`AH0vpO!=8TbE820_KiV@k>-Bh$N!rS$`7D9ZuBw`RL5*Hh3q*1*D=SLfBpyEr_L-l@jvKn6HuHT zX8!r&IMjcqnSVYw?)>xNX@vipU~#sa`RD)rpm33$2)aA{<#y(upz}$GTR z%s>CH2A%OGJMlmGY!l|6FP207w3_+ngXPXYAFf8Y%@^c0ko};zsE5WGXm16!I3uQx zDTd~W*~~xx&j*E(%*6koyVpSBJDvIGi`h`O%xC`jV7Bwmhw~9`(Sn6hzI5iF50agKK1@gGTLcPAP(1rX;~BJ<7rJK`9M7P&h3I_`ccgd@hsJX>^Unw2 z&OaYUW5)BnxPQ}Mx;uc+2>2fi@|V=a|De0-yqSN#@Q1oBnEB@ef9IbMgAs142DuGn zKPVshL*p5A?-aTD$Qc^G(DMjhJeHjJA9R-VFK5OQm56qo^KD0*Y^8)z+6u$P*@CB{ggziBBhc9Sd z8hZGeGyK#5-Iobk^Qa9CUw!7E544?sKGeqy-!@SAg4Sy*GynXr4vKq;iT~x9f4-Dw z{`o=~>Na)epAVFse?C-4xJ?=4Hjw?G@U@4AFX)VSEa3~Drv~l+{#kz+yk?YE@h-J{|~*>gPHl~ga1xHA2MTxxh5#gl^uTm|IYOD|8J(BFPgIqZC?p9Rs-yWIrg(wV`3IkGu<*Ul^z;8?rk^hki%kUG&-U^*)6W<8p?-MG^z*@er=JfW zJHgvoQ$cID#ubjz}K0vgVvexTzsI<^z)%H)6YldOg|rk z&f2tR`uWruysm213wMZ};ISER$l0TyHAxRa^IM>ENv%O^&p3X*5a;;$fZ2W`Y|R;G z3d58K+(&F5d~UXVplk;@%iJHa&g79c(@(Y(&|OL{J0EE~{e0kTJCO;QpKLSnUow(> zv-QMZ$o$1t6Tczz4_i+Bgv@_zG4UNTpV?yKt7L{LFU---0tfNIYXKqalQ~!!%wTt^ zJ~(VP@qsdAjSL4z1Na=Cn;-JNKVK%>Onmv6?dQv8>xnNx z=f5nrn)niQKFeXti7!ECv^=($_!4xc3bVz;m*3fbzWB}d6TFV?Kikg-zukU5{O|Vj z5wrcom2Lm0gVxi5!uvlvXzdjb%G#^{m)U-T)}lRVHifU>fw^rH$ZgV2KVO2}2EOOo zcH+zJP`8237z4QtbOsp6ZQwOwmJ?rs&g}xZ?KIoZmms%6?>+{*?K<1f2bbM`KD_Ss z^9i&4#7B?ae?ETh{?i?_j#QrM=L66^GOO8sg4R(za5kCvKpZu!`atdh?VAL-ryCkp zp!2anVFfzB3gjNp8CD?ofYv*K!fHNf{e{KEmy4n9S z71#EE`U82VpV-3bkvZi4mZ!}26CXcz|M}#(`%h3h6fXze%?5RQGuzMq?QB0EFdI*N zz>n(oc#zxqp<$T}bvx)hI*{8zXVQV(p3nC4CCKfdwND_omqXoN4Rt%{{?%rv+d=j; zyZwCF4sp9a$nC<|-Tu(r=_iW2oo(Ug8BYi4eyEeUSUv zq3#ErH|uOW@g?ZYS&;idXT*Zs4_Z?Ma=$m|zH-ZnFa4qJ2d#MmrG;>|pD&`J?g!Zu z?e_CwJjDI~TS4b+V0ZtE3NqhW!A@A|?l`_ZA7wR0~_Bv?%1b$cTf6$o~9zP$dd;C1q))1u3 z)DQ%^YkXfK!xYf^6Y#oYMu$(JJyYQI^6V@-U$DFEe8I_J_F^@X+uk!n+~#Zxaoc+L zpD*7--S(M)+q5};zR<_ww$Gq*?>v4!)JJvObdcNLgZd$$y%0!ld(XV{#e3(S;Bv>9 z?I-9A;s?zJ6Cb>Wp797RcXlT+OnLFz5t6q-=gorR6LdZ-C_X`JmO$|-4^5BC(D($c ztpeq3ZD@MbXZ!iW7#g4Eh;>?^a;Li$f4PH_9+Pb*K2)}Yr^!#CwD6n}QXX)#{ru0* z_Va^N1k6C~If6n^z z0khu32e(n(9|dwh=)43_d3G4;{^P8Wvi~&H{h+hAL3!#j=w1!Wi7!ECbc5mmbcQy_ z{r5p@5?CQ+KggcPu0J0>cLkUIT3~lzcRzCZ`(UvZIP5|5V8z}4r$4w3b^C7Cpa1u> z{(Nv)XX1m)sBYH=x&1OU>_KZ@K_DQ+|FzPce@M7?dPFxpUnF6KWGh1v-ZRXr%~Ph2b6a}XBdOR z9kk8_{Y{pZX5(DLFif%3wbEtt#u1j`NMV@{4a>z=kg$w)|M_w?G%P`9HG}pMI&x2ZfvsM!=J@%-9!prR zcl`Ol+T-U#d(^PB0EOjhEM;#x^UfFP&O13|8Hzx4g$FBx`3q|#H~K@}c-Ru+Mtk?4 zFXuzuxELJYkh|ouxzU;9=L>f%Zd~m6^MSL+&xh`)ZsZ5K5w!jYJ-+>!cfRmPxbX!y z=)4?6o95wSD@Yn}ww-9C47x{z5mF9A*8x3X)|?1hSA?7fG(c%!ItPP7PkhjiS{D2Sg;PJ&?Y~)mz67P;|DZc1Y$m=0tzQATogM0SZm8SA zYho-Wz7&SKU7Ypj3u$Qj1=#~#cLPelCqZtXjNR?TI0;%&JgYNRMocQuN%g>jf{Pr3&r(-ekC3M{j zIINM^y)fHPoC|UfX~VKSAqC9yqH`1f8XgoHiDM+*=QI z?`o)fL2D{N?TpQ!J3Fi=zT6IVFKGP-sE*zbb?;%QdyljHd~uouQpcTV`T5|q%g=}B zUBGo*A;`VW*u!@z=-lvPr2O}t3DQ1mwua=ta`&Gvi=p|ioIw8b=J@%-A4~o#2c7fm z@$;cSYW~xYXPEM$7)u%PooVNb?@o~Nw%HnzUYYGDI)cJ89~z#ES$_Us&hqmCv&ux! zncm3Z=?ex0JRw=L*pNGj}R#SXG6ntKFiM+i=p8OvS+c& z&xgw);VBCW&wT9R`9dBkEYCy3^05UZES24VzKn;4Wio-V4CeUxA{G zJN|qS?eX(rJgOTvgWMR5#f{sUcD~q-a3e-}``7}K2ApjtUQ_%({eeF;4OFxI{9n)V z^TA=Ii4VL{%YZYWwB-#=1E6&epfW2Sng)`gX&@b%r?R1G0JL@klm?2SX#ljQqZ*n9 zK=xF-{CrpsNdt45K<>bv22jddW~keh?ItbQS9dzdqs64QSy4@b?c4w&D-J#`yH`MLWwH4s<3wdn?v;D+eklWp{yZs?7teNd6 zrfUD6{s44-9%#%#o8>2HeZvE1g^3TWQQcbza<4Viy`VdWK<)+IF$8ii=#C*!c?+7y z2jw?usC(t1?p21m7j)N=HZ-jDS$;mycKP{G9}?D%AoqgSRADP`Vd2YcKhYB8UeMi! zAont}famHTFw0MTV2tWsSCD%_=dOU-W1#zlK<)+ICj@dY=sqEkdqMXJf!zBUbbi0( z#FyYXc8iHGe=|ec<EJq=fS^d_W++2qX|2YLz)9}9tU*1;FUb%&zJHZKVO2@VfAzTd^wrp z=L-ggtq+wQe?E|R{P~C-v`3S9;$u)<7|Sr_g*wPC#-EQt>$H?>En(*ozA$In`9itY z@}+YP;%t9&C&bys;z(!vi-XP`bo>cAZwY*MF-RRBgBdtX?{ob8{}>vkj;s^^ujcsq ze?2rTS3|>gJ;%?N_n~3>nB(WG`yM}EK1K@D)6g(I&jC4OY_T9DOqUBn!<2vG>+2kl z^LK7@{CxGC(4-L~|_n)9Mv|jdu#(N<1IpFifzB~MU`5QC_ z0zEShv_JGS!%t<<9$*&G+rQWijmzB*KVM9S#wF+s zopNYgg3i^2on5@y;pfZk5IewU7lY#RF!YQ#P+T5{o)NbjnqKxZ{DjBlVbD1ekhpvS zy6b_JVdDcqh7goG5!Q!pww|b{@_+gR(79otG8?+~=fPpwi4Rso&%uX|#oYj<_0nk=GJ2+fQ84 z0CERteHZ5VKZ@I7eZR*R6F-6aPs(z$`WK!DLkTdx6|P8R~v#sQcZa?gy>00EN9j=&l~Ci7!ES z_<-CGy2A(Le$X90pz%ZK8WC{1L0%)mY(G&7{4Wk#za&2KK{Kk` z-+;<9(0NLrHWp~!AJoSB&ICy}znLKE=06jp56%pAJ3BL^4-Ptq9OQP;ng(I0+d=jS zJO6wr4srV)klR6P#;~{@G=2y^n^Jtf6zKdmCI$wP*T4RYgX^I=KT3e-Sg*5ZBI~J3vv%LKPRNECCmxAhgn+)(k{>!0<{Yu z_b^LyLhfOf=luCfpY!KSV-WWI`4V*B0%#o`=q%oPaG5#rMLDEQ2iGO#4nJS$d&1gU z8^GuCp|`a_>&!syf?|fBugp1rzO?3qw6%&Iem=;D)+GrX;JU;rnqdm)-1ryu43M@K zs9nX%PzX97Ygiy>e!Kvc=h+NDvqAMgw9o${p5f<9P`^K!0WxQl4xUek z+`-Jw37IqE=KT4J-Sg)QZqJ{u+&O=~@aDvvGXmYW;O_bJp|>Z>9n6Lx_a%es7jRg7 zOoq9|+v(?vY=)m6Ah*OjK->@xbwf0g8~#J*t(ZA~zWVR+^98f#&sYAOKVJl6aYMAj z&jCKH#-|(6j6~SQ*U!L)W%Ea2A^gKI4yBUJEw%%mvDapfiI(`4DuMHz*&Thvvh} z(0q6unh$R?{d@^3|3G)5gUXP{Opw0LbEcm!UW3jhXb3`CC&O$%@m3xFIjk3pE8*>Y z4mJie&>S&JodhixAIScn{s44-7N{L?nCT~IEz1LD(TNY7QOlKUpm=kJmWhi&XF%Id ze7PLzpVd(RtcUt%Gt@uZnIPo~XsrsUT-gs=%LDb#ai*US4m#F#RSR^eP~!Ia`vBS>?`q1)Y0T;OZ&;q4PkeT+-@&g)&;POKrQhxBTLCOzMn1IevP5|W> z=r|YX3_0+9>FP-N1zWk%&H3|1KbHIgI)AF$^XJ2U)N(@^1dZbfL(2qlB>SrgYNe6{Q0mQwM=*w$uI?UuLop4 zo#7)&nV^kSCTK&>QGWsT#|zMXC7?24`+O;U`OFnG2E`Apzh^W31g&{`a9DWa18&rO z_6Ou|&>4=Pa-$lW&+4K1tQnfm+M)TZ8=BAhq4{hwwA`4^1isfD+-{oB^b>a9I;h=u zruP4I(Ajj@){#8W2d$^Gm}oKD^BM^U-z2pO0@d{(N$u@#oXWp!+i9SAp)~1+9w%tuF$tF#zY8_l!Ru zK6d>1;=be0m!SFW)vP~XtOv~_Ys1%bO^srh^5FU*+XwrbY#%( z&q+}XQy%s^?|gLH@#h0(t%-fed}YmvUC4ZAjfri@{ABfsP00LawTX40@VpKgqwQc| z*a~v@i*CrA+{^2Zh<$>nbFh%M!Dd!S+h9BE&sUpWf4hFCS}7 zd8vsFC1~y>S$*P5(A-J0+QgU8xfAgDXUKCWhqWgv)gskz z%oeEY!dA2V1nqr&(5y1?!Dhyv$nMYqxdU`g1jrqrIR=nBKywTrcYx*?K<=0i8jn_= z_!6`S7UYiQEI(hYX88$r$9k5Z4_3SUe7N4_=aa+Q6CYK({(M~T`txWz~;M4A1w?XUU&TY^sx5C$JMSspVYhl1f^5ZeqqoZ zBA%eUvzqZI*sa+tKS6sVA2cf=?*E0x*+WpAFNeA{7&IQNHSuLQ)UDvLdyR=N!DIL8 z6JLVI?$su~OlSG|A{*+~e3qXNvR!^Y%!jyjE6A;@G2Qy;y5rA>m(kqItTiz|7j&Nt z)ScceKSBEw!Q=AtQNwgQ$eo~jcR_Iq8kYyfDQH|C6sDkYc~F>w#^ph23p6ed3R8EM zpD(<}caR%FWA7k0g2vuKZUl|JgWL!mdk3dG+8Q!}u=m~oHdR%eZg51A2e zoe$E}4|VHn=AZxHgZi{`6CZS=hOIfst=&+!g2$A!CW7{-f%DXDQ2$(G;>-I`w}R#s zKyH1`{PV?YW=Ng}nfu!L=fn5T;5@|*winZ_$oU;KzYWSypmj%~pm~LMs5?(H|NMU* zAMlI^7H!g8`L+%#gef9y?h&vxvgZ8jty7Ps)D`L&zf9O1-vLeI`8N> z=sXPhRVZ~twd2nRhh2X@Jno9J=5S#+sDBHoqd1V)9R6q8`QpFR&I}O-vxmx>kU7J{ z+7mZ}#u$sC;kKIj=l}JfaFapYO$|+p`y&{pyvT>f?__AWfyU`TX%RF|2TF^eaXL`m zSqvI~QJeU3IrGmKtD)frGIzD}&xh+F;Wil*ZpB!_?Y#>k+^$2zEm<8BZlL>IlcC`T zx{DfgUIwmkJI(s@1?aphX0&iicl`O_wCm4@=TXBg7!+>FSi4z#w}oT6%>p#P!Htwh=0oG!SpyQ+pnE3Wp>gd^Adg&T{rTcLmOSF^2tVTtxgB*Q zjA61A4@eSlWGM{PZi}}zz;;aFQ*TdQqUxCK;oS|U{y|4B`v*bk3{4a95<{Kyt zf$oO@l`Y^gMy-i2L3hxC!VYu?Ehy|jd&WRv2O4h$#j88$?ptWs`7{4~;O+eLp+6+- zPF4M%{s45w33?rP87YsHL&L3E4H9nGUBGu}fct;u1j6k$>(3XU^`Gc@#M}{nwj6S} zb%Dao7)u^0XWIFq98VqrtwUmFT=nR&*2FiUu?&4^SZXu>{I3rxZzLu@&_+#%i$P(j z4NZrjyB0y|5OmifC@jI_y&4lid(>Wn!V)~*t2Xf^X#W~$&l~8BA&|MyJ#U~kS~(~z z^)b`oLzvqRYfmfy#j`rpZP0yV51Pd%K2Sz=TMfuys3XRmXE#%CvFgXY5DvqI*=KePUP#m@HgB{vAW{d@_!+YU6B4Z71@9y)IeIy(h+ zFT1$o&ll{FdwexvcX@ASh0KLR`#Rt=Pqw>)&t7>2I+Icua*yvrVaJ~j!1vYZPkek> zd*bC#hAA&V=E+0v@_w8NA0K-m&b0Hz<4nt!%$bOJaB-x0aCW45aL~PYpt)aW#-C3> z;~C;kJ3V0Y;PGrf|AY5W7*2$p`w0$1ZML7_Fx6-K`7$1QCvq~|&sXtoKVK#zg{3$2 z-dBIahS~w1|AyKDp8viL z8S4ej^TOv$LHAZYcKG>%nek^Kcs#0M(tqf_gqO}paR|x}pg08O2T&XuL*vk#?dL0F zx1TS~k>XGs8i&%*IJAbwp*>O@DnsK?o$co<(0&!rUKM*c@O<+N(A+iX+?4ZR_f7=O zMT6RA;5Y=`HD*m94);Uj@G!&ASD?Kw?$9_q?C|r!e$c)42H-g42gM=CJkWixp!!lB zG;YA~^Ch<{_&gGjo#61@?(p*^XucVCM;a)6HzUR2X6U>(XxVdz{L=P(vE_)Nu4z&Cd>Sv{$M@>q;Cuxzi$>p%)dh0q*9>z2sHl+Du+Si^`LSX zG+qxXhe6}@pmG>AUJojVLF4tHau_;Z4=#t1_q86@p7^c;WUm88KOV)Mu=ZZF+C)o` zJEue43EgY@pji|#&kA+t2T(kM=2=1R1dY3c+zA?Y2e}h8?hbP2e$coaXxxSA=Sz?~ zp?g)q?mUmQSM{*=#3LYgg637x+6AGYv09|@hKH~=jI!oLK9F1cp>AEx^b@qd^g*)- zVqO*M)}tV|g6360ZUv83YE67Ooe9!E0`2<*xph9&t)MvukXx5C{d}<+bl+b?(2Mm< zKOd}i`uT9Z6SyBY6XaIVJSv)7QNk2f2Pdmfd?F3%PeI+;&GhqsKWJ=I7%_(mb?0o5 zJ3(`(Aa@pn#wtN$I8b+j$7D4oz66iSs!x0g9+Op@__Cep=ZkKrJ3;1lJNKc z$eo}$Q#5yi`f;%F2H1RQ=O5^N>2kK8|5tUos$l(M?m`om$O0UN>{V}e6`%| z=gZY@Ke-thK7i}uerVY!lbhY} z&Xt189?)FrdPv#B$;j{lJXeZd7lYkx~~bex9&N}ec0wnLFE$iJSoTxNb{s{H-Pp+ zg7)_{v;BNk@AmUWv)j*C(7mP@ZUD`bLhm zaHwYc`KsLQ=Zk8$pRe|V&iw}6lYrK51?vzdPW&j;l(p^5PMQD`1J6v8kCbk`Snycjfp04ldY^9P`E3p9TK zDhojK2cYs5G=Bgp3(}c>zQ~5=F_5|0PCp;!L-N?Pa@^x(FD^TR?_qw?&#?1_b2_}; z*TKqQ1{#~hR$j~!1ND!fWra7>&;R})e+W)|U=N+If%;pQ z=h4_2UIU(jBhC5dVSg0o_w2jMh$(hpx|q+5>KDLe6;r+w%<6wgRoSlxO() zLLQ`-;Unm7D|~6sN(!{!7@GF9nSTD)2c*tq^>-Zv{!f2--tp&)euteJ2N^8?b2I(?&ku4V|3uK8v&iEXCqQll-TMV{Bj_Fg zP(J?-x?@~(B4}?kcwXo~<4%xS{zRWG=VU&xiaFH_idM5i~D|mOuVC zgYHOTT?x9c>!CEm&qwkMKVO34m|1?+OXwYFpu3YmXLr10XZQ)amyCmv!Tcq+!%x^< zMVfydFT>P+{r_JabRX0MafhFO>i&c8J>psL#di@Dp^W z;Y)GQU2YCPxfr>+LFbQx*B67%0IAIQp;4*z0~D?x{U84S7k>hZ3vq{^oS-vU8CkkH z85w?p_Q?i2;p-JmmtjG=c=nKS%+VC?YoA?RMo$&EpenHz%Ceg91d+4n*kVkhWs zKG3~>pfcm3zQfO1h742C!vN(@LeTwQ$_zgrsWbe1tj+NAi9W+mkUr4-{Y!PweZmYs zLH8>^Xhy_`FepBh9ezGAK4AMm8WJC8;PHWa4;?ICL1h!D@6^l45b{9Y;pdZP#)*%N z9ezFrm6^=)TA=xaCDow&z0mZ7$_UWClc2H;dJh@s4rq{hpnLURLeH`3Vq^$;CG7AM zZXc_|PY*_pZVgzNgUTmR-(Q;H=iC4P#X)yYg3^lyBg0P(PKTc$^FZzc#S5tI3A!&6 zq(%d@&H{8-m?FbO@V#K%kaBMoCqoG6&M$bo0(7q`sBP2E@Dp@zvs70u;1Y)Q(59`4xJ2SJ^=N@FEjjne4XJZBdFdw?eO#Ed552`E<5~uecj>bYiGuvuiQar z6w9xA1->(w@#ib>J;soGjX~!!zi8&1_`;g;C+Hr<7tCB*FYFnAz5wkHvUmKsnz141 zwLT-HuMjCV5qu}IKhsVv!G@q$-b_1Ju{8vN&Oqj3Wcc9KC^`|m$0VHb=Zj!Q@V&|} z!yUon0-$y6AoqdB1VHQCL1*28&rOD|WA9>S2m#A)clh}NwCAic^T$ethM<@Jj6dQ1 z25-inulzylCb(9C)}X%xjioblu6nSU;peM(#-A^v8Nq8TLFPO@47u0(!Dfe_j~;VO zd>Ftm{R}_vgX-4vkahX54m?vf_Ca}r ztpn!)TSwjlwoZZvY@J09*go!Vuzl3tVEeGS!S+FYgYARG2f*rHG0U%d1v)4BF~iSS z_Zfb^y3GLJlknm&+eFYl3=hy4@NjsTIu&jEqoZ;tV&=}ckho8Ue{!f3% z%&_X=YKET=7#OyI`~kY3`+u_#$~uM@&^Ug**x~1!B(dV@Sczt(;a>?vpW1_Vg%itDX(P>8aHod_&I@*LF5H=Pe&soByB$h znSUCgkA>CYCo?1H-bs0_S0(?agVtm>!SsR7WfXwudkE7r+2QA_=?*_V86AFt%C%SO zp#B2W&!^4&6CW|Nu6k6?@RNb@fGr~^zW+DaKKR{W%fNZSmXY^>EtB8@TV_yv^EcW) z;%>Bk$lhrCfVt83f$%}Fx);o>t6o$y{Cx7=@#o{ujz1qU%WEAifu_fLNL>%|_k((e zpAU)|euja@b;_ZB0hM#i469zIGyLRaaQLYRI)99raTTbog6zkNN~n4HNap23%yR;j zUD*ylU#2^N&I$ytO$Ogh3q6ApWH(3-ehy_Y!_QaYko#%DXJJCmq~v0PgxQN=ho7&) zA!VU9tHV#8kF}R`Gjo2dd|Q3lizzC zUw+;JvZmUf;U_Dn1Ej9F585Nf06EtHbp8n_ecg8a+2q_11iFtV%}vdo@!7!V1TBBm(227FQ+r?Ewc%b&XV?ic>&0}3ohz6b%s}i%ptO11;U}oP0o`Far||#uht-Tf zAC!YI=xhaspD#dj^~@ZrKx=qcz{(nT&>BaEpASKCI~g=?@9-0z_NF`hgvI4lQ2Vc$ z;pcUzI?&!IP(A?da{|YOHN#IWMu(rCtPB%18yP-wvNQxKUhSF%(+^5pzWmU%V2_j* z>>>6aWMB{h)nTA=4s4!2#JpFaKI1_LOHkhdR5!oKXZ-mBbl-?MB<#TV7lYbM+K_Ys zYBPY=+k(Ob)Lwgi-r?u_;|@RHoOby63bbw@+YwxD@_wwn+?SdA<4o=O+2?BcXKOO@ zt@dK%*_FfU@KgJ(!=&y^-5;JGPfqswTXXqUKI6}q*^HpECh(eG(B7{npz|1E=|mkV zounhBlVrx94?*+%$&No4`85PBW^4#L_CO+!NI1Wo6jN2rWlIVS~~pQ-+Rn8$;4NNFT`Wp#BEf@5&B8LH8Gf+S#jl zAo&Aq1|#S$0FG6!gc*KnDKboaCC>0ulM^Jyx$2cPq#dWl4N(tTDGBBdH?dE&_n-1y+gY>-?cKG=Ubni2$9OUKh)@0;< z{hFC`)oW&kpRbz*C%$H9`1uMnrUDvI0l5>>hPa>!ay#h$4{t|sJK{C7(8Sl=3_oAF zgT`B!e!gIUx*62Zg0}VG?gO>=K<#U8ho8vqgSGj}VeVsxw3T0KGyO#FCqD#_*D(F; zumbHNaQeykvG($e>HnsK!ssC=zn*va`3bcCt{IY+A2d7sM6dV%H?v**lP|IIZ?)vg z2Uz+gPeE(N)g6AmR(AOL2IL2Qho7MI1)8sY3z|b&&hYd9Y=)oz=QI3#nancre?P;| z|C1Sh{-4h9^G!d)&)1U~euC=%m$MmuW`f#Y^FjBRJNyK-Q@KHVm>WeWzOH8YxtgsZ z=yg5A&(%T=L9dw^A!EhtjG(dN3)vIJCcbWG`1zWlA?P)zjs@*m1f5e1nhz3Z_z4Hs ztKAGgU+#zAu@36@f!gET4nH3qW}cYp2U(X5vhN9~PYzl)@5}@qXMml*xYD0t%4^VF z=b*lmy2H;W%nm;v1Rt<{px$5$x^o(IKllsiz0t6Hq+gqZ?xzQxZOQQSg)_rX&^d%J zK>Hw^A@_(s@^<+7*x%u22WYJrJHyWdp!=KIL4D-Nm4EUhR{n2h1K+m{x&!+msE;V` z06Ir<;$v@zpHKW9eom7Ewf#}m{y)rc@ozQL$_MNWKOb^4{CvdE0PcG{;&%A?fZgHe zVg`qwOISed52jV+|3UhlR{lTC0JaCwZ{WTNZikjL{CrZ)@bh6k!%t8>^SGVi=c8^& zntM?X+QZ}U^K~_-Z|3mx4XBScpW)}5#SA~+-4YrE54YmrF4Ysd}8Gb5w9ssL_wWGl0xH03;6U+@k;J%2t<4@4N zE}*sqXm61ns2+su!TRU`Eh}Dt=2$@YrNo2ED2Jcmc0w}v3}L_2cCk zf4-1+{P|KEbRQN2cyHA|P`d~eFQ9h7e57_jJ*ZuR)DD;rZ3oPE*r~w|X$OGq@rK&t z?eG(nPC4E(eB^<(k?I|OzH*1$Z3DVv8FU9TsLiiw*fk53ClA2NYj;T7`-L~d&v&3U zQZvYIho3L)k-`PM{sI~>Yl-c6a#s z!WmLlYB4kfc`2TrmCeZb(aW%77HCXJlaZ?nwm<&`zvEBP9(`CG?u3R32QS0NMyOw& zm5Mr9$@A!2DN8E=fW2| z{CpYj@bgu}^&#mTRDZvKwsl^B+BwDyKRdV~b=DKm7<#kA&sU(fjW`2%3_w%x)MWU+ z8)2ll0^h9yjjO{9KOY`<`1# z9~>V!SG{EBTJ;h%P72C{$_zhWooD#@0(5r^v;3+z%$%#L+^=7# z&zJIIWcc_Bw9k#POX{UQ!_OB?4CbJ`03It7+uza{U7Bw+F3%c%TnS>)@~ewWUDg zx1e<)+zdaTJ_e7WL)z@Sp<_P#8Gb(8@9^`%Zik;rnGHe7j158Q?*FF00_~##om*_| z@YAzW1Jpoy)>ia;_1SniUeI3wz*vsh*KVQsd z`1x|W!_OC>bp@dDvdIiTAM`u?1hpIfH*=$m4ZzF$!&(=?=Nn#U{Q2lMyAH9FfeQd<*WaPwNUH@^|4=r?r8z5>nD zMKeLxgvB%c1l@fOy5}0+wyJ!me0Ve8}9jz1rQ_P^|R{Q2my;6y(k zhAA&V=ADPE348b&)Ta^vpCbrsTTJq0nDPp=Pw2km&nMeK=NBHdeZbym`=6QV=YP;V z#bN%5|9><7{QsZv=d0h0KVSX_#RC(#&-Q|y>E{Dxr=Jhmoqj&zcKZ34-|1%wXk1}8 zBcwe6Iy(?8{6TT{ireYuOMa)HuRv=H+97TS#TjT{5V%g<4DPpxfbTVHcl!BqGRw~w zpgYo-l_x%Q7J$zuB>OT<0h#x}`;hGe<0e~BoWsm{06M#MJ>$i)z!)&No zvms{91L-H=hD9JZOo!^54$(IO$ql_Awz3jr|Cv0}{=AZw6gYKb_pZFiNuS8jC;!Dt-N8h3MBK&6l`QW?r&xgOAf3D02*$?q|5DS9{ zD1MRM_#jzfB4`f=$gLtEx7I_~&qDW#ykM4}`2R8U&;Ot^q(E*3?fn4x8@l%c>{jHx zA0W3@Gyd!bxwYEy=YQzAC-6IuKyHPeRRS*Wk6iP~E_=>OnH-{uRbmpz#9GnJ6zVGyi;X-WfdBAzT5vE5`BX zgX7FUAA-(JIqv-PWj<&umGkwh<@2RpJ!jhK#mG>^A=o+VMLDSaWB3S~t9exJ_!Bvd z9)jYYnQ_%>(7b3oG<^0m|NIZS-)J%9&Z7U|y(fwjL3bCu1clFT=ASS2GegR#!^}S) z?05e8@G$6n2jz*6q8WcWgTg1;5xigH|7OtrBeD}g_YA!Rg%9Yyq4m(XM7pEM3=}@` zknp+B%pii{&SVAfn)gPKJ7IeT7Bm0+58B6ZSZ3mX=p8~YLGcLM^8s=v_)a0HJC`&6 ze6ZO0=fmYtcLp>5lmxjm7<6|e^H0#dLobqLCjRdS?YB{y__Ck*=ZncucTQ*i`Czj1 z&xg~UfAWCb2|6clJ>$=<%nTx+yJ}ySgUUS4*9%w~LSTF*M$XsR!Z{G+et&2v%H`M*!j6YxI{h$8G z+wmvpZlV9xpgbcz5p=%}IGjQE?36>@U(NjULAmqKht#9`&^;P2n58HFho0dA4tLO=3sAU2_gsMU5AvQ1Q2udd z{J9(CZqVL=Xy%`wyL?_OmYVn&R6pD&`J?v7{v`5@Z)=fimCpX)&Gc88>o zaFDzCU4D9)Gi(8kY5d>L@)LZ&D)dg%|C?EUzH(Na_-Z}N&sWI`6JLS$lWu2$v^RFM z{Cu_D<>$-YE}*$A$QdECSs-iB=d(c8pgVIy+8geip!UXwY|t9?<6t20gq)s&ImzoZ|F1rd$OA-wR%|1L`MoL-Kbo14GCQ z&^jGvM#vd#-yOkgzrkzJLHA~X#tr^6`~>wUU;Kui+w~iCrWPpvvwnciYkR5h0$GC& zU0V;fs3j&=52ekvfewi86UWCLYd=2_*mY@GYcR({E z#UUs^fZ`C8A3$;V8k!&8v;2JZ+U4iV_elBSJTyOCW`V@vYG{5~56chy6JOtEfyCi` zmY=Uav;2Jd9fV!L>-Rxt#DUiBzjzNFFMysm2X22qcli0@GblXp#3AVXHc%Xb=1@WB z7XOFlhsO>-AKZ8N`6yWp9EW+JI0TvZ9=eY}+XdXWe#!3wo^yrA;dO_fFG1_~8KL_K zK;e5Cx&|E-zL%kE&_VkEK;aAO$DVfp_hrH7=z;oq`XD!F{djSh;pa3)0JK%8$8WXq-T9W~~KOJ0#d_2g)5CUo&yaxFN z6nEM#KVNIJ{CvgF^7FNFqU9^*B+J*#N|vvb6)hDM8749+GE963>d)%CfcughEDk?G z>)bgw9Kd~24jzY}FFj!7%pAYPve?D|}{;3Aq3%=X|+=n>N$RGl0`+?V3fZ9~k8Garw{XhLF zsPD|oxa#3-(3%{`{brAhoqxjGw4i$*GePsOu=V}WJzy`GB`5xe-a!Vg=RkY9K=mAS zPZ!u9$a}g#{+P`0lM&>P$qqmNOEdoj-COozvBX5sxm#d=h%^6uAr1A1JoC>7($1i^ z_|Gpnkahl``gtxRgNWO||KjLvp$DKgy|d!Ptsu9;*3I)X{{-DX_5ymB*niMjT%a%q zoy`SuD>w7c7yQt+gfR2Z2mH=I9|}X;65R|xujTxo{s?rB=YOW3|CvEyE)en^-XfyPs>JO2FtSjkd@6Vm762CcIMwfUMEe!g;d`T5$N z1vJdhKAL1rk@WUJND6F7;W_3mekyrN}f5OK}py$uO zL@KXegUV`9IqeLsYu!Qn>0E!lbO+b9kiB#I(7M(bTGwVn>)L#9T{|Hgv=-MITG!gM z{(J?x!vJ)Dfxqj|m&uUzYTz;NbZ9vZ9!H1PwV-<*z2SB31WnK!40^jIoB`5qiDvlu zDwy@>%W!C23tE#N4l1WL!R0iI2k4Az(Ec$q39&J@fJ(E32o znp|t7HM#akc7euaL1!}|m)qV*<+e9;PSqJ4Mjt_A=TAXn-^}u>K;z(`HRzx_+8fyz zLO}iG2cUB`kow7wl$9nbhy0)Zz#LjOUT69Vx{K~bve-n>{crz4dxJpv^gJ}}U1s|E z;yN_#-Ddjv;JVY#hqs|=&zRxoo9zG7LF)lQ=WP8y4Z3$sY~ugJp!FY06JH)?`uXBG zH0_;c`uX6v)6a*eoqpcW2H6kEryUFoB9HDn{sf=@f#gn5+4ocY|8&sUsWAhjFOAJF zAA%c0>KLpXuj=-A+Fr?uYtC zo#E$BkYCgte*TB<`FWu%I`Kc~OfXQH0o}I)Zm%Nk+gSthi#EhBpgl#8Ze#b$F{oca zV?QtTL1V}aKVPsgYyt6M$Kb`3(_&z&O`T*^70);8` zZaZ+DgM7CgsLo+$_?ZFz9C7Ox?wZa`A2$jA@^j#pvEpZ~=ff4&rU{0Z7y3sbMk$RP6i zxdXVqdCAP71sbyi%}2f351LQlSoP*Gh~`}N<~YO8*QX)#4zPKZ*C2ZiJN$fe9Mpbu z`1$I*!_T*u9e%#M?(p;7a)zI8S2O&41sa#%%<%IKXg+#3!%t5}hL11J=Sy*b)`prx z<|sHAJEc6B7|cO;sK4Co@Dp^G?wX(Vm$hp-XLHqZ&epHxn5|cPa<&&Ef43JSU-w&( zo3Oa&4yddEjp>8ttf6hJH`^V4zTNHc^KC!FPte-D*V94s>kL0%&S&`f0yIAlT5ASf zu5pi*t#KQ8E8(3SArn~w5Aetp7ZN& zho7(79e%!HmS2^{$knaO&=BPH*KzWzXojEOjNGrY{?<=^8_)3bO)|sJ*XayDUuA>J za)zHTKzpy^9e%zB&4s3e)~!P7)wjhCKi@ht{Cwli@bjfN!%tAT{TjOV3KTaSj9jNQ z8M#hzFmkS1!OpM+RDOfjUA+d)H-gG(Mu$ltw`4Q&ba5~`T*_wTImN-qz3P=UWDb1= zBg0mZ`Zw;NwW^@CpAJ7gYk6jK)bh;suH~NXReNSO2P0_xE?4(UYlfeobM@Z2JN$g_ z?C|rozr)Xu-VQ(CT08uF11ifo8iF(#8iHOib80y-GJX_bW%vl1L(}-@c-cVd!Ylzc z?^T9s2WElgj3&+sWMuf5%{XBeXx@{{uyfYQTE5vYYWZfLujQY8uJ+t)4o3cN4p1E9 z2(K-mb<&`@v1W&#uiG7dzTFR6hv@M0UA4o{kKqnKKLk7cd{gf5^L(w~?Dy&nKYMBg zXJ4oln0>DH;_Mzqf$ly=zV3J03_sT}^1XfoPKW%jUzpFATFc1ynuD=N>NRMui!sB` zm*xzhb*<*0HB6v2=dVC(%RuJ?8Z-O^%}asq^nO+C@DmjGAUC`Ntw(z7@bf)r9!=lj z=LchlpC8Q~etzU<`1wJY;pZE1sGaSgw9o(gMLUw6ptaDW_Xm+-P=Jy$Y{s;B* zVROJxJ3(g&zUX%N3F^21|IYwEcOBG^hm}d7{v&8_`OD7?kh9uB=bnSkXMfG`6V%^* z@Y><$!}p-QFPszqs_*2`wA?WpOCdin~ zeJ0SD%!KTRViR8%gVyOb1idbYtn&rk-SiT4W)^5XgBdh01qwTG-*h4Sq=ymt8c;P?UC z2eTV&|7$b;{I3rh3jv)C%=q)aI^$2!di0l|u`X>!$XK;L z@x09g??zjWgAU+vxrGc2A)s|Z;5dHH@H35xK?I~0wD-n?kzwltcE_Jjnnfl)n(XxR z@pLEnyqFGXjQKgk&nPAakq3)~A@eu;84>3PK4$pYBl_$Dg1zsVuAvAD^6O_}RhU5Y$n_F&nf_K?Am* z<1)if=w6!%;PaqB>%T$!IHoiHd@$MZ=fmlaKbxW&!RrQQ*#Dajs&_%_8$f5{gYF#A z584(5gZOTL2dw@>+qc6=YDiI92T1RkXdjdsGatRnL|st;Q#ao`=McRnepfU>ri(v z^G$s4xWV?pbErEGgUTnNi7$^c{(K2?$7!fL&V$wyK-~elgYhz?-42S6?HT{4gW4^i zGeAIN9^f&3=-CP{nZ+l9?(hcnv0oh)n)vE5)6Z9ng(toO-39&{x`yCA)6ZA0oqoQ2 z?*u9HK91ymlzHn}A!QzDO#e0$WK91))6Z9+vvNS^ywSH>7X;qB$5`cDxXuFZIHoaVLoXGC2e>rtj~FxL;*4 z#YX<1K0Orh)u(W1|j0ab^B88RO1&iwNg=xi>~d``IY zPxN&w;4%HlNMSh{)Yfwb*B>t#pyvXh*B{-`u8Tc@h8yu0_ZG*YEb-V{dfU7vmoB-C#Z~j2^yz@on4df@bhIc#18P8 zBv3oRWBO1#z~jN?2s_~8!SxJ3L1R~-eJ}7aeR<}epfO04I0WSfP#l8t11JvVp>e3p z{PUH(^Us&cNO8yvjYD>59126@P#h@^`Jr(r%>45e=zaoi=ASRMoqxjC#lhAhf#Wb4 z5}x4v0O~8K6NtlTXdK2f{Cowv>%bTqhw%6no8&x5h#59k>b!FI;IaAM*@uzf%+_7v;&^UBPvIDd)A2jX*8ykY!0gpp}=-3csUF1j5cn~}e{Xu;sNPc`V-{GeQ$B*qV zK`x$>e*zNf9A!vP6v&clp^#9XefX+UD&hQg_-o#;{iLXI< z5tLrboqoP92d({L`uVy!*z#3!h~?{K5zAN2!ie!;&^qyIr=Os;bznb(`VpY{4A2-1 z$j_iL7?7VqdlaC4wsc{b@|NA<=NoQ^pRf5HeuDP8!q%C;jc39b3ugTHU;M#yP`e$q z-S?jvw8ma+<=<-Yl@F9bd#@ROKGJ6R`54p}1FaL+cK8YE?||wm(0X}LIrqPt;U{P< z{Yzz*iT^?STcQ1PP+#;VsO$orUDNLXDOW-5@?z*3`f`S!uWcHFUVmnQl&jwvAmu8n z_(V`&AH2>DG=>fu8(7Zp^Cf6J0W>ZJ>Ysu3MT5=-0M$|AkhBZVlj06PLG=M>FC4sF zoef<>4_(jyiXSxQ;PCUMFlbFZ!_SxNp=;>%9ezF(cK8W8=lfAJ^Ta7mpt({=+5^oy zKh$^l`GA=Te4YTT9el%?Vafw#ho6tx9ezIWK4AMmxxx0Kv%}9v?hZd~L2UosUy;sC~%1`+XUR%(-@nZ(a`9|P9xRATez-^R9@rj_Z!fv*Ppx5Uaes(iA z1ifAi-LtZs5t83RB__VU&hQf)f44#HHin-sL1O{`9e%!qjj@2%Lz{!^?1?WxWisrn zLC`v5(ENO5<_~y&`wY!*pnmUXho7(18Nl=WptA>Ff%??!(0;JL!_SAHF>Q6wUOTpl zI~*CNya1VJ4ygkl`h(VGvrGi-^?~KLKTZr&9@snld+3 z=082mGV$?jho4X8gZ8#E2rXr0m;%153A7#=)Ybx((V%%%X@;LCK=w&H`~>a4BgH<@ zSrbnVvrK#f+SfAM;U~xsj~6pfe8Ir*fum7;BIxW0(7ihyp#COkEq67;PYw|KH^a^j z#)hC5{~30I)rLw;1hw~GfW+EC`*N5k{?BIk`9GiG=l^1cpZ1cFFa!DR38;K*ci8z1 zR9=}Muzld(U<;c6eBAHwla-M{NQHr63h2B6&_1-+)($@(Bs2Vcn9lI?Nit}E8pF?5 z=?*`$I2nFE?RWSI+S36#Qwr3Mc^L2TlZm|{=rB`5P?ycW>7e~`pzwGF8jlTT`1vB7 z;pc1Uo>b7@J#9urJRq~t;{=gcWG;f%Z9f6^)(z)-#AN8d~=)e=j&|dpRYi7fPwmmpms<)=qzdGpD#i8WP$Kw zsfjO=p>xupHC)M{wx9FQF2;r+P`mpT1H%WesS*=kg)@WC2za%eZ6_B`L(r?mY&*Ny z8iHPd`VJs9jp7quf$r$4Xa4!3ni;bHzux)hOVGUv&l$nz6TAf7q3|3so&?^@eI2r9 z3ci>7y5r9m)sQwNcq|EY1~IIEP|W=ERk`y|@ctvvTJK^In{(9z(4O~p(7C_Npm9?0 z9w6|V?en0sb{&5{a+aF-&;fK`ALu?uM)3ZBkUVJJF!(+P&_0Iaj6a!J9ey%0I{e(h z1l`ARn(=1?Y#+yI$Dg3Fjz3GU24A2>VzeCY1{^S`qUY99IzzK2{GR33uvE&;9O zfAQaW=Zkjcoh%FtA|Bv03XQLJ=bbN_nL&5`3UhEW6uyS-w`qo%!C2T0+w%mPceG}P z>^DQY7YxJx_l`d~Ss6CI*w6S=kp;59=_#o1-|V~-?BCzcJ6|4m{Hem~@KYJI$C8mj zXdMf~l!xZbKOY!_u=CFcptha4Gh|;CsEr2;1JFGUp!B27{PP9Ux(5t5YzM7$qP`P0LAZeP&xyb-ya=iAmIX%1Mlxz%n07w z4K8Ou>oZ{Gk1#X%{;~(c&OaCNHv~DeK+gBLXZ3ITi^YyVUxMO^5!5E))OyLxpvBRs z`8r7wYBngGLH9|_XZ+a#-IooTV|%$76!r`spMdUhXJ%Oix)0!GHmJYM_>+~<;V0M) zpnKF97%o7{K<1wh`JI10;CBAWBmmi?vd`+@^w*Oef4-XT2sv|sSzgOCQ`_Rjd`Oss z?U@g?2Q-Gv%(CibI^)lm&e9V>dzZoX^&{C=%=q&K=qzBEo#mkMROX)#*+Kcs`Dc`13`(l>5e}i zg3s3k&5wp#zD#EP3EMLd4zp~>pRdv#f4YFiL&HIP##mN?&Q1sIrv{xZ0*@cid7ZGZ zddvh~=K)&p@dz3}VIcQ~JN|qX?fCOWyyMT6tPMfn_(_Ju&&$=0;Q7{9(6ikiFmtQ| z-I2|~$n_eWFF=1>K+cDj0Nbp5xD_{-C_%_!E4tk254azwl;+q#1L@pD#db zP+;z|X8if$Hq+0C_nm$|xb5_lNvI*{Q9aYn#Y~VitP64@$iJXFM?h;;tsQ?ps(0G? z#M$v@HY2Fb#rV?|w2tRG)6W-|nSMUJ?)3A)Wv8FYEDb?&R{y5Ibawpt0<u^hC%60|>#W7SJz@ZOY<@I8m1Grc(( zJ}N3A@)Kxo`hh-<{G<$xFKy8NeCMB_@qc)HfyVD);c}P>e0SJ`!%jbwgdzFqmF2(b zuarS!`HtXu0?^(8P+9`n1xin#assp-_kl3#Hb`kmqD3(#5!nE9adly@_M z*E@jLJ%GmOo-lK09TIK`di0-hCo^+H&^gP0(_e$yg`j){IuH4`!_PL6XfYwxOX8QSXyVK7Ho1K0pvqR$X2{+@L;_?{hJP&ZwBR?2fG=5KD^KH^TBO~pDLid zbD81i15nxanBgb5thvsBDBJck`~;oH`T`bSp!;W6Gl9=$eX!c;r;|uS(4&6FouIvV zEg*k^_RZ~f`1$I+!_SwXIljXVKOglw?mWZ5aG|GBb7C)}!_T+p8Gg31I{f6W;hycn z$o={WXfGmY9m!&*pAVOV<`$fOHnTJY6eLlmM=FmpqBT~9Ux%>x_1^7 zChMVLvKlE&ri0ENfR^`@nSMS5%|%Rh`pF~;NuN%ja9HjD-v16-mjEwMHbeG1!pjrT z-g$6+#IfqZe9)Kxv^-f1VspOkf|e&Q7d!lXI^W^vi`Ag~$NBmN=)9|JXYf8lc)Wnl z=IUmGlr5k(bw3mMT-pcSPCu2z8iF3lGs4RfDNz0al_TvAKS6V;kK`S9g3iZzo$dS+ zw8jBkj)2a&ZD#uUu-)nBgJwuM!ejYw`b$t>V!Ff62cY){wvpcpOT8@CmwW~pE zo#a=&sAu~5pxWu@!+Ix-HW#QK2Bl9TJ-td!RThhsI$sQXG~e#bGfM_&%}+#ZEt)#36Bb z(c<6qSJ1KH2cU6eW_c}e8B-03!$+V!g!K+TA67g3d(D*H=+<=Vr zaK3)w%>-%J`ZN7}06o(bqpkp@uW)Ey0-d)2iU-iz2vFO}8z~+@Yb8MEq{7ME}atr=Jg;oqjHo1l5BK;PNHM;@@=8cqnMB@=?9RPSE)arx+M6cr|KH^aj;|&I~_Y zSwZ{UnSQ>oX8QTi-s$H9Ye-oVYw>S7X#ELj5Bn>3$T$UZ8{{Quya3eS1Ff-SpAHI}hvrN_9~gteG0+mUR~n`L2nz#cXc-GS7Znr+pmS$n?MHp2w5ZJl zKBx16w$o21DM(t>1G!xpG%f);W8DGKK7sC^hLZ^mw6LIhw5=c81v`<+0qORlimt5{(K|O`13V4Sb@R*l3XgrL4;ujl+ zDWG$_K=y&hpF!tkbsw;OP~2eqpqUlEU)kIa)VFuo`JnxP?StqBTMk(UaDN)q|9)}Z z0n)!_WGsBkzyM#D@xPf9rQiM_9@O7po%m?8!_UW{a{{4fZXQnq-7gDWC*lq|lLuAb z3(!6kXUOIb66QBa)8#x&1U!snrnRE4+&F{dXPOY>K%5zNM_gxY6rha zXW027-C-xFtp^&v)CApG8qcuPSAZepDRli8=$t9I-zG!d1G?)Sbl%-`ho6g-Am^fi z{KgOR8)zN{6fcYpmM^>+c52Ep2y0GcD1711u(Jnr2B^2gPR>?FFrOR7e+l9Dfc9c} zJM83Wgs6Yv@38ZQHN#HMwG4$X?HP7*a5V&RFmh&t)mc02d=byEGaR(m#ol2jsExo< z>oEC=FgU(Ga5(Zze1Tj>bwk|_y6e3ga=z#x&rh3KCqCZn@bd|%UCYe4s)OtQ z^auRV^u>>vz8* z`01pInNF%eWhlGD&llDXJ6}BpoihkJ*OlQT=-gCL+v zLHPhQZ}S!uU+fM$S1>Y|ykK|O$zjS+2s*b1%+_Qme1Inpg4!aGHUYy&@SeM5hn+9u z9e#q&d&8Eu5ap=YMbH_b53?C}KFVj@`53gOVn4&rr=Yt`HbeRiuR-fM7#b$M2Hh6{ zT5CO-=_hEN^~+?DiJ}LA;3Us$M=w9pfPCr3sSb_Fry&VmWBti__0n^Fi}}PCs8RX88FEw9bAzL=;&N+-DK9|gt%uAZyvTNhlz*HIh2ZiK#%E+K1f6Zh!O$@2MKQGf zRnGJi)Mf?UrTf2G45fSo*#kPiB$2`4XA+CU&-}mtri1obIe^CgXFL4-pUw311=892 z==woxU0`twn%i5!1m1hR(}R)047{d2nd#?$aNE`C=fiZTpXmC*WfSyVkq6OEKOe?p zs)5-7TIU8}qh^ z3~~?fZm56vGyQzE+v(?v{Z2n$9fs^F0k!Qx=D__|4VsgJ+`rz`-4F!oSA)uR4Uqpp zYg#~UPzLb+>>!YP;d_tu8F#+Wcij1cmB9?O&JH}U0_vx+L)LeK+CSbl3{ybve39$` zK0gw4mLO;i1ZXV;Y~PoS4a1a&$qqjsf$rd77M%DXo8hOq4a1ZNptD1>9d|xD3|dFZ zsl_PkFgZ5n|MUmaOg|rj+lo#mhGEJh(0txTq8WZ30Nqy}?eO#eWyYT`u7lRifyUSveuDOh zfYz9R{PzDebr^*rOx2d5o> zK0NRE^G+P79pmuxp*N_mK+W3^K68Tar|3|C^f|9sGfa7z?YQ%QJ=4zr%}hH%d5MEz zNzsdTrkxtalY%(f78SkdhKVmKdeP6cbA?-T5Xa7iMK2~Z?d(u#4$|mZSoC5#)6Nr< z8-q^dEG&94n`vi8=+q#O(1k@W<}>YFVc8kP;k>Zu#bTzN8m5gw9wrNmUMy$YsWGP^ zh(lvx(TmkgJ3TC#gI35cEPAn?Y3B<6nL#T=78bqO%(Rn(VM@>oo`pp(wlnR_xHB_| zgKc5ai`_8yEG&AlpJ^w@n%1C>Uki#}9A?_-kv1`?4KscpnEn?%?t8)w4mt4ZKjNHdcn=S(__-a zAdX`TieB(D?>upNLQuz%1w}7}nRmW;F+Ygo@PeWj;>}w6`*s`GLg*Wrg6APMxR%~8S z^unKc=ZXKVK_@mXD0&ghyz@m@f6$AK3yNNZGwYQ^P#ol&qX?rIbRJ9&>8d`THz-Dri12vU)VeR1m$8KyjNhUR(Dy)B?M?8b~gLFW~|0IfMNb_DP30Oxsi#-E^d?k^s5 zOa$$-`mfCR^Cc+HgZ5m3^1L$WTnA{L*Jk|rK;7}@Lv6>O_hbK0e*iic(;PF;gWLvl z*CWuHVrHgQ4;S-K{Kg5{3kWWY^c}$av|fP5jX`HHsDsY$bo}{3o8c$eU7)_FFlg^O z$3)QHivOVgD9Bx)eHI{haWnpW!4GwpFeCV0MbLQ+J3;PJhpc@-uji57^$_eX##Jkr zA$0^pDs+7VsGL-G_zCLkg6`l0?biUc!9n-9y^x2x?K{KI|Ddt>WcG>wL2E`pdl5ix z1Km{!a@%JH@O}<(+v7LG&j;Tfem?x|@N*K#ZJ;){JZ6}I%JLV`H7Bq&D4;lHl46+h z;yKeq2GBkLafZL(u({6g^FL^hNiy5S|K}Ng{s-Md2(lk^o*&45(BA*+43PZ^w;6su zxbE=t;cbVXMIigd9sY7Kq|F13)q&bBpf>PJ(3&^s{sK^)4|X>{(mG(!m`lFn&X=IG zarr^xbX?spxfyb%5TtGI#68gLXZDOgpE@)CeC*En^N}~>&nL5)c0QcX z1Q}xm-6i1c`16&$GspJgYPcSF#tZWhS81ZSq7 zuRv-*>k>fc5`)H)%b6hS5~`iRb3`w+A@d=iv5gnnNb3@mLGx>zui@(wltJ^IkTyDa zT>|LrIR*wuTRk6i7M&AhU4k^^OqU0sdkH|}9iX$=>cQi2kaY>5azonj=L31jS#rBA z7^b`cnXL_3mjEhLUKl(6d};3Z^Qp7I#8=F$t3Y>^Dli_fRb)M2`;fa4e2$y~=K)(q z-UGHuf(LAsLFc+lH`+cDZ?t_V+-UoNztNVV@th6lyg6`uGeh=Jfc7nb_b+^Jumzp9 z58g-c8nT8TeEvIVe-gjb&&S-Lu~N{P^72|PvCy>;;z(;D#Gz{;4m19Iah&nzgTszL zA0Bu7`QKRzrO)t`-|^?e`A$1u2s^^h4u9ax2RcK10Vz zL1jU@6FASmfR*Q)q2>8@#-9&CXY_4${F&s_5Cod%erg1o=Z2im@&L5g2{vBO4oxrC zjz2;BctCrUG;!?LkFFk0lt%2Vj?&_-3G0tgx*il-)Q@wyAkt#iusMU zk7hU8KAhfY`(SdT?Mu+S+~R{^wH&ezlTgmx`qkVb9=8t<^n0R+6(z;wZl(PIDyth zK+f(xG|Ptpbarny;_Tk#h_Hi&nE)uvKw}fHnSMS1owf1a>E}z({vFV{JC_-LUIF!A zL1_;8TwiFqg5R;>47w|fah2NY|I;6W&)ER&|8n~I;VtS+PgXBir2l0()XZnhQ%c;`|ptQ@d3Umf5{7hfaIjo>^YBST% z7od6h?M^>mZbsO*2;`6BkUOhhg6>jf4zPULEM^H_KL#2TTFvwm)_(`xGX#!j&|1pL z3_mkq=lO!}W?k*{^JO_`zTD|2hv3P{p!+$%=TH@+#o=OT94<%9cQ<7~&hp)C_;30f z&>So1Ok>b_#-OxQ4H|<$I?ES4XUehaC1~yPdM5C_sUWw4&+=^t?YZY(^#;7(9Lrh0 zpz~;9XZeEe1_7Oq((Ul`al6CMf2RMYgZH9?#yvo1GuIPwmhWmN@cMuU{gC_!8cTW6 z?*Qq$?}yB3K0WLNTIUDJ`=E0XKx;zhGlA-wpATj`!O!w7G5k0E6=+-l)Q6vpbe8XQ zhM!CR{}%_fw_dDv`uQRmbf22&M9^G}VA}ub?~NUQzS9S--EsK&=(fYpSD^B4x6{v8 zptyVunoj}6XPD(HaGVNQz66h#IQ@Km-0A0=(@sC%o_G5Bpz(ms!^VR)@Bcgge1D$l z=fTECn*)svHgEqk{(SSB@#pLBj6Yw2_78&YpaG?&bkIH-rk^iC_uKYE&TDv)EHd%M zWazmK(-G?eUPk?&{t~oT2DDEfG_T$bxo6TxDKc_xD7 z!R^oGj6WZO&S72b`11(JP5&K!g2s$rM1$I&Ak6jpC1}4W(q2)Fx*W8|`Z07~*Pr3% zOVC<1bB3Rw`W>|2|7E(kXaXZ3o?F#Q5`JyW`IX z&5l2lSsH?#8vL978Z^h{4Y|kVC1^hpbd4FP{>xy1)O(;couGLY&>lw4fB(fn?3eFB zes{3cWMwD>_2m}A>MoF9LHB%^J3!W$f$jnX&136B&%)70n#Zn3@?$mQ&xfEhM5`Tt zD)~d&CwoEeQ-|)s*GHPeHHPFHaD0O1ph5dZK=BG%(+67T2fH%`6tAGWQ$Xc_sUR%Ps3bYZtiIMZQ7j!NdG?)HV z9yBKE@Dnt*0$w8pnukb7@((w|&lgDdp)>`6){`*oY=*8)YXkWW6i%S<0?kE$?sSlM z*a^A|5WF@GHU}Kf`13_Hxfc>VZ}O4B5WM#dG@oM0VAuefV*;@S84N*Zs-Ww6z$~wYY{p~Iy&9ml zQlsQVP~Y8y33P`i1Nh!l(4L-0iy1&`?k8|CN19X;b#VGLl9_g4YZg2g*|w! z{R9q1>4~8EJ`T`*4eAU(*J}Nn4!=Vaw2q&f;pankho2xff&2#wr@c`BH8A`z|6A<} zzw;98H%kUX2I!m-haiLD0+`=884ME`7(!SX7)0Lu|1XZL?=k4^O|X9;Zqb0c1+)(d zbg$;4WF-H9`o$ps2s8X#!QK$`LYrYHcwe?Y)ITq!CxXTfR)E%J%QO6}#N{6aNPL0( z(@87;ILd&-_5>(?KxKn6Jc?8N= z(7Q}*z-~awQ#jme2UbVCxyoSw6E;^BtPaUs*!{4~3_l<8GwgiC&G7RjKPVqN{N(t1 zzXLSa49btl=@WD>%R_#Loe!8De!lznfBF;9eU>r|MK9RrOTA=Zn4sAxIq{`3!%t79 zh9J;=#Grd%K=;8sPG*=0mUon$2)f^9CFt%VVTPZck_|yGwHbDT&-u`2*a=o6DK`;x zw}U5RL(ofk(7kUALR&RKagE4dxZ+O)d`AqjAF-zgJ9KrhxC7;JP`(2Bi_u}{3x0;3 zFZdmHzUFrLsl(6^l=(Nl!=8~NJCT7QB{GmfYt<>ya3Ux422HN3?X1PCqp3vGed|J1A_>teEF};@Dus2UU(jCl$!{; z0~K^u2I%gh6C98{2reV_8Frok?;Vf_=fMnU9&Fb9HyzYYcnD47&%u5~iYHjOg7PBt zexHZXyNp2hpK^f0n4Mwg-v9rngX*4#><&9YVHOGEb36P5shtUqE2MCPnTaQ^cvu+( zv4tCQJgxZ0ZU!_Boi$i1NbQ!kl8chx}G20-KKC9}g$9!5@XymrFk36!>2 z89su>Q^5AKJN)$d{~r>Lps-vg@VJF zpJC@W(3%ErNLuD$WhlhvR#2V?jlm+<{h+e}VfpQ$GQ-6G?4WTc`Bk>2pt{}RCn;s% zDs+G0C2iy91Nhm#o5il z!0;2JZR5;v5p@3)IDSF%BTI8R!&;^X=UrZ zPnuk>KXKM_&h}c)6?UW=HKYc9Dl1Xzh>sp(oj7u1-c(5r;(wM z!>~)ri;+9qOOQcGQ}L7(10$!_e`jc&1oI;_j=^r{cKCVY|NrSA_6uePEl~Wv0G%Jl z&hYcn|Nr1SxIy9!jhw5H;|vyGAb)}K)m-&|)4kRIO=sZ29bX`ICYArDKY-egVxBY8 z#lO`Y@UjZrW)x=l`9z%I=TmWqpP+UaDBXeF_sE*z=VN<@pHGw-CxXiiMumwl)Is|) z!R5(MaQiBn0kY3A9$KzADozCTCo(|o9nc!E!weJuOEdiZFVFB3R9HwSI{) zOaaBy1O5ZH42%u7@|+Am<#`!?K9E0P%fQ)S3#J=eZ2nezto-lHG!b-W)qiK!i+}Qk zSN^RQSqVA|@*!vrO5XuAMz-~Db;!y;`N1pyJF|k-g3eV0tsD7Y&+zkqGs92KgA5Zv z^%$sa2|Aw)bWRy~jf*nm>`l=6fmLh_Auqt^F*^L@kaYOTQ2Em4fpvo|=)TK`P3WD}(f%|J8yciWGzKUn~sm0k4^eUO*XBSID(5ur7JG($Ys#fzIXtt>>7|@Y8{TVXH7`JO(rdA`O~vVc5zKS`Q}e@bkH` z!_Oz6eYDd-YZf7U_y2b@fcNq%GJxju) z=seB`pm{83CPW;9`a0gwcm&l~{tQ1)urvg{Sj?~!Tt~<=?0m5t8lMLhCxYq_P@f!p z{~2g4S~SB?Q2f1NclZgaPhZJ9fai2T>&>1TJN$g7@9^_%Bg4c4j1E5!vO4@cBmLl2r4s%H3knt@?Mwxj99*UF4P zPlNVpt26%e=4=Rh9Sl9MESw3n$81BkquE5zUDVp3`-MSg=G%kzw1L--nm(QmSvwC} zTmOieb7HCy!<3iZ4nIL-N1(Ni8jKuWp!FZ1vszv-Fl+(sQvj{q0j7Y0Sm4{s2;B_0&gEeUNd%>@cF3KTpt~X0 zGBZp8nFF#LG^PZ)Qx>N5RGuNsL)aPhY>%rzb{(O{P~bs zUJEqF@|0PA6}bFf>|^;doda@aUv-1+i^J@eFAlp~zA$Il`JnoM?Stk9TMy9MRda`( zptHU~VhW56wi;N{9LTSnpt=uq{)(i-&l8}#uRv#7g6aU!cq*v;f6NB%FTm^g`=D~A zAqaFIyarc8(2LWIJHhq&c}7Uz!BJ`Ai`NW4J3w{(dxoD6l-VXe5QeNd1D$;U8arw< zg0v|?{RvQe0#x>a&KsB^$}k1A?*Vj%3v9hyff2)$C!qaR;-LFM9e+Mzcl`OdnH5oA zZHBsMJHyWmkb8<5A@x)_l6&?;-E)}Xr#lzJ6j1zXEM%Cd(0It^L2!dD1M30X2jLC2 zpnL2%0vSH$FfoLH&Y%Ic2|1V;w!C0=`1x$Q!_TLndv2FI{Cu+6sq!RfPya!siQv0t zLH*qM3_l;ucKG>tzQfN>Xgh`hRNpp(?u5pj2LCs+T>O(Su<~!U;K~Q;3_l-2&*}lS zK|uGGLB_%YSN_QlSoy!11>Amlp^hl4otPM=fcP&#=Ws|f`~>c=IT%7feFD&3i=K@P6TJi-euB(84LbXcQDNe1cZQ$Z zpgP!_;U_mgs7_(nc^Y)5?|cx=@FDx4@wH0i97s!)Qr?tHio8KbB3Q9 z{0%`bia~9vhM*VaAe!L=$3f+ZptFX+dCQsM=QU1-DOkfC6lTH^T{J+Ve8}{BI9BM+Mpj291dbgU5${g7PD{ z4a|+!1{Qbt3F;ri<4C%}7PdxfJ|n{vQ2c`WBO0h};0xe3uspO447zhupdsj$H?$4x z4{ifr@N!g{_)44M=POVf7<4``^xP468yK`VhZ!kOm>qsT2i?2P?(p*gXs$zANp9jm%uyX|ygDEJUL31jvnB`Y-GctVSIM_7{wny+$w8PKG@eV&9=`;L% zY|QZU0rYO^gB%P~9)j|Ly2H=Mpu8;X@bkbw(3lXzPH^65ci8zr`G75~zCw2I|7K9% zlyfC$?H9Q3D$lU<5om5goZ;saX@;Lq5%%!Za)4h9AR&&t(1Ky7XYM)_+Xvmb-*fCbf2pm`fm`a%oKTYvsT z`ti{4g!xg8fk6Zw57G`lLGG*m_kTL5|I6UWU?~T>_W;yK1KqXF?eLT5|NrTd3=AUA z)E$04Rd)CZIu8ikFPC@t`4FoAg)`&C|Jn>c|LZgS{BO(v9(Mw*m3z_bX!$@K5x(F) zkF*15jolXT8UM@;K^lw<;59#gt36l#Z-(}*nL&MPp_PBDg;zc>XW01=bbgyTXbhQC zi?!Ba@>6#3exwT=2UWo57;%8+DUkQ+Fhlm~fZ8#UTK}el>JgCtUV`>$gZ3)99{{yk zHgGhuO$7D#A2c&f1eI5yw$DRxhMlmpqd@UpWB_R+%u@b09WXcJNyL8i97s^hw5Qa{5KuczA!I=(4Un4O^1}J!7Kmd2d(_i3>hEz?+hBV zWdV(Y?0m@1@Dns<{#cq}=M#B`olk`sem(>BbJ-nsg7WPv&{^N0a#bEYo@Dm7+GXW` zXUN_LpbK7;OG1*Zjdhn%bpnadgka`g`ZUic?Pcblr zK<0|VR{qHkUHShoBrSpFlR3{(!l%mS4mu)Yx3oz2dc56mHD8pxesF>!~Tpt}TKfzGT1?KfM_ z@Kb^JfUN>&gY8Su+NW@apDzwGS%UVegVuV$!Vg>r2|N6J3A&dDbnYtXtW|b~pD&%A zEME#U?92eggRldrpJM_kH_+l5mQL6~`+pdIYOsRNas{=?P}RZb*+KmxXxrj}u*1)K zA%-cS_0OQPOe2wDq9&-_0NTF~YHR2-fbJXK3LbY6XV@tYifhpRRd#TB02dbo#S^Hl zD(&#|nYhDG(7tofxY>)x3=?7Fte|-zZ1Mg=+0hadh7ZIYb|TNe!`efz{t2jF2hCGI zXl4ZW?Lg%{s9(pb&oBklZUnV0p6WaNJm}0-Wrm+#ypXm$=+2Lq@ksuYhx$9(;V0;9J;(Ip8`4I9 zrtR?a38=mVoeh!9G!fJm{2$El^M5#In-G*XUo3XAd?C-U^Cf7Ht-Qld@H~qwgAiz* zFN1->6g1BVnj?I`4+=<<41Zdn4 zybg|8eif+PSOXf51MMeP2e%1d_cAktfWm3H{=exbKzpPQYEJ~MvFiY>Wth$I6O`9L z=OrG~{Wl%7{us1o;6*>f&xey4e%k5(o9@8g5OftL2O2wpj(?hi8Cj155?wVbm-arLU);V0-WGFW~F_1|8B&IVr(9nXN~^Z(Aw zmNKBU2-+JejwuJu5Jw}J0 zx~vXAbvPY~2@z-bsmsdnQ-_n`r#3IcPc1}^ND2U;Vo$qVX}a=iwv`2fxFJ!48wS|)<}vds)XAGS06{HgnIx&vcF&;*@-(;rkb z{Crr?@Ni|?E$ObK>dIqkQ#Q# zIn$4r9ey?nGE4!DA%ND5f!58q=z{VmT7LrROzxM=tP@{?+V#*eZ_s!js6GYtlR;x& z;C7}qXnj27TtxSXM17;RPABmq~CkF?_51=_)O+BBLKG1Kl{qM~16E?o`5OnrEsD4H3=h~|Nn+_W<0PP_J?fV7YH3+IxI+%WJ z2hBNx@)p?r%nU!*tNsI*mmqO)ea7tY^VMXBpInSw-42Y9cHOJlpmYyPgP{Bjsw1>q_ zmUIRkw<6R|o2^4yJM9tM5O1e})_(9afcnwkeX*di9R|kqc?=N>e2f+bdI~ZN{Wuxa z&NU3v_O#IjB523{m@Xy~9rq0f(PlJm5V0nv0S1HOI!zSuYkd z{0tXnnDSsb1NiRb>PJXM*5RxF@aEZa;(Wf_Z|EAB9`#1do=+2S`hKZoI zGKa0hPYz#(kD#@8Cqa7_52{WCo#g_$)9fUBLl9`+$II^wKOcT}`1$BNXl{f-$XTZ$ zNQJQ>h?S|~5^KVvPs`XFF0na0`_%dS|MXX&@T-T+D}wvppgRwKL(bKB3R<&`b~l=n zZbK04+|eif3_tl)|4j$Y&4TwJOa`s_=U4^0M*+--o=F5d7Z6l-y$0<)g5FgKo5Sbe zW%#Hh!w~WW)c&h>0G|gBx~J*{Xm8&^)rp{c3SZo3_;~^}mIfLJf6VX`bcguE#|}Ra z={5vCS`9gG?D2Yrov&2>O@CeP@bgu*!_SxgpnGW?em+|5u=DYHhn*nvvjrV~zK(|O z6}Zmu6Lg0aY`^Ypm4DM;g4_@d+EbJH1GHzCqmf}EXio`j-!C})bs0V$1oc(o9e#3v z(#&~CJicgVvwRMkZ*O+9*T3o{~a zp0PmU#`^dF=`TR{mp^9!@7o65%lQ(tZ(G{&=PJ+|8AsEJp!4TXu{8v}VrTs61zJxd z%(T-Bw2nrcX(vRD*+kHOQ!S>3An+WpJZOJ6Xg(g?KA8l%2N!$~B&aVBn$vZ6_zB9J z@Of!azaMnp3aGvQ95hem@bd-uZWW~UBCt7lXDsVQkmumV8GnNO@JihAC#X&LQW~@` zmf`1W&>R(Ly@)z=4qh9&UL+bi2OrP06Qag!;%j5ZpWyW(=8QjISu_58X%AiZ06L2U zHV3cFIq{|@=*$a{TS0Dyu6sb9g9q&+a>ks42dy!AyBu==;~RU(Ju9z3ZEd{OnzR;b%`R?`)75Xv_*!R)E?u;4}}qYY}uu0O-6+(EOsh!%xs19iTBO zQ2R{_)aI54-Phsp^Ody2PtYByNsJCZwQHGXJ1}y0GxBnF`+)KkKST|<%XISxjyZVg6;pa0RyN_cx7X}ktBUjsh> zMjkX@_hUPV&(X;6@x}7_Qs8w%@(kep9xvp<>oLGj@O`ZL{L8y)R$rg_1T%_SAp1|c~nrH z#K6eejnZz1_A5bZKyAo}RH*+Rg8B-ey(G$@c_r-iA8f7%G!FJqnBnImafY9dr5S!c zk!Se%6qMFLeIZbK0L_Vk&Q%26Z39~40-F2LX7~vj?*fIfr4Yjukh?)+9H9Ah*jlm% z1_sD@89#J9$r*I!4g+W&1TGF9PXf&^Dm(lHjjw~}eL>@aXzg9B<7kf^EfM2INb@Mj zYZO80z?$LbBYTFQkDVEQKIv!J`4m+4fbIYXe}+~Fsv zUxe--P~LjLe!vzqp3hLJxd+sr1NY078GarIm2IGLTz`h2pfR5Zpfi|)LF;!>*EJGd z1}TzN22Icer44y#+Q420P0++r26@Q-n+_Ul0`=)Wgh0z6#=%(zf%cm}WaiX*#7(#j zPOUO1>L=u!!@*bvJvC0!FBivDw8xo`%2oubH)=m9M!>d#-On~ z(0w=_)(t@~K=lQ{ z1saP1t%U>m6;x(`%EMQnH6hFlKQ)odDo{P1%m6+c8&nRxILtJ$#Q*XMdqL$GsH_InVIcSTGyHr2Dr@~Q&HE4CX8`gi`dA>yOwd>$Xzw&={nG^X#XK-tbU2~Kk(Wa zkXy7^LFZ^6uw|%RWdj|XhK|)E_9w&ZRdI%&12I= zH&zcCD+8_nWq0@qp6_ON_z9Yaf{%&ODgE|*M@_#q-%-dS-rM)1BUz1MUc2F+1&f!4VF zgs(pXt*>H-?3shCZ}D3B|1e|@58PH@clZg~3j`{kLF*PE>z$C)fc7@?LiB^`V^BQ~ z-apaUXaiaY2NL4|t!aVHwL;hFg3fdWojv<_G2_IQpfmRyg(kiZiIx`l+f?kg^{X-_Q6Rem)m=0N;zo(0I`1fp~*0 zsQm;Q8(?7s-7(8B@xM63PuP4fXuT3F?St2ZJa(`IoeTb;`H;;6;RajKzBy=l2;TFJ z9zL*oHx88cK;s+S4nGwbL2JBWYk&~p1YchWY6BpxV+DmVXiW?9Tr#=y-yNWRqg0yz zJ}>!iI;af@8p{H?2R#3sscnH;ry|xpVyjahD>M9j0vewIwR1r8;L;9|F;R2KxC`>Q z6R7V2DpNr9JZO&|vK*-W0cwYU+6tidBdEOq8jA#_$yK0s256lxXzdTE{S7TUKz$3) z7#RAzg*_;YKy5B@ho2stpm9P_8-wdLxLpNmV}a+(89u%Rt;Ghdr2?&62CvHh7}QRK&Cy@^`hPkoor2qA><&M7sxnLg zt?>k@2Zt+YEE0Vl9l8b@Tl+SaRec-t&kb8o`Wev79OwjZPnnOS?Z$SM(xO+hBpFnQ8K3@v9-vGG`bd&&{ zGvM$Oqz7~_EzIs}705b$P&){euR!Cpx=hghU*NT~4nIL_-9h8aAoqdSAT0#-!x=t; z#(N=cd+6Ch(%|*=KlAt?Yg$14K9C-enV@x9ptCMv_9m!++HFXEKUiM|x)vU^zUMJN z19;6W=nNG|f7#*ZLuH1akJK4{g3crY?SZKQrBP{ypWuBEpz)u_4xshHKVK|numt5% z&>k1$^K{_z`OaMM`;s1m?qtqp`1v%S;paop{3~dFE*-RIsA1A8&|V(UJpXZqpAVW@ z;P(XSsxVA>1zK|hy4NiEfb9eC23y!#@t4Yw{r|7p8GeHHRe;7iU-mQn1l`{Z+V2dW zPh{kn__~+@vPZofy3hVI!%lC|zPRrU&^bqqiLdJ!es+WQT7%A01fBbQo#E%p>kioO zPVxuOyS)bA0|J_Rz6_a1UJ2SCDabt$bjB+9yy5c^hOMAB-~)Hi9y#WTkDFO0E>&Wf@&aUDG~^x-&{)>PW|oN)1OHD4pF7ULum!ZQ z=)W`Sng@^?@Ho|U&|D(p&ljLQz|8CuLG6FoK9bwY3{$}7f$qnK-p5o8GS{8~w8nbN z1AB*`56r>+C=rml$IR>#LG$j9o;&=s0L=p!L)95W)Xf9UrGfU9$2np!HUu^>m;)j}@T1B0%k- zcn9#EwmyswKRMqzOv_Mr~m)OLH816Ffy2d@9tq{pZNH( z!_OzrL3gP!t^&;=g4TP-zxg*E6i#uVHRqsvZa5+HvY@sYto^nYw67B+2P(Tj<3fs{ z`*<9Fg4W!F)UD!V2zkj3?lXJJxEWP*;eh5`8OTZHvyGPps_Yk zT!7YOdhv31b1-th29-&#v_WUtGlI?!fw&8FMm=auTAlGH=&scl>W<*~_!st&v-m*v zg53dXbAtLojGV8*?qGNL`4m)NTRZ-IXb*7*GxYA@Su)Uj*0mjfz67074>}`2+VST@ zdB>j*oEd*UbZ7jzhL>T=OLx#cmkmLTwVbneXMxIh`Bg7KQyGYQHwkDHk$J`8sF`6%4s zXC7$$*%+$c7*jpy-a*ir0Yv2&&>RHl985y_1vEFx$^hQW1Dfvzjs1h#=w#;?d(!gD z3Q&Fl-J8(NH1Tn;!%xt8ouK*$mR}~n2CZ2{4L492fci3^Iu4YEQ1XpEWL*NN4hEeS z4ywy>=9|UPe6yV4=PS@U4A8oU)u6L?8GeH1EI?+Hly6o$`~=kzd@E7^Z;I zKXQI~4od$d)o zOQF;&Sn>(zy!R6f3}$52D}?jOW#oE=P(C^NYG~&Zl|hnEn25+HB53(U8CO1m?em1T zmBDjsp!qRqpO^_`4!Ays)Kh|)pg2U@_X!(sRA%@I+9L&Ot8hT?0|A`@3)-`P0(6Ec z%Df?B%nUTA1sY?!?(=^-2Lt0r@Z1n+EC$&O&^?wQGeGz2Lie2itwxvuI`a#3k0to5 zRC|V>pn27Y_Mo~6p$6nG(AnXjeIc;E255g8xJ?B*8v#7m%kc3mXiNw+cBJg^(^HXQ zBB=fFikso5Dl6y?0fvuH*um|`3*a^lXg>$23V!SAoX1K;xyLHVw=j_dxA3(3~-Jya}|v2DA?Y*^ltKRc?l#$o)3h`YEjA zDWEt7ji*EBS0xp}`v<`Lr%~ouLGjJZxN0&t!<2_0Hh7;qWUUjdkHw-0=~sfz(*%wG zqs*N9}uO9u6CL3xHjmcx%hR>BWF4$dsU3eFdAum$xoVEH%^6hENz zFQ8`(fbz2jC&N$B9%2xUJdXPibmj!8@9quC&rBb6LHP+Z#|zERq?iR7GkqWo*((Cd z+aSBJ*$H+ls2>7KbD%v!{E&W{F9$;i$P7?_0JJ_8G-tuh(GbKav%rsmMIx?;y&>ow zGmq8^}o}1yPHbdIH9A1~pAUa$1>?~e}w0YSdc~|K&q|IBacwrVu zeUD-Ptn(m!hP|`68PevRV`TW4&DcAuL6*ZWK~};KWB{ zk@jpM%>#1^9=OH9(GbMI$oU#R4~#U|`T%^E7sF1_S|ZSWV^2Z-4p4jD+TkZ??>qR+ zx^mEYqD&J(dsATjjGyw*GyOpGk zp!ptXKb_g(=Tp!*P0%~2LH!r!ryl0%;e4~ve-<$^J0}}F0n>T@cqmQG%K_Jg)fcAiZ z`Wxm9JMrZgcz*+wH$ZI=7P?ML#hLBfbu2@d3mxIfxMjVuoG17!^hfW8H7Q5wTP_;H9%`u z8JP;f!zyGtN=5M}K9ChJg(Ak%QEB{stVV(Pb zq6|4}4?I>6TQdSWyC)h^mxIp+P%$#>z69N6ZH+i1@l`YEd}VN3 zW9xsII5U$a=*|Vu8MUBsTJSzxBstL8-JpKpb9ING&p_uTz|O2_2dzOuJ&Or+)&TPP zMzAxO9>_P?zF=mue8KDl*;gcg!1jT9gDq%ZeFr1t>=4jB^q@XBXuJS4|6~v9<2f=| z{;dvL`6oYc<^RKwvqNF?w6L|=MsNR52d}9Cog)dl^82U|aJ>;kxt7GKANeuz}7v1hr>D;fc2He6I|ibtZV$ov)XH z)jde-&S7;UXzT`dMjgJnYsQ8k(A;$c2g4Lt-yS@!MPTk4eoh^U_H3k+J&#DW2TwSM zVhd*q$E-ko4O)y%b%N&C(Z;6G*GaAf@0G_~CwZHH@Qh6fy+IqB0*x1e&#^^}$->hh zjoX3wte`V?5$(WiR?K$bdC*`=Vh(x7rn8g!o|Blz5y z2_UzE_85ciu;X|5sR44^LMHIp#Go->$lmydAke;g(B2!+x{jCr3_m$p8iGLg9)j+M zsFwzk$-2 zDEF0+81Bg+zd*x16jW}2&R5}w-fKcZxT~UvI~ChCsxtW7H7=kv&uHzMJ<^bNO|TTA zT@w!)j}``b&W+c=;_&n$>~ z_R436pWu5m1s#6Ad<`0B=6nr0#|u;!V5oiX@RM^P!^D@*8Gdqzg4e=qeevGm=gZ%q zHRK0u85)~xo`CM~e(wO52d!xUuRC7M`13#L4%5YsKOZf3{P{SU2ef{EgC^*Flzv9Y z*&CA?f35`Izs3x`e~o!3xL$D8ocMA!@zmTCxM!E!!};w#XZ(+)phzjpZf>bS#C&^_89zk}8aa)8$6h|ib$ zU(fjSe>3Dx(MQdWKOZ}DPkfcl`155x9lZT|3Qq+;AT1hRaYltcJQ_J(3%4L)~zn z@#o9Oj6YvIXZ#6TiwJf@HN(%B^$ehUpSOU{0RWxVgL3W+NDg!+5$L|`W{00IL3dq4 z&v^1;Wta#)zvME*&sU%{3QeC8|No0W|LySe*>{JZPuDyAe6-o&=Zoi%az_hvrf@#P zPfbyWpA4)HKVKwsPW-RW`18Lp<4@2%MxeeX=>93#UN7+c;$lzB7ta}XzDQ@C$nf#J z&4c+3wlAz5A^QNIBhJ0WD8E4aeL?$&p=;dczWhHObdT~&Q2c}L=80zb>B$N`Cn+9E zCqwCUhMzC88GgQuclh}VbdFHE!_U{*4nINnH-OHLdj+~vIT)JP#27-rXI+5unl?PI zP2d3KHPAT|%8Wn3=OuyW+tnF=K2Uc2`B2^QCzC=$(4%a~{k)I!8FtPSLdt8P`5w@D zEZGh_ALl!O&(Z+rHEU>ILtB^EFZ6HvOVD{2*3i5Lx}OJhUXnAz&;P=V;B$+>N3)5qzC+XPZ^oZ5|AW>uGW~oR3_ULi zv&z5<=0``Y0r=seZe(GEY~fbLA- zXZV@G$kPov1BQ{2tNVpEXdR`)Po`SV*#^S@roVmf@bevLEhOj+Oi-BxI=cvzX89d{ zuI1(HUdhPt^QE@qPn0rC7^%z>X8@n)`5H8)Wk3eTgD*(d)04?2H{@#lYbM(~{?4?%afGRv=mn#;4rA>$9o`&CFzQ%Gw;K>H7q2(W{i>kxUr^n_3_8cPAqdnjxDL955@UQHbRQfq%6b0q^9(@enu5-w1l=zSx?{wh z;U{P489js*x~1Mq;b>-pz~E0Gff2DUGhJg z;V0;h9Z=t$3)H7YKd0rfljVcvQ#SDVVr$5GN#JwXL3eqA=8xqWc4~m`2bFi&2|ADT z#bQQF*qH=>t9@7gZ-(3t2b#YCttkbqX9o4dL3=Yndo-6lg{;r~pUh~9SbvVtH<;QE zVPgNLgXdCkv>i%Cpk+9yo`Rm)^Hvnnc4&dgA+;SqWj^RGfm#tn+o6*Wt?j@FE$2tu z4&Z%(pf%N?^$&#ZQ28T*IKPMYDbo2p1ny9IAwv53J-0=$wH-*jZwycUbQt6pa2bMB zKhdy_JVz9NI^Qjfna+)&>HHK-4k?}MfaDk(f({EK()oE_v~0FPDbgqakoi`7{x{RwK=+OYwWuG4tsLMvf>L;w;UojNJig94l zRV=}<0`)yOS7O_rN6I-)NuaeO+zdYl&Dp|4t~X&6W|#unrv%zV`Uq{k$rsR>?MUlQ zI6!ycT{MBLHv!%E1ip&_b-fAbt_)6Q#Cns*LZJE`b-fAbEL6~4uAs5-m!NyRKzqQ% z8GcgdE>RNO4$yUzpmQcba}$)Ds}DO%L++4$xXRgt`OF@z>z@sqtC%45VFA*hZ*9UlYTB@2!>Zik&5YX8*9iZ@6c<~9e zA0Kv4`Ge-;HZMSH6!{x$!FR}k&fU~!0N*?H0(6f&XrGKRXbl^~1dd4kiJ&nQ@EI7O zJ9I(!Y>PYmT(|1qbkH3ND0|{z>jaq@_C921*bB=u511YHK4f>;%b=ks_rjQI;)8yM zy)Pd#Li{4AH}RD{=x*kQpjV)=8*?PTfY$dz?^Xw$;o8C5aET+~!6%R#LFZ9}*4TsG z56fQ(@-SN z57;m?G~1xei9z?qgVN4pb|g0`Ga}ri&hQiLCT)hF9l;GjFQP$XZ4E)7Gg{zoGG_P* zb`vN)f!rj|06t$1biXC%1H_rMV0VGerxgaB0e1*|?+7^UfcWeOY(ee=-L(wb>yEsy z9)52HbiF>f90Zlc%p9w<1Q{lR*1Lhu5`x|32wJ}jPrsnCOHkUjXZZQbn&Btt{C&_E zAt>Lz1g)ttXZQ(9+o1gVK>2_zJbi=qqk!_P^Z{G&83Ec1KQlo4vq1Yupm&9KFhKJx zmUMn_C8*p&UbhT7!%A%B-)ixd4?y7qIx8TV8Ga64wgAJFC-M$IJ2V`Aa=c{(-wOx2 za~yO>@xye7pO3N~euB=T$^@;EXEdMq5_E@mFvHJG(EUoF_HsDG&z0#7K`%Em?92p} z#h|;Nw=?VnkG&t%oA?rR&PP1MPw;sT;*fD$(E3PTmVeV9%RBsh&F=6Md{!%{Z6l79 z79KNBd<_aaXNI3z84W?Nx*2wQf$kyeXV?i^7Y%Bs9{c=%I_Q4l_v{Wo-*G$qd@Jv; z^9|@8Bha}C&^v*^=if>*`~%$(q}$*`60;5yHk;U}?WBskAF>Q4ma$qdk)A^f2By2DS< zI&jc=|BtmDetLn^j>pRX&X9Ae;qF8(=h+?hzWmHM@j*SqUJQ4_%5G4)hnDHIaHj$; zcQP~l1(hkF@O;4R@E277Jg{f@i|)=9baLmn6`;I`6rQlU6Y0zra65q8;V0 z6G8Rk3#78+1t<+zgX=R$8_S;IC(d$2{(vpK&POUgz-662_-yD49H2BH%{EE#1|t9WAv?ogP?$etclgVo zktl~I|MLMm!(Wj82kZ`iITdy(R{97%EGL`^3fAm2!6TG~X=SQ5k z3c3RhG*-#bc)$j9t{+$}=#CZ8IS)Lb@e&R#(4FQ&{Gk08ko(IYHZx7+1DOE|cTn4p zr6Gu`k>Ml5!OmIx{{Np2G7q+=>;XS$y?Ud~-|E1XfARxX{%?lvJ48O05LBjv&Vd4* z(~We#=~q66DWG$fKx@6h?v!`<33jJb1Pu(5hQKzz`hBcL;>5*Q{jG#s=6-C@iLy1SbJ($@s-Q33gb@nGkywIF{8JN#sL z!jKQzcK`|-(3;ejpt}%3>kmQaE`iRc0i7=hxoZ%7k2WZ6y#U>vDazRmI&%dy_XfJF z`GInS?Tf>XmKux->WK9m}e6;8P|BHj} z>w%oP$vp8fnRkal zW59eXLFcSI)Mxnl2zn0`=?Ky!YN z-5GX1%y#(sDBt1dRtAPC91IK}LFc+;aWjN~&Rt|+bok3~BQcI6kzpdJKgr1I@K@yocKG=y-QnlsWTuJmy4@dIuLm>y)U0R-dbyfmC-}VC_0anKrvAj2(F{Mq^?W?! zo&ag4f8aX!g}cK}Q2qLfnNy3C^OTfkEtfR-+!j!q5;U)?4XHPufYyBSg3fYh0I%_&DjJ3dmitt?ZEXjG%EY4pGi-4n_w{(7AV@x*ybT1D)#%vKw?)Bj~KJ zY|!0xpmo%seNfObvHPI2D?odZwH}A`~;s*=_V}_p(%^7|! zVPKd7J}(-ScDNyF>yf#`Pj%4PB`6;;Fnr_!-3tgh(+p)!8F3a7sB8tf6YfuDw0Ka4 z`cs|ZC+Lhg&{=VdsvCkHGc^P$gW>@+J_0)H1r!gw4nIM84cu>h%wP#S^8uv|4eMip z$|!Y)pN~LyI)m;#1FbOz-OUcV-_)DoC#dfWPUF%HKS5;{D6NC`=79EmGB7kuLhggU zhEW*4SF^JXdDgX zM@9!r4-N)1a6JuLo1p9fzTX)meON=yL^=!a5!B49Z2zW%?ivHH0|4FUCd$>#!RoLR zls_IaGlXE6%?^)~3ml;SnK9ICq%-fBY9V=JAI!b%4nH|XIlDC!873;QI{aj0h1@Us z*x%u&_wT>c7celGf%_kb= z&Y*Sz|H{AB0xLmj|A9Q{E>+MS7V?mD1{X6=

eV#JS+%r|$uR#HH}!)2nobpD!OXO?(B~&jCG?;XmvS%jUB-FPa%AJ^-B` zV0^$9R40PhrGV;0e`wz@7~Hnoz`Kx@pOGIMCjfWjPfjC$ z`Ti^aJ7a0*Y-ZT|a67}^N4pvJKHkr;_sL;~y-$xb?0vD=ap#NE3_D*ecij2nJj2cx zs~vZ~xXiHg#d^n`FRnA}e6iVa=Zo76J6~*f-1*`@!_JrY9d^FD?XdIpb%&jAE<5ae zd){H^yVDLk9~^hs`|z;C-bec#_CDV2u=mM!hrLfXJM0CWzx6bmaqp9S#=Vb=8TURa zXWaX+nsM)gdd9u)f*E(d4QJf>CYo{Q>v+bUuaX&ezD#G_`F}CP&;QGzdvc)n0fP2` zya;#r30nUHF6%fMKAsX}2mzT78b<()>4Dn);Io|F9e%>@?Bn2M__&H6NgZ_T0F)oV zc?Gm*L?5!Jr;8W5r-zw!A_p%^H)sqx12ldEDnmeZ;cRF*0*d?j3_l-0&k1vCZwPv% z&#)5|pP;@1C_bM`GyGi63c0HWbPfh6ojlTa*!fi2;pY?3S;d?z-LF9VSwLr(O=tM| zV6wx{htnN?HZwK^&1C&I9kjOyU0)YtLr`}O*X&n|Stoiy@0kYgCF^JS`2c$6a5Gaw zP$x*gKImL?(0y1AKSB0_?$HJ9J$umX@bh82!%t9s1R56syOo>aXAQ`$><&Ml=sWy; z3QC8ddS4i#*P$|H&jWXcy|0{ECwlR+bia~k_=$d=(qZO?plnt|*$=W4=2!Tcd&Lev zAC^1(RAy-iN&wks54lJ1fxE+A&|PDSm05cjITYm>7#+alpbU%*dqHhD&^bKtJOGWq z37|Y+?eG(HW;I;Snc*iW4b+3~(uSTb4$3zmdD#B%JW!bwe8BcWaD(jwXUDw{-5vKn z@^;+&*xzw4M%%QR;UZ|94phE@>gYGj99plL7IZEV_>N?8hMk}@j6r!ACJw%fTbyC%1969)|C<@WYm)vqvtIm@FS7D)wdl$h z$t)8=?I~DW7-Z*5W)3ZI8VB9G2)b_?)D{HQ5#YKSv`3fWV-G0Zg7%Jq?i*Hj`1u-i zpV4EMiJ&uJU(aXw$?=e3;{WLkKmUXFeNG3Jbq$v|K;zxeH2uGy;phL!3_o9i?na%= z@biB=!%xs%4hpQGaW&?N53Cz(LFZ6Duy3#hr6Eun2lahkbc4)d*ucSPI1#jOZUu8g z5a_&{2iXokLH9^J0;RKVho3A<|4j$QBa1A!Ox(cX$S{#Zkfj?GX7K!#49#2V3_l+v zJNyKVoiX(`1U+VJ2s*(4I)jfx>oNsus2eaW4_kjnWUdKc3 zFb1tv1m9s14p|Ecsuv#UAFzFSm~kSwF3>(;3+f-i#>6^6=k_!jg8MDtK0Z>L0d(Iq zs6B9D$-n8Kvko~tI)Yv>E+_(>WimVH-*oVqo}vsN89;Xeh&%iQ)z6@`2TFr4q45Vw zw|}ccSN_QlS^2-26_N%HgVKQL%D>fOD_<;TnFt!khqYN>f$MGgRiHaGyd4=PzLsbB z>BZ^r^E5+4&>LoMEpOg4v$AV>W_vMmzXsh?@)C5f6{t)D-O&k356J0+k0Au)M$n#I z(D~pDj0_VP4zNvh`~QD>0|SFO=pO2iOa4v&`TxK86LW{3pnM1F1OK1T@Do%fgYKz^ zkEMaq4yc@lrmI)Vtl;zpy3_u}Y=)n(GzCsWhnXjW(hfKcIXBq8=m(7nHUxpw&}3K| zGMWfFBgq3auMRq&6Ixb)?+l;p@UwWyzv)ku@uZ(@X!^-#_z6#c6B~jSBc&f_Z0QGd zZvnJV_c|FV{iHMegr%!j(V#t{i1hTp_<${FtO=BEKxqloM~9U!@bm*}&w|DYk=wJu z4nH4fwjR2W%A-81fVt z)Z`c$)a4$|X4uQXkT#EjA${HhZ-&1wyBT(Z#`Iq?Gfnhjtlb0(D@KV1Kg9%wJco%4 zyb3V2&J2Gas2{LpxTBc&>M$c%twSS&FWf9^hQF_@9e%#9cG&rPHN#GDevW1UonQL% zl`}*=*ew!`ehdkWd5#kqc;R}r8UDWXX4nauX9e4zz>uftz>vqlpeDz_pf2~on_(~9 z9m))UL1#^Y+yNQ~wx0NB|@1QUTg*SL!QW-o}8w9Qgl_B>kfyY-sbN`@r7pQL!onH-G{BJtw z3=5S01!9bNCn!8X{q+~@4m&v+8H8TgGfjMH&twT2*Y09q*x=P`1fEv~&k+-tSJhx{ zxWw^*ym?jd7zk*N7|VQ<>S9p1B8?X_GhT$vYryV+0*z_H!u2(?1N@%I*PwOX@}Rxm z3_n5lN5c9C;4}(4zrB`oHn^WJ47vLod}cE2u4re*ix0RN_CDli*b7Q$kHs1GK9OeF z`&1rOUO4OprLjli4tpO9JM4YJ@38kNx5HlW9mn1bJD)l;?0w?Su=lYy!(Q+j4r_*; zkBk}iJ~U_8`@ouEFQ`5D)Y@S$Gl#0&18;}DPs|P?iIYFaOtO*!f7AVednAhP@B88TO*)9q2vR(6wE#a010KsIU5} znF(}W(FBf-MiXBIL;H5&3_n5h$y%Vk;(-UBKzsOKGc!%>VPKfhbI@qw8)t@}YnU5? z-ncXTd~MC}6Ex3`JU{SK9NHH}o^Mn?VEeKevR(yzHVo2yBj~;)aQzLPYXrA%aK!zx zMX>aXv_1^B&J!(PfyO>S`RXMz^F-JfBxp}JXb;D$!%%-)8czh3)u49$3(%hLV1}P? ze}^;teC>?nZ*Qo-{XyakKS66HKyzmQ?HRy*r;{*$Bh8n9%DR`ZH4(~?`Bkw0LHC(L z+vTwR8*qOML-R9IzRg$!TC*dsg}lcDlcYCk12Oaz_H z1WqTQxfk&GeuK?}=7Tn%v&%taBA_|w|43>4Z#BzGP&)&3<`npBLC}5Epz=?VVIt`M z8ql~W2dEreK3@vd#^Pk;x1f0j-w-g$-z(zytKPG0qGZLG5TzKO>XBA&8Ta;isl{Ll7q`!%ulmhM(|q9eUm% zXl?{F&iLy8|LLH6$R65*=GGx&R4YK|mWzYdQX%HtKx*%U)I!HlL1VL^@C2(B##DO= zq?VuI=K_#f{Fw5mK=RyBd2USk7s`wiVRN#ex&0HMxe(BP08sox&vtkL>gzzxe%kT? zyte_#z0C5fQ15ww&M$z*W7Qpgt^wH(ol5|n&j4x{XfQHtd7a7`mg5wi3cL8djgU-Dd zX873w@*imIp5Ngor*^|6(EW?BH59P?iflh9EI?@qR+fSKZs0Tq3U|;rBeT4g1_OiH zL(sWe;P6Md1%5_VGv~z@%q$aOV|=iC3m*qF?0gc=u=8m&!_H^%3_G8L)(wFAD!~pr zL1Ukwvob*UJiHNR{P|j(@#o8W4olGa6aTpxf4*eqnE0QW@#iaM#-A_Q8A0p0f?jen z{(Qym`12*VBWT=pLpG!N#Mkc`erB^Z1ik*u@Uxq*G3fPc#+|Q0_X@se+}X{*Fd^I1 zc;f5d3_rUW8-iZ{2c6f!`17SY2s{3S)uG^XUP1X4G{**--(%!_4Zc?p)bCVw{K-+7 z`J)rG_Yrijpfux8@H~$^RY$^ZZ2PeFJ1sXP4qf1ly!!+H7YI)C~ZCj^%HM9{8Z39V5?x*U<*1k>i>C$pL)jsr@shy*!kc* zIIWsJF?RU*|2V_X|EC##J`i^N`B2>P=cD5eKOdiV_$jsU-}D#v9e#q&3IwSGnf-r1 z!_WVq`yU^(O?6fZY#r7ig>;G-d%B*LYFSG4aJ@hMyTc&~Xh= zpR^m&2Yr#uHW4yT0hI%db%4%R0-wnbxpVG+HN(&U^$b51I1kvqU}m29z_`H{)Ng%Y z4juQfZm@k(4Q)@_OJW=@oI;b7~tK=8d)6z^oDd^dw16d5LNfr^9km$bvrxBQUxORtz2etIi1 zOw3|s_~^yR+x>=FepL@6?`tnco-R;+0*!Bg))0c~YF+5vF7R{r7#e~gX96SI(V(^f zD4l@X%b<3Xccc6d(Ab?0Bg03{gWa>T85llfGwMwQ&9AIxZ3ud8&hYb%vBS^T<_qQPoQ;YFF|XlpyQ0Mv>ASa*5iQsE1>&II7p)vl) zA|FtDAE_S&?XO^qgD0SI9MC*JBg0mZe?a%G$%E>3G6NrTR92kjqy%s3I$ zj)SeMYXjAxpt=B5b~}Uaz-9RPLfOd@bnnLs(EeL>hn=9d4k!#k=bVGuI}kR*Pc2Xz z1+|0)6@beivG|x1eOa!gB z&0uW^0bj-497O1SzwE#`xG)t!4N(9pn~Jd*+oqb3@nO zy4-`TUjw;^k&*MYxF0BNk>UfkFA_92!|w2tg%h;S0X{eQ0lt<8G~WYiPlDEzh&%jD z;%x|8%-9f=4RQ-~z7}-u5@^m6G(V0w|I>LTysdc{bT=~_%GwuD+Y#g!P`eYBcEE06 zXZQ&Y7j96Q!T@mxXpRWv4p2J<+V4HY+Yoe^2@)>p3`lo#@uP(cw0#U}tAXw^dIVjI z!~qH)&^f7`;IXD|P}}%#HPYH}(6|9V!%ol~AID$j!W?Gsy~jI2=aqxzRzd3>G=DM{ zzC1o(3N&`D$;cqY!N|$=f`P&OCBMT?4UvW*n7R`T4CX8h3?iWZIIPXd4!Vn$-(e@m zR;EJGIey6F3=f#)wP5Q0L+7}`eSU3*pRjcxpmrW;Z2@d-7IX(M=$u0>(D=L+7j$nLs1AaSyModyD4l@XuAp@^pgr-RyUal4$tn(pkSD?pKSA>qpmWSY zaSZOWJ6eIu&=sKciZs{V}VQsq? ziy0@v*3g0SCCJT>m^rodO8!j;x2Hkr6Vzq{<jz4EDE6bt!`EXXr7_SwQJ}d%&>h{N^aoCJp!O)JzoE?V6P|9MbMG9QpgXf5L zp!K=XwYOf34M7~dr)I&z5q#eZv-~RX{3IxD`5C}-0-*2$%_)KEJW#tD6vtdl3?bk# zcWsBC8VeaFDmyYxR1k%%LttWS2;ztZ?O}5G2^zx#r2$af!pfu9pthqqc&_dzD8GR8 zt03tIt;u@K%%P0H`-nrr1NneK>JjWk{N!2?jncX zN&Pw+vM%5?=JTNHkUNduPX>p#O#gA9V6 znHm=0vh0$ z>L((*8I(>zZe~Ywb1~G-NOLnzOB#Zl85@G${{1^0lrBN(T8ojR`y^{akS8Mp=zfTw zpz;kgkNq;6;V1IkAjVw~&^iEoca1T_&qwAA5WU6@KVRuPfXDDa^ZqaW9e#r1p@EUdA8- zif2%o0M!$q{wt^*18Pfx#*0Ap2Ph4k1eIa@(0B%gnK$Holc)Yj@oWus1M(cuQb;^6 z`1^PI8_@k@pt6J8;U_5lX>*>Mm0imYyR(w{A4g>nD}5h!_Stp|EJfV{XZSFw}C;B;U|dZ zbYz(Lax%kD4o3$|P&)~9f6xmC2GfVj9l-LSe$S)B+!Lpq{XhK+DDSNXt=(ao_^_Md z=Yz!@6FGRH?(Apyd7YVI3TV#r0W=9d!_GI=3_D-fGwcNI3xJ&;qzh_GG_!)!GboH<>7))6*8C1XCx81p{rP5xpU<{C z{Cv9G;pdb64nH3sb^wo)JUs32^TBzCpC6r_D?fC*S-$UgvwSz%&GPMZH_JD(-7H_v zce8wT-QnlU+YUcLV=2^f^Mln6Kfee&{QNBL@bkH}!_Q~(4nLnNJNyK#y9M|E^c{YF zOn2D%A=_c+`+SF;?}{CEzAbmy`35v+TJNy)m9xXom+qkTQw~2L9_F418e{)b&G_?k zJ>$>k&5S>vwKM*F+Rga$Nk8My$CDX^J6kw<%iQemhaE=SiZZ=WBK+vkL8=& zJeIHT^H{!`&-nA@V#c2@mNWk35P{@DP+kC?G5uh z9YN!zTS0ddzG!#+32Xa++8Lm6T#&mqg32Ri`Bnd&c_)I}a$o!%SN_RAyaF~B4r)t+ z+m4J5mY^|lP+sd`U@!%Zm&5uK;JE{KkefKWVPc?hbR@l%V7;~sLS*RO3DQf3zMoKi zTS;?k0|owUpunFEboQqM1#Si1SqdIwAT=G38z&UFbpXPZ9Xuw85;mYb^pf3SrzYot zD9u`dVA$SV21QL=d1fc5kA|M^kzB5G);faw%gU&2IM9B9^I!f> zul@3OI;g)4YI}nE%;2^Bstg|&fc9m`JN)DbWcc`ifgvOsG`^w^Ia43GU;j|r;pcyQ()(^ys`(49dUJo+OjX5L2S_e7RXqxrY*xqP=6wWg&_pg2LbH`Q8%Q~0!sI<#zqlFo>F=)=W^*g#c(0C&&c>D$V%ob31f%;pZHIlIP zfE=KEUqEZtA>*)HU;O^Rfny=xL{R6*j|1i5m!NyIL1V4@VE;kp3bh$_a!h0_^kQWQ0gYF`ad+7H znps}U<8OS2JR^5Dbd7Kac#W_;c#I2tcWDO$gBkMv$rtjFu`Wjjh7fVkUTJNIom#96 zg0I9Gz~ixAjSPhxOFN}rNHgqwA?>j9g)qddvkVL&_wAXlz7PiIuR@Ug577E&(D@6{ zu|1f(FM;|Vpz?#!Vdo3zxbJIuho3$S4MCZI<2&pbIl%7C`ODSO_5Z)=OK#Ad5=S;@ zjo3?mhMgV%*g@lxpfe3jk=+iO{{ihQbYy487VzY|NnRT3(&c%pgt=!J$1tL>@)?ZC(s@Z9d~uv%r!~y|AU_8) z`~>?MbSDaQZ9){X`@I={KJ;h!=>yXP^0PCju7;dz1zT_63)3U*@Dr3TAKEkgv}gP` z9aP?c+U^_-9Ip>BGK7Hh?prhP`so*-xkse+(>5?OKxH#@3|0>sZr-49gXYbMpMR$t zFfd#YU~>4$z$AYS%w|Jkb0M+$kk~> zL4uKi;Q#{zg9{@A!xRPvhBpih3 zFflM(VParlU}j*@VP;@hz|6q#fSG||3p)b?3kL&34F?0m0S*QR2{s0X6ix<)89WRO z415d>ESwAs4*U!ZGeCw5GBA_~GBCUlgxDp*z`&5hz`(EuYIg$z1H%Uf28IMih3uyK=A=a1RExXjgDYo zVBlb4V0giRsUDjc$czO@YC(EIVlWJH7l;iC7Z7d0$iTqB#K2&~Oj~@05n?{bewbY_ zHpu=Lj0_AKOoZ_Y2B;cr>amGI!wzH@HuGWPE1-Ha7#SE$7#J7~Bp4VXBp4V>qCcQ7z8EMa9}@L*$Lc)`KIpuxq!kipHs zaDs<{VF4clg9|?c!wY@}hBJZ;3@pM73|nLw7<3dE7+jPY7#dU<7*r$~7+5qI7+Opj z7(}cY81|?#FtFG&FdT4YU=ZFo4QuQ2qqbFbq-;V`HO1^#%h214HZUz#Vd}U+s;-K+s{mf$G|D_fPrJmLk5Nm4;k1~9xbH;B5h5{xA<_~`u7-ldrFiZRcna;p) z;y(k!0VW3KD~yZ`FPIpZzc4W}2rx4+bFeTnSTHj%PheqWh+t-5E@5M2XkcbwKElQb zYOgRmuro3oU}j)$;9z8U!OXyH!3m0G28KDDj0_ws49p4K5Pk+XBZC181M>rJMuq?u z2Ien3j0_bl49pjJ85tI^Ffd#2F)|!rVPM|E$H?%2g@HMQAEHk|fsuiMm4UfHfssLh zm4Vqn5h8v@iIKsBm4R7BnUNubm4SJVG9yC=D+BWrHAaRFAig>y!wpsj<^vjx3=C`x z%m!MF3>s_<%qz4QL3xpxL7R~wgN=b%!46{H3O7cE32Y3^cib5ncCaxpmlQHGJYZvB z<|tug;9zH97AR$8Fkok3R;XYE<$Y$6W=4hvb_V7L&5R5y*cq53S{WHGurn~%^fNO2 zU}s>~n8wJUz`?*AF_)3SgM)#&XE7r~0S5!K&T2-685|7E8#XY4+IGx4HZy|C1!j-k zj0^&t49qQi7#S=$8JHIwWn@U;WMIB=k&&T;lYx24eMW{2oD9q_9x*c9;ACJfc+AM~ zgOh=I&P#~<7rbO-P~c)r7*Fdq?SVld!lU{;V|Vu;{oU_Kzh#L&Raz}%w11ZumooH1o$Si#M} z{K1Tg;RHzD0+cct7@k-#F?`@=U>2}sVi4eAVAil=VzA(0V3x6FVo2a&VE$sw#L&UR zz`VhRiD3f|1G9rI6T<}_2IdS~CWa3@49p$25Oa9!m>2|j8JH*7LHIrnObiCR49qId zObijc49qi}nHVZ~8JI&{Ao4n{ObiQn8JGpUnHWy+GBE3eGBJGMWng|2$;2SR$G|)# znu)=IkAaydnTa8TkAXQMm5E^jh@Z#Au!E0*xg-x_jz9qu!wo(L<{br03_ti7m^+G? z7!>#!m~+aQ7(DnHm}@GT7z+3qmK&xV4hRM#BhP1f%!%)6T=67 z24<5wCI$fk2Ie<)5Oe3$Gci~QFfc1LFfl|3FfeavU}C5cU|<$$WCFFTWbM zF&q$JU_Q~p#PC9Zf!U&!iGf3qfw`lVi9thzU}7*3VPJmqfr%kNgn{|QXC{UM z5e8QQV{AOY}Ai}`x!^O<-0>tNKW)Ki%VD{l-W-t(CU_K$h%n%^Tz}zFm z%upf9z$_uk%&FCX;F)+JyF*CdnV_<&L#mpce&cNK#&CFmS&cOVno0%a(oPpV; zhnb;5oPoKdhnZo9I0N&X9%hCe;tb43dO$S`1H+phW`-N$49p_E5WY(}Y&Kzcj0!aquC37I=Uzo$pFhP=mdCFX7h7FPo%n9=# z;wkf(8E!~2Fqc62YZfvy{E%c|j#$OapdiJ-{9_d}gM$_J`z`TT?h2eq}1M?0c7KR^E49pr5EDQ?L49rg?Sr|N|8JIH^SQrYV z8JI(qSr}$WGcc#9vVbds392j%2c#L8H)yahypU#KzM>5g&(L9E5RhSDF41FQu#jP3 z?yz8CNRVM*F0f}|=#XJx-r~u^utA1_nJ0jS;f4$YvrHHZ1A{CBb3+6RgN7^vb4(Nq zLx3y;^O7VMh6-5*W`VCP3=3o#nE$A;GMtcQU^ek)W%vM+4`OAIkYixhDP?7FkYixp zQP0YdA;-Y1(!k2lAqR?IR)!6749qOESQ&1}F))kFVP#;DXJF=8&dQ)6&%i9Ok`?R^ zfpx450rCvYBAZwlD&!fM-)v@OSRl{9yk|Qr!wGo?=9(R>3?Jkfm?aLdGDs*eFfTa> z(I<0^mBB%QftlktD?@?;1M`m)tPC9r49q#FSs6AcFfboD&B|~=fq~iJEGxqg1qSAf z^Q;UCiVVyy7g-rR6d9N~uCOu`C^9hbxWdXXL6L#^!Btj<9f}OhJU3Vw9w;&}o7`e$ z;80><{%{9kpTS*L1_LDqW`TRG3=v8U%qQ-#GE^urFv~n-Wmo{BpRqEWP-0-#`N7KY zL5YERgBTlwgfauOi4_}zgE9kiN+=schB5=QKr9>B-$#9vVPl9;VPJMR#|CO=GF#kbV_2cWz|8Z3jp2d{ z1GCH*HijQ649s6d*clX58JOqjurqk5GBB%HvNIH@GBBSBV`rG5%D|kH$j)#;m4VqO zjh*3zDg(1kCOdl@Az^s2xv1f&+y}5FwkaTKH$f} z5TMP#{KAiep+K8~ImVxZVS+XTvqJy}!v<{z<|zRj3>UN+n12LtFnrKvVD1RyU=Yw@ zVCD$oU@*{OU^WQiU0~XwYR~R!HGsSOF4GE-l(l{6<=rJ%CWO6X< z&|_d$$l_qQp~t{%kJgW&;)F6Ln1FkoPQPy#VuqLhQdz<_~yLMaDBfB^%uLNy0Ng#iPzL=6YS z0+4tO2g3ma2Ih=f4u%&749rXFIT!>C8JOoZa4=XHg6d%oh6qCj<~NNT3=M`1%mpnR z3@Z#7n0Zx??gCW6$f%(ir4u%dB2Ih=K91I&w7??Sha4_63VPFi?b5?RN zXqYlE&sYNyw^+-;5Mau{T(NV_?3q9m3zSgM(p) z83S{`P7a0xW(>?SyEzzMm@zOPISi5iaF~NZz?^}3&rt~f%~1{p3v&kMg5war!wC+C z1ak)F6Q?*BI?NfEr<{R^e>ua!u)&;xx#k>%uW+7&;f6T_v(E(xzXn8GFfg-RhVWA^ zb1-OFFfhNl%E1s|!N4qWor9sm0#wd$Ff6cOU@o}H!EnNYf!X60M18?+4u%gF49qWX zb1(>4GB9ts%fZlK$-wM#4V9CJz-~k5% zhZO_!nui<=238Er6CQCeL|8E}t32jlsIX#SKJ%D^VF5_|2?xUokoYqWh7Ta|XB-R? z)(p%g&p8+ztQnYPUT`pESTitR01X;2Fff?BYX;_&R~!sCtQnX; zyygH6S~DBG<6zLRVPF<`&%qF218SFXFjUwuFhBUn!LY!Ff!XIX2g3;)2Iih`5chug z#=-ExhJpFZ4-N(iTLxyE-w^Q?e>oT&Y#Epx{&6s5*fKCP{D+9EFmN(V0Pz_)8Ftt* zF#lkL^uv9aI2j(;GB9&6L-+?+IT;x27?^W7ITKCQ%u5tG86qqh zm>ZNh87|l}FrQK8WcXmu!2Cs-lR?0Nf%$?8Cqse*Xe1sob^@G^ z0J4X{gRg-RqyWreU;vo|8lM+f3sDCfcVY103jiqt$%Dq18ldtuP<;#@d~ka}W1@GU z@+Am)6njAK0nKfctb^EtOC88Q5k>|Ep7juQpmAWZksf>nF!zAQY$BlYps`x0Jlwq@ zj0_BGpz@&c9H=}v>_Fz1FfuS)fXai$tD*7=AoD@)oWjV!Fk=(M{yShv(4ZUN1>|r8 zsoTTIz~HkPqV5Jl-2!BFAp1b`41b{NKyxBsrAXn+!o7;e>N*hWCZMYWjqlyq z1yKhY+5p>&mVQ9y9bsZ%=-3NU#{*8C3=9lDd<&S+-1mlwfgxu*|T1#F%V-v)Gb zBFqd7DF-0xKxqM+I#9TR#*PCHLezoA-@)pT(q#-Y1H%reJSYyJ@+jc}GN*-^fuZCu z#2nDLBvhRN$oU}oCCm&AOQ7=D;^zpcTXY1X-vJSx80p{*GXsOfQHVOwSS{2Zcs}9* zZR9!zkw1bk2gAK4EDQ`gjziRe#!jK;fYU!HK0tF@0w*By@bL5C`+y$5H7pDaf1v7c zrE{?VSr`~LoP?MMnrB3|4?*p!TLe|QDJ3ZxB!(0&6R@n`|uq=PB$QXd{`M6Snfg00nL?w)gk4x999Mf8>l=| zxPi+RkUc%D3=C7C@*bc#1sUMOcYpr0{wIT4bgTQ8xuqK3qT#R~~i-h6Y`TIu2NPdGKL`s|h;;LxLVeod6=9 zCZL-a!_L6qVF*zNnnwY<(1-5>Kbn7AKpQ4)AnHJK7hrWBd?@)B6n<;i85njz)q&>B z!0LSX8qn>%!p^|JVFxi!g$t|-6wViT(CqyKntS(vs9OW+QiIeT;6ziW!ok4M;RjJ? zzz#R>00){n9}WhF384^mCJ6H;aG|LKb#LZGL)0xmnD>AiP2C(01_qI2h`JWY5CX`3 z7ueC%9pPYLD9C`Q<3Pm61y(e5Z#Wnj0K(|+flYwDJ5kwtm&J^rp56t@4 zhLeHeOff{A45SGLb|1QVp!Ey~Y9Q(?Kkk-CZMMi za2i?wF~*g`>V6>nc>pW(0#OXPR} z`Ew071H+P65cA;Wxd$J--FSwZfnmjKh&*WB0oeU$Ky$iKb#QY; zco-NOpz@&gK~VV(==HY^4+BHNJBT@7z>2`_RE%;fg@=K`<~>9mQacr+ThzLGfzB%fK+_GerIdtUf`jCqVYZ@G>y?e1oV%>TiInCy+TcybKHr zpz=um#R!)rybKIHKOp8jL6n0B(96LyybKH{{zBBrAjxUdZ1_l*Th`JCQ;RXtqDSQkJ z0pbvK(4ibqxjF&aeW38&1F}~hq7JED2rl11@^|kV5 zdC>YTWc{G<7ZG4!SOS$tYG0z{e~>vg0t^gK^daV;=M#{8i~s|JhXF($ss9i6M~wgj z!yc%70@xAY@&gH*(40E9B zDiHqrfL<>x5oBO^V*xP_G=>3oI$C=KU=@eWDagDOka_VCb-2>SFvKK5%=@4PGK>M-KTt&T z2WTylN-snmXdNtAB^G;igc%qd`XK7y;|yr=0J1kkn1MlM0#qH$eQ5PCNL`IE0|UoI zh`I>~br|V(i7*30!6b+}&>B*x`@s1G6z@lb85sUR<*}7>PlOp5S|&sEgZkWH{XTpP z(Az6KA`A>SrbE;#AG80h-hB;9A8ifDAsP@xU@QN{ z7#I#HLe#kkfmJbp#{baM_Zu+=hC9X(bx7@TjP{I(I0Hk734V2;aI_I;U^oL+hg5%o z(*a06Mx23x#}r}?Hu)NH1_mFfyaCkN3?6*&dVG#J149f{9$Pzhk2nKE3Lg18;tUK^ z@W}rGxgRQz-VO%ElZ*rd!x^aj3q(4YfF7NegdaEkbI8>1A~qgL>@He4-OLO_!-DOYa|#LHbCW(%1ab`KYMdeJ(8vEl;V?y#f#CpD9yGTBwi22yK=y2rWMD{ff#^pXFG6WwfXulg$-uzl z3Q-4ITMRbGg--yKJwfLDkz`;n@qox9wX;7U_ZL9ss7Ns|>!L9v}}PjrU!VVqgf_3Q-3d%Ll9U;oE@TkN+dZz~Hb0qOJhZufpiZt4M?97a;0D zb1qQxFvd}Rq!}1w_CwUQAjZEIpxav_&A?D`6rv6^Cjm7NV;paeGy{Xp35YrYME=8= zuQ(#jzz}c>qD}#+UPBIFP&~Ym28~BR)TtoUHK6Bb5g7)C8y6tz;O!i=@nDd7HZlwh zdoDrLi6H75%=VuQ1H+0t5OpsQ;eugrj|>At#$$*&7le5Y=;Mc5WEdD)-a^zx;4$xx z3frgugAbz~V3B8Fm|_c2_XAw!ROe0_%Qo_@(c`TLLllc zAoA@2bo0*0Gcc4yK-9tKsXX{F>ZvdC3=BMx5Os49@xK8h{uLM)8WJGtkm^T_dd5Y8 zfgvUhq7JEl3a%eO;gO=iz@U*1kq7Mu1cw`zc5aUX1H*?5h&s?5F;pFjKSAkeivk0K zO*TXwdixw?-xUQ0h61QOd_D`y{Lvo;28JCu5ObhQy+QdDrJV~hPeqY|;Y1!p9lm_; zqsYKeQvgv1nv;gQA7z{w@LfPpKRikd3~MSN>h>U+hhAQqC^0ZJR72D~ z02>B&KT5j^Aapz`qXKrHTBqQt=Prw(Ec1EQYZfL?E% zQDR`Y(hN~2fanKc%%6NwVqn-a6{4<14(b6Pz6UaB<*AG^1B1jCs5)h+x&Xcp80DWb z14GGmh&lsls5&3M4{~Vc=d1I^`uRr>H@S*Te zQD$JU;P?wJcXdD;oInN!@J%p7Q};xffx*TFqV5JFTppm$EAgl>FuVzas53y6TNv}2 zCMpaJU!oxD{=niRfbW7Tn!Pb93=Ag{AnHJS$w1Cyz%oA6qQb!7kOfiq1F8QGZm2@4 zK?YDdUZcXmAW#WWcLm{(1|c+iuc$CE?CFN66F~R_qaF4~g@Iv7KSbRPSO>_5ZvlF| zsi-nAglvGQTOkhi1*n|(fSz7_R2dkq9EYgu0CjdjN`3eap!=glm4U(J3PjxsS&$;g zJee$-Kjx@1Fl_k=u!b3;ZU#af$~XzgJR3Cz1{pSpI(Yr+!-rvBiW+E-H$>eQsCOCA>S0iM z0otoLfdiuM3PK&cyjY{gz~I6Okl&loq?eRDvwl8qLhcA@XAqVV0cjk zF$ZZK0!Fw_QD>2U578*E=qn3=BI?K-7WuyF$%7fZl%0(PUuw zaT%fxGzSS)w*fg^K=Cz2lY!yL1Bg1%I2%|UwEqv1-=fLDa04p;11t%yf5H7^ko*-* z28Im}A^I;MzQ|fg#}$Zg~+c1_pu05P9@*1CV|b&{#TD9^1H7h!z6_2Ojwn zB=gbdpF!qN(PChbf$GOLF1AIBfk6i~*NWY05149ZP`4Bw@h8(Co*7(PLagL6A9j^cWaUK;@Cvv0%)b zu;?=|?DzvQrvnl1DD@D?J{^4q28sU=b?Eki(4!GQ&$ z4p(@A{Apsqz>vWTQHPX%;Nc!(z`$?-Dn9{HZ(__h))+7_XmCT!L8`|v#ut_tFfjap zs>5dA5d#K>03L`rNb8F*^3NMkV&sLWvq8i&O8*=bt|EpE3?lpxb@<$6W5~ep1gZ|3 zyJ8F(7;FR}=HPQziy;HU8>qS#JnmX!$iUzs3^8vGxR3zX`zYliD1NROGBE5Afv7`T zUjmPxFNO>ZJ)#hKeCbfeh=IXC9HI^>A7bPS7b6CS7DO-cfkO_W4qtex z7&9=`K-HngGsxX8#taNspz>J#Z_L1uA`h_#mwQ0w^caIKQh}&LN_XJ$10=u3n1SJq z0z@9ET>y?(ko*~A28Ioa5P78aP~dVM6c2BV85n**<#Q1IM2vA15fcUm8#RbI28ebv z#`vX;2?K+RCPbYE9(5@u3=Azg5Owf!3d^`;j|l_A5nYHnT=4<&#}*R?1`9oix&?@I zfRdg->h72@Fl^9=sDsaAU`a15rVI>Q3?b?)5dJ_(=OFWROc@xCm_XDa^)E2gg_trh zWLQAd!PhrnDVJ+Z85kO@A?iS9FoCl)+B^#=UYD3MFi6-!)L~0sM@$(QRzT%(g&WA6 zH>L~>K6Vgu(9;JP);p1b*zz|{&F&}At6h^$1m@zN}I6~CT z0DBr-j$xG7bIceR7B~@Bcf^c=LBJWJ4s^B?*hsW+1i9~x83V%>7l^tQuyHjXz6a>* z6h+J#7!rIT>hPIoW6r=};tx@W&%Y@k^8z92aJ4T$?&~pUU^oyAQHRgoE#?diM?xX$ zkoHeug!3J928I*i5Oq3;e1b7w&SJs9@FxPI4xjsUEEpK}L=#pQV!^;569-X;&)ymf z1_p(A!s?b-Ffgbj5LS1_f`LIJ5uy%XIr{}P>7EQxhhCn8;z7icfgu7ak1HNP`NhVP zfuUdp#2lo3NAU7C#*%^I3{)OzofJy@6J$<{B?H5j6o@%U{V{mCzQmG&VMQuL9%=ju zE`P+5fk7Y*yFAE0PeA5F<&oA4V5AowD+Y#$bci`f>M-)9i4_CGAE-K{dI-flkiTNA z7#MbBK+Hp0{|OJD8Y>0{olJ;4(z-R2_8-XoORN|e)aF(%UV2G)KsPlk@3tB%Eq|U{b zf#F31L>*FnhT)GKTLy-RMuoauh7#NOpL)3xJcm>z9XzN-* z_J!Di&KQEILmIz??=LB_V_;zDg~-Ri;uDKGbLNsHS_5eP}dJ@n&%h{}RV8dFV zaJgd7z+kW#Vy+J&e8J@|NdAjG14GObh&;CO7ZC>rh7_nglDkmqEs*f_z`)Q4=5JtxsSnS{EJ~T~HZU|YHZe6bx3El1N=`{lOV7y6%FfBn%P%M_DlRE4E3c@m0;z4-zhHmE z{0aLT`awJd{xHDcBgKFTFA!!%0?N$HCM+y0E=YDRI0OpU00zi;5DX0H;R%X=P-sEa zDZtgC^FM&i5#WcJ1JVP+2=g4BoLyYq;P)nhB(Y#va)Qw?B``iNnpkz{`eFKDG`c*o zd|K%z)?8xM;quQw>4(`1qtV@mOPpMF==xxMV(o#cN2h6}pICE=Rfq0w7=NJj!|a98 zF!#V{T;ec!7)`7?boIpQBczUyJi5IwJ|P;HxwyosWgfZaquWo&976J>nuo3)7a!eT zbUsWUOdLkT#0k-)sz)~urXNP5%cJuhoFFGW6`TUq=NlLtpc>KZUw02rFK-`TKmUNh zpx}_uu<(e;DBLY4ZGEUQ3?Dv%T6O{q2A?2w0hHbVr9VJvgU=v&cr$?k)~24@J6-tBJ z)F9?u5W&E}uoy}&htg}I^kygxYJY>6`#}T)1H(ZmeH2O`htij!^nED(7)n2d(l4R( zdno-8O8BxS{h2LLTO_tZ4RX^p|mZO_J-1dP&yh)$3p2u zD4hB~_1K9qhArC&qo&rte1l>Q5)IiVSW8%oPUX=Ny_3#E;rv?Y|bhSH8u+8as-Lg{cQ z9SNo5p>!&g&VBNN3Z>1Vv^A8rh0^X&IuuGr zLg{EI9S@~*p>!dXE{4+OP`VpR_e1IFP5EYMI+VT- zrJq9Sk5Kw6l>QB+|3YbY=s*A`l;(%hl2BS2N~=O?bttV1rR|}#Gn96P(w6K7=Bb43?r4K^s<52o6ls*rouR`gEQ2I5L z{tKo5LuqDcMZ*cDxuLWmloo~3;!s)|N~=R@O(?Aor30aKIFycs(y36o97;Dr>3%3Z z8A?xu(lep-d?>vfO0R~}YoYXJD7_y_pM=t=oghtl#;S{X`fLuq{|Z40Fxp|m@c_Jq>DP&yb&!^RKdpyeR^K5J-w13G5i zo`I2xnT3^&or4oPTExZ8!^_7nASfg(A}S^>At@y-BP%Dbps1t_QJ|u#rmmr>rLCi@ zr;ljiSXtZH7Q6zre*_p9UW4ch3?&&wsfqB*VHgP`^$Uvfvr>~w ziuL_dGV}D4^NUjTAsV2RUVchu9zzJ&jQD_}%>1Ivl1iw{A(X@wkUa_vQ13FxL;29` z$)F78H!wnzB}5Yg19;30#DNxf41W1VxrsRpKKbPg9+~MG3`M1RC7HRYgxw2O2zETw zxs?T}@t%2U`3%LGRjCY#IhpBs3~4!u>BS70DGX(aMVX0tB@7`jRq<|MDO5hlX<+;S z?0y9XaI21if#Efn|9}y4t|(Xun1DtvgL8gvL1Iy2QcfyEaAs~nPHH?vBo)a*zr@_s z6o$OS+*F37#Nt$jg6wpLocv_4Il=j*MadvdDXH;3`N@eTnfZAPX_+~x@db$`84Nj~ zQOo4~oYLGphJvE}`5C)D(u)yp+tuyu8%nVz4?G z5s;Hul9peT8}Eu;{>N2F{KCd78LvV3u=wTx^BtIB@eMN<79Ozph1tX4lUY)dlgi+f znT`}9L8W=f0pymGp9sA$3*jG7IOe3n@)OJ+gnVFWVo7RI9w@wEk_-$;b_ACcW#*+b zWERIK7ekmJWeELF`T04iiFrsm9P=uXco3CHSqY>aNj@MyGp{7Ih#@s671k(5vER2e zrzA5TrV6YXMLqx?ouCAiTg*_DT3nh_QVdD4DVfO($@zI@sd?ZO0n^UloS2i7nU@~# zj71KlDB%VqzF_^03@9I#A9JC6SU;o^%7+%04E0bxEdD#7e2}Ri^Cv<1F!QEE`7r%+ z(fEtOdKsTB;lnR)SLiJ)1B+{6kfE3-JhxFE5p zI2Ad4g7n9SfmMP61d1W4E-x)V-lZ}xF*h?AYB)kXI43h1IrD^+7UZNdlvEa^7K6(e z)clU5ucW9nxr8ASmK^B8~IjMOJt{_G6pp?xJ5AhJX{qe#1iSgbb z6Cm>F>8arsD25U9Lv3jM9x(p_3oJcAOu?*QVCl&%vm!Nx0TO1=5JigXP_RFtRRlON z;vwM!3Kxji^77;JGIJPm6DyNa8HzI!i&9g-0tkniZ7R1U(EY3(RV(nU;+|)kdzI{ zK9B@w#8AOd$p9`@Ai{1%`RNRxx~-&=A*(dEAU-2CGd-h(!8NZ0)Z#42FU|zld-+9~ zsd*)kR#8f7QD#|c3IoJQV+N!KfNy?YF{myE6<_&D`6ZxQzbZdBDKnKJAh9Sh9-PlL zGV@9_8Q>Rdg1yH8u6t8UiZYYq3-WU+bMuP|GBS%16}rNGNc_O!Llup$g~rzh^BoAb zf8pg*e!c;NTYkPFh%f>X#t?@=$wW|X6kkx3pI(%hn+u92s05S(wK+4BGfU!&Q$cws zzbHPnqM#_XxERzfa?8($DuYuu!0uCkx5sax@$Z274RCpwMp*iWweK7moEV%zp;wZb zm=j-Io>`I%zIuu{^AYw3JOG970)qCz!pnsr3GCStNIG&!tSn}5NksHfBp!myL+YQP z@ztPwSboxj@W{r5jlOgqagunwOGT z$>5t0rb0?ni$UD*)Ra63DTC64MPCvWoNbtduI_ z(=tQgB77!;F;@{|qAhs6Uoln;wP5hx$#ZfPi=4{DqigwF^oPocsX{>ByG zV7D^36{V(viFn7H9EPA&uzvzeQ;RC&-BLj@n_A2O;etzKu%^V4{GxbBnGCa(fq?tTNJ_gu)!Zj!#GCKmguNV>@kb5u~7zCbx_y?F^^#aUjLh0APv?Sg?E#4OrC(u?m zyr}>)g@FMk<5-kl3XVyH6qp5yv3S4yl6X&0)d5lgZPiO^55 zeSkdP5T8_p9H9W*gQ}Jln=R=gn?l?ln;yF z4NyKTelI}zuyrXPpnRCTz;lTEVDbh~K1@CUjb8xe!_+r{`3)?v^ak@euJi-TH?aOD zob4yFWgE3I; z48DmK@t&ZR0cuVZ#|Nb*CTFCkFgTT_rKJ|d`O!gXZfJ^YZdb;{6L!^Wxny zb5O>5Ko&SdKxrX9Eip5vv?vwSwn}Em0XNYZN{dsA;tNWOAPh){K0XsP%#)W0X}UYY z^}9j!gL}ILMX70-6%4tl#l?x~sSJ=7KSNG_d1`SK8)N>3B3=-h+T||8*2j#=cm!IJLh$wHAq4Kcu!5GSi?$ksq8 zAErJ5%%8vrlLx5*VO;qgW-fYr2i6{d#WSQc$c<20_{36&`wI`%^400KET=Etqo&X|) z2Y}i5hy`GE2z@o+3*7}6LZI{<@I8 za-{GG)_0Jx(qes3RhN=l1j*IlOp=pXqLP@GpQmfgpuk|Iz)+Bwmzm4}%N+`-;O=88 zD6^!dD3sX<}^m?VanREC%|hL}8tm?DOl5{8&EhL{Qi z1BMvbyamzmRZx_fR{}{epz+4cyb=ab=z|GR6cmA`Op^0Kt>y}bLd4t$B)>8w<>%)x zB<59u2ZA$G7>W|hLAv4?qT^!0Ge-;>nhZJ$44MoIx^@Z-%FyxXXlU+7B9PlS@O5Dr`kq+PDSpbQx-R$x$uj}FW@F<67#keQnj&7fQa9eC7W&{P1mM2a#iq8VZtxRe!2GEx{3^72bk3ldZGQY%s!GCNZ(x&k6rSvu_Izp&s6PRciU&(ofNX+{MU|y8RDyVUu;vGtR|RU} zfmv`>#zwkHnI#NnCSZyoG_Sa{pdi1fBsE1Lu_zg|J0ZCQG=~Q^8*Uny2R04t3j~o2 zvNSQLAR`ex-H@3K3gD7rhJvD0-ICPQykZ6@Sq>UaOD$$FWH4fYHJTY17((;1^YY8{ zQ0+z-4+;&?#AJ#BXm(MdD7B=tC{F=8D3)4O%#fC!Z=hfcq6{IFkpgUK8Q2sqWrfs= zf*jBg6xaxGC9RNOmRgjPpO^wFLb;SdQB|5;q5z&M;8Ioqj{`z@L77RQ&1zceo; z0Tf>#6=2tZ&4bLagC^~u1Ex?ZFvX>;tl$Jn;tG&ichuP%2Izb~4$YwPd+=Pnf@%uL z-jw{jR4xXPkr2Za0zjn#*d7?+oS2uKnvK;jKl%YmcQDL;uJ1gQ&;9R9E&Nl*%b4M}=_1D8j+nJFnb zsX7X|i6yCepyYxyAm^5!uV7^bOYYSSoT|m(bdsQ2oS?%6v{&Y#EAD6LT~QH5F_bGIJBt zA*?JoD;v&A&d z6`&(e5c?sjA)~RypmtU~I6K9|RKv!pAgV$3gLNSJQ=vSwBtsz=w0fW*ClyvCL+2M6 zz^V~LxyA7y)$uUZ@kQVQ95U?;wt`DJ*xykBGC!u^0~t{R`3r`*Kr^~knFR`oc_|7Y zc4=N!W&unV~%*=yK|A6d=H4hX(aA$_5x^jWq=CD=NEvc zS@Vk+AW9+Oq7E`oAvwP&)e1K42XO_01P{0>sFo>|XJqE2DnO@eGxO3x&GD4{T!n(7 z%-mEx*svBTQG!GRK%xqcR)~%t)X1R3Jdk`|X>L+#kpg&(5y51qK-n6CPS`~f~s;E7eg+1kjzLU*F=*c2{a~2uzjCj zte;;TpORQq4jVVlFG$T}07X$MsGLm!&FyD1WTYlS2dbbE1*Hg@4;p#{kH3KyZB#%z z5Q%yD#W|^|1w@SB<)-H9=ceXDG%_$0mlT1P9a$-4LKfD5q8hRe2I3%s?tvPh56(H6 z$)JXGBD7xv7b?k5WbjM$W6<@?OJmRm5fH-}7(f%Zpq?vez8uy#wo-sKVxck$;OP^H z7NXq))msenC`3Cp`=Bxq3hEszh0L6s)bzw0ND3?f4I`!~l;kTw#uMU`GE0gXkl7I3 zSp5@kXk>w`7R-mKC+MHjyiCw|ihgNHngy6Z^$s!Xtf1_YFNd@UAxi z72Nun`TCjp5Z4+Q5Rtw!^Yu$hGIJn0h)|!FTcV$q3r(@AiW*LiE(+nEE+HO}Rti)k zAjs9(GuYGLPm@7aQNzz)Ag(zkqTm*N{)k^zMd14y;6XK=8m zpSuD~4MLIuEDy2~CI{7zs8&=JHDLOkef)!66`X<`on67MaE%BFa#Ucj$;-^KV^CFO zC@CsUWk^fR0WCXYfPwh5+!D~Rj}@rmNJ}jOch!nY^Yj$LGgC@3zy)0)4jv8)tIp*>5`@*o|B@{Iiaf?~KdI8BFYgZiHtiFqlY4o4bjktZbUg4_V+ zG8kkq7{G=~z)pmQpQ~S}uR@rkPpB(OZpmq)en3a-RTvC)@3E?EBq{Npb7K8R&fh7y_3*yTY zGfP0-X|O;_etda;5lEh3euH%JVD^{hWkTzS_~fEg(CB+S%;ua_hNM&mXy*zX7a)S5 z`Oxl8WQDSllSTMaPznlTQ*bGuQgG_<6KtSGtI5xMfX*F*v>>TZ%*lZ( z21$W2R98|_equ^;Vlh(50G1|Po`U@Y$_SaD#k|ns6lN=ONkg7_@rfn*xv*r!z`y|E z#^-{gp)@ZiKN*&Ci8LQR-o3E`@g1K$0MBaE!zJG|&PtkRm+t zAny>4Us!mh=9Lsxf@&>jeGW35nDP{+AJmuzH|$F?^Wuy16QO~OTAn5*XG7O$LyZUJ zPDFVRng@bOKxydwE9$H)R1QRevVL)DNqkySelDm?1aDaaNkDNCcx@b-c9@~Li3Olt zGN1`wkdr}Lpx#jcb;!W$IzTh5DXA5(Mw)^zWQ+hd(HafXgoHuE<|y;6(clSJ9oW1p z+I($JYF>It26z-OH!(XEGKPU<9LRR?h7<+ptQmB$5IU!jS_BzEMCgT^4;orePAo`F z&Mc|KV}5>KYJ6f|dQoM3N_k>YnnHPEu|jfUPEKkH14yd4B(;DcDYY^`FNFcripj{uoz?jrkEiwwLBg)X@s)FuRJ5MBt9`dEk8deJ}EUPGqo%g-nRq!6Ff}` z8D9hsZG)ydK)#6w&u25FRum-Wr7#qf!U`^T$bJXV09qnw7OE(*5;WWcYAu3B*+9tv zJgg3GT!TdN)4(lm@L(AF{6>BrVgyY=H3c-b1sYnn!Vm?y6oSL^i?UOT6hab2m#=cgo9rrLuhxfl@P2^oh4O+msVk0B|shyfA;Ntx-ODOv>$@PHv`q)ii?qM&BS?ri16-WYxmO6CqpZ;o z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S|6U0no-6(5B573=H7=Okroog4_i=ClLHeXXERgsCggEHz`3t-Z42(<+42%j442(7m42)h342)3>42&5J42&fV z42(?-42+W)7#No@FfeXmU|>AOz`*#8fq_wvk%2LTk%6&~k%939BLgD~69c0S69Z!m z69Z!v69eNkCI-e$Obm>7m>3veFflOxVq##_VrF2BVrF10VP;@#VrF2Rz|6o9A0J-| z+WiRLi)w_-%}!;APXh0sjR)=2%1>s9PtM6NPGyJ(?+T31DNaqzW&j;`pIlH0rgQVl zQo)Sk)DnjHJosrY@dc3G{PBq;B}MT4@u;HdsU^jrBd)=lmKboz<>zE3SE5OR&muro zUz}Q!l3J3OoB=*;4^4e>YDs2ZMru(e#6C<}Y|elkIso$s67308w8Fx-x+w9&%Dn zJosD_hWPlBoU-_&{QQ#Qk|NMi1B~$utPITY3=*ItyBWGz($mXS7%s6eFy&^%r&gpU zmzJc)XQU>A?u#*qXD|V!MFtKPhTM{((!6AbNlfW^rSS|Km{KcBQu9(W(u&iJ7_Km- zG2CJ*WmwCco1apWY0U7DIVH1<;W;w{3nV<2Fcz027L}A1#6x#yF|;v(4l2k)66s-r z-W4>Bg@MzM;S{40!yQIrhDVGh3@;c>8Qw9PF??Y(XZXcv!O*~D$uNP1h2h6eW@ZD1 zbu5MqyI71Ejaq+U|~3O2t+m<0g+QqfygUoL1f2y5V_$3h_p^%)r1@ zoR*Ph#IS@Z1x&AEVquuEjD>-P;RooFOQsB?wD`=_)KrEOOld|L5au~17KS;iKx!7O z29XC=voJ6)fer*I$xKOOc*B%g!O+6Y!th`<3uAm~9%#>WY6`iw zGN+`KWHPj{Fff&5GAv|H$z)j0%)+o`2gt|^J3tDd0lE(yphuWl7~UX+O&G2+gF^c@ zGYi9oogh6Ec7ez-8qqULm`^YsVLidPg>eVt9hL*kTNqa`Zee7(!Q8-X zGlellr>4ZG#3#o`!^NV5aSvmGicb&Y9mX4sAvFuw=P-9LuVC^x!#Ibrhh+iN6s8Ww zC(Hpg2bgv+8kihmW?`wA!gPl*qh0orQ zxxgH7fN>6UM8yfV9gItuJ}^~8EKutZ+`=>?cnWI=(*(9JqGuR?Ff9>T!@GfR3(o@n z7VZwV3H*DQ<_PVO*du*~t%Gq556cdY4@x)0f3SBjzF^$Lc86mD;}QN7T1%KNFstay zVEV#%gK-bz1V#-78;=&of)2(WMvEJ)C3_eZRCG*Co^a0*Il#Gs`3K(>mNkMIbC_2! zUSNL0K7s8E;~M4$#yw0iI~Yv@bXpjvFeYqaF^T!WSP;;{+`;&RY74In)9gIE9Q&?L> zelXj7;J%`>foqTW2IeiyYuK*HpWu2S_C?a<2jd0C3ycC98af6V1{!-9H8e_|FovW| zU~FL2FwltUVD!<@*u&VtvVr#j%NC|7%zv0ZFs4*!Xc%Z182n+`z&L}cgLMPr1I7tV z4NNbX8klAw|RV7kFLhp}P< z;|<0ij87Od-f(PSTfye=f@u!p0_GkTg&k~b*cLDzU^~FPfpHF_K}JS~K@0N&#uemI5Ay+*2aI=^zc9XGI>46F z!g7LT4YQAr#tg;-j2U|v?=b#g4B5lTp`h`D@dMKu_6tlVcbIavFm^C*VcxZb0@(;X%@Im(>gUoYy1L0>u}9aJ844nBy#AIb-vhY#Xkfbv1---Gy|dyql;LFeFu z_@AKipmX&>e9%3}AbE}t5ci3&Li`Ile;*{T2IYg!8^paEpnL-; zUkB7yWnf@%h4Rn*gs4x0@-u!z_-#=Bhd&VhIw)V_AB2Aq%1?muUqSgg{~_|6>=64; zK>2!5{uM?>@SPmKQ2rMt2tOOj=U{>G+o1djQ2s(Fzl04UzZc3s0_ER_@*UVA^1q?{ z1`Y^ch6Car3r+~%7Rt|n^5dcWIZ%ELl%K#2Q9lvNPl58+LHQX_{wXN`0hIp?%KyRx z(J#OWvHt=ugl_@mTkt{np-}!7D8CfS58;Q%w?p|`p!}IoK7#;6ejSwW1LdED^4CE5 zpzE4I>EnbTME!rLyn+IRFUSRPUjdY_0_7VhLgX!>{4+`rzCV<&q730DL-}){{CX(= zi5f(HGL%0@9l~D*ZLOXV8YoGjT)Qt6&G=i$VD-+#q~) zDF2Q-gl`4qmlQ(yu~0ro354GShL4B_vF@*hC?H=+E9R*3v} zD8Hs3!sq9KxL0Eugs%?eN6dxr&7l0A#SnfZl&`ZI!q0>9H*A3LTcG?Mn<4z^P`<}* z2!Ah>-?9h7KL_P6I11rEfbwr#gz$eu`BUyg`24&O_r7=p;j2LT1&<;85Ga4nO9($7 z%3lEGFM{%KyoJc`g7Q87L-=>0d+!0_DGi@&zm* z@}Hr64J!!$50o!s4dJu$L;Ujv$`^+6H-N?n7#J9opnL~gh(;Y&dIB~ZQ=lrK;Kk#~UdcR=|O zP<}@dM7|Wt&nbiOCqnr(l@R_4D8B$SHpIZda16?qse#Dfh4SY>`QM@Z8?_L5VIhcn zP3j)tP<}s@-!T;;zYNOnSq9@<>x{939ljY4N$(o2ME6p%6|jp&xZ0(e1^!cf$}-NL-^aE{2#v|{G(954;M4I zyuJ$M|KNr2pF#OPd=UP3DF1{2gfA!x@qdpHgf9=}ONc`F4p4rKID{Vv`AeXDJ1GAGlphG?Pnio*pAO|G%!Bajq5Kpme=?L`0_CrU^8Y~j z$D#Zu^C9{lL-|J*K=}Wl{51<9d`St2dm~ms_zqD14=6tX$`4o#kxzi~b+$wJT~Pj< zT@e0kC|_YWgue#LuYvOSK>0VI{PR%0$sUOM$58$RDE|wT{|3qzl!Ul9WiLd%4wS!y zp9P%%oS^(2LJ)o^l&>KH;b%bkPb4Ayb|^nX0m7dJ<%cLk`0Jtk6jccS6qG*!%D)fg zZ_t3qvr9qTcSRe**MjmhbRc{yD8EDx!jFOSJ1ijlS}4E39>Sjwr|R`66>5{3pxn`5*2;_zh6L!CeS{ z5tJ`*55nIK<)47^pF;UE4FLiqx*5dK>z|40&q&!GshuOJ)3*MRcpEQj!Yq5P6v5PmL{zhobTKN-qja0J5N z2IV`PgYa)d`4)E}{NGSM&j$!!LJ4BO%ohmX3d;W?!VdOdG?YI_2f}ZF@>MJ${Mk_c znJ@@{CzPL)2;tv>@_o`EdYmM<fj6!k-G|U-5+S*FgCkUJ(8TD4)R_!hZ?nUx4yi z)gbO$-~*ADh4ME*`Fc?P4Jh9c%4hI}s1Jtnb)fuYC_e_uFNN}3p!`-Se+!g970SN@ zbK?0T8|fls^T^H-z$kK=~d}en%ig zeLR%U5d`7aLiq+z{$waW0m@$q<##~&TcG?WQ2rq(KPMPs-gzj02bBK=%6|am|A+E9 zLLll@G$8&t0_FQa`Del)^5sx|O)P}J5X!$358 z5c92|e1$9sKLpCR$cFIip!@^55dI=4zaS67-wWjj&yTUkKszYD4Tl zQ3T3*{?RL*%zY`4Tk{{&^^W0+jz6%Fn2U z$n)wz+_R(}!Z(HT=QKe0{!qS1BZQv~<-dXQd!hV-7Kr?MD4(Yl!oLdT+d%p6q5K>u zpHmlNKSvuxy$Y272g-MX@_9NS@~Ke14wT;t<)47^*F*U(-4OMcq5LmU{tqa>pcf)9 ztOv0_pbx^=hw@kSL-^iMe!~O^KNrfEnF!&xL-|vn{MAst%Or^WaVTGAGKBvK$`_de z;s1v6e?a+s`VjXdOohlBL-}WBLimYL{+~Gzem|72vH-$g3gxFj`NyFAGYcW|Z=n2) zMG(G#0mMFzB@n(LlrORj!gq)AO`!ZzC_iTzD8B{DUjya8f$}dw`7&D}>c2zz z3${V{f<_ScIBbXTb)ftkP`(e8U$6rrp9SUbfbv_R{D7Sh`Gruv%x(yO50ro8FogdC z%Krf6vlv6{-*XfquLR}4f%4s<{DR{U`9vsR-~@zU59K>R`75FP6Q>~ZN1^;FXCVC7 zQ2r4ppVI_l{}(7<56Z7O2T|_<IvEtFparA(@*hC?2cUd`+YtGC zP`(3{{|Cx1fbzx6AnthqC?m_qkQ2q%hzYod}xDSzE1?As>@~=So zPoVsNQ2qxfU&93mDPk033--hy49z*y)q5LyYzNiJn z{0UDW@?KEB$}2LHRbnA^bEb|HU5&zZJ?~@fX711m!#Y zgYX|g`3(Ode9+ob(0ptLl&@d|u}_786Wso{g7O&{A^Z?1{|A&m3(EIlg2>;7@;R6x z{QpqC0F0hM{AwsahZiEh5X%1o;pMmmop?nr;i2j98z5|qh z70R!H@;MzL=52xUZK3=(P<|nluOS05Zz+_Y0Oj9;@@GK#{7w+_u0Z)NP(F_=M1Lie z?*iqogYtWz{KruK2`FE}8Dbub97Mk_lei&zXQrY1m&NA@~=VpH=z7iP`2@Q{7Vq`NV`Ma`vb~1h4L9L zL*)ITd;usw7s^k7@+U$08BqRuDF4D+i2nO9{yPX?z=MH-kAs2X0xuW1{Ir4cUqJcE zAU)f{ze>7L>mM%CCX)cR=}bp!@?+{w65@1eAXf%D({RgVu}lGcqt7 zfUZ9iV_;wa@qgTbtjAJ>@=c)ilP;8B0xdr+q5KsJknnVc@>?E2^anusJ`W*$(ET?c z^BJJ){nDWFB2OXmg;4&LXApi3l;80j!f%K24WR1-Cqelx(Du|^D1Q!=zY@xCfVzJx zlz#x~{)13H1GKz33+2Cnn*R{Wzaq;BP9N`}d=WVa{|A(RKor7fXM}`b090NG#+QM} zD?s@sP`)0N{{X7r8p@ZDgs2aM@)tnm6QO(=D8CTO_kp^v8p{760@2?Ijmup^B_Jq1H%Vs`nd+>8+?MK&%0250hIp)%HIIx zzlQQZK>44be1p#r{Xao`b_RxmSCI6?z{J474=TT3L-_0rfnh%r1H%C(28M%7 z3=D^u7#I#SF)$oqVqiGR#K166_9}pOcB!Cm#)*%QR{?L`F$7CPmgV45MA<_M+*f@uk6LUsi~?1Qi&mO$7LTOe$RHRwBy;^RTLXM*?9fEA=< zmVq|S#K(hfSA}n3ijR*^%d7xz$AK`xJ9JVqK~6}^tN`;$AUyakACN*A2eHW~K0Y3_ zMGC%E2+D`=B8rcX2RjDra`2|A6!5mA`1p7*53(5vwEGTn`)Nrg*x98BcbCHTV{X}s z2W{svU;tBw5XuNb8AB)&2xSVP%pjCGgtB0W2X6`kS&n<_AKHep(XD`xjePL?hX?Ui zz<3o{?kK4&NR7|TOUq|~ZOPMv++7-%>w zN)r?TP!>lK0OfNO0Z^7f5dh^36ai52f+7GaWKaY^MGcAosK7xH02MnZ0*07QHAI9F zJS5{m7v*6S2i;7G5RZ>X=*Uk)h{G<@%*jtrPb~t66{cizeqKpxMF~P89(+?MD9AzL zy2j>a2sxOE@JsdLp*PB67@m__k_x-K7M>m;+7QMSB<5u%Bem9%6O`Ve`&aca6%~QDIOCEAxdGt-RL$w2J<-@Tg11X! zmjYisjT9Wv>p9~=ZU)%~%e2^ar)6RfbdYY)HJfNbiQ!;yfK=l05$JMr{3=q55<&aL zVUA16FU?CSjt6g0hWiPeO(2OdGd~Ya5~>4yy<j6G7LgXXfV_nIe@4g{ArNIHdB6VH?I_krIz7l$w{EpOOl4 zYbwGiko!X+wFkOrQe_E-N{AsTSWPJ^&BIV%YG#6NY$m2qGU(3OqWGNrY2&liY_xx4^;dX<>!DdpDhQ~eVKWB zpn5O`T%g7mrIwTy<;8;!Do8C!ErRJvttiOJOwI)D<+|;}hsItslsOccbrB;;0 z7grXSq~=0pp^hoaOpY(e&#BDKFDl5$EQZNKS}q_{Q!5g43vysKB^DJWR)Rd0UX+-d zi*O{UcmRbY)Nr`f#i==|$tC$k@t~BRT3if{0I;_T5{pVQ6LaE=%QH)oGobolDH_$% zq|B0d&`run7Nn%6r4|*XLc$jka*4&o`N^5!IEIC9QED2zW>;T1mPH}2{enDyx_zrQ1>+*|WoiiyunEXhdCO)Np=w_NaD*IB@3YT200x z4i?a3UxrfK?=e`&ppNj=?&h3Xnum zb;f5F$LD~2UYVL$1XT>y7@wE~GabYPMNleK9(o)I*gB-6S8`Kx_3|=vK$ovNMz8(@OFa89=oZ zSTrraC^xYr9&&*+LbwQ=gNidim(mxPAjC6^VVA1M=cT5D6CXkn(s+zd$}A~H2x8F@ z4=&PS?n2UqRU!@4r)P*SElIP`gVa^fstRgAd`fC^W^Q7RUP)1AF5F(YXkszwv=2=2 z;*89+lK7&`^bCae;F=(kIjL#5LK0kakCEA|wF7s!Q@AEr=p?Rj^b6Rt3(2@sM@_q|E@$mS8bR zJc1QM390Ic;9^6Dh@IcjdX1-ote0dQl{Xtv?u@{oY zVC^Bemek_p#DY`|VW_uZ)~Dr`=#_vQGdXz-@gQDt5(>8*3oi|#64X*D28{xgK>3M9 z>G64`xk;%-5P{6R5=c-c7NtW((sE1UlM++n%TkMykVNwHa}Yd;uL=@VAgvpan?Mc& zjw(f$pLQsnY{Vf!qPk!XVlB0#L~fVu7TfnH9!G4i=C!w50*D z7bE~}`9lO!^Gb8$!L=+X-qH1fWFhK`OY%XD5Rd?F<|Tq`K2B(*3vGY?XyWq>MHy~@ngoD{g`g8cj(@Gu3c z2)d16WvJGIg;4AQi-3BlC5gq^sOA;q7l6+y0~a??r-7BHK zdZ%k>VQC3B7Suv3D$zBxG%!GjL4yJ$YKRa8IT9pfgb;%I4x=Vyaz2$(LAArMzU8j_jC@dcnh475QBQsS%ce_~33D)X_z-wj(qPg0fs< zQgMC`=)kd}#Bzkr%wlkhkT6}39xKR%t zt4)aq^(i6!KB)cR!4#0X%-r14643BoJh)?mVpL)-nvYV8@)ALryd)l!IYBL;)D$Eg z;Nccz72x(CE(OJIGqBS z;=!f~6ul5xY|)DdZqPw{;GPpKT_U7%^KnK&Zhi`WV~Y!m@Mup@#%nU9L5`eK5sm_7 z)xy%mB5+p}n&ePYM^1h^w(tN4d^`?GP+%40gNJ0W83`?ku^9`}iJ4^)&INa?aQGyz zEVZaO6*QYynv;*qaP*uGI*Ji%Dgn6!T`@sJi&IN5b1+J9q7@}5a^NBXmmT2h9=p#A z^2<|;;`7tuOUiNjyEp@10xHhHnI(!dum%sVG7u3}5EVJaNw|E3Q6$0x0~`>bGLJyn zNJs;EK?zrnrBKBvc;SjcDFIYOW0bpa70Eex3gCjG%-mGaKtW1oS!Qu2czyC@ z%LkCgvcwW_ z?*|mlNNz%xiZ98}2M?Iy&>EkeSd>^&T$+@K&ybAFbnx&eE<-@_@yYqQ_)SSl%t_2k zM)oj@Yl{nu2)hQP2%ncyGRxwPad`zKS)7~!?(o558SVyOl(hM-AC*`R^z(gK1C zi&INLEo)3KrxbyllbfGXno|lMQpJ``aAa2`cjKs#aHxpSPeHE6;i_`-)8laz@o+Vu zh$zm;iO)$zuC39ei_oM&ns79t(DEQiB}TIeR7_!OwZx|n0k;WTQWlA6;@!;MDrVO|zgCd+*lAno`7m5;7GArVXGeHB*aCPyS zAXAGH%j45Zb8;Bsi!1Yz_2Sb?OHwPqeOg^3b3+SEVaU7zXk<6Pv;?Ha5>*YT5uKQ$ zYh-R@fGUwxl%JTAoLCIfWMl}HOD-)c0@VhPE^$0)x(w`&T(C1h1JzK45P{M>459SW z#G(|aBG7<0*zL%Ch=ZUa#i_Z8@df$d;a-q`!Tj>XOwbr8h>!3-R0Bi+#SDlL+&fT( zi6!~DnaS}GcOtnGMI6QbP#JVbBMYP03zYyn8OaOC!bm=e#|TSa=uAvcltPJL`+{Eluv=u=) zsd@3qAeF|(<^=6AHZee2w*wkD&r69<%}LGGH8eIcL2^QVQA#Rkh_)ydbkzVz)*ML| z>nPO+|`iGewCqYK{D2USJ|iOJdV;O>pCp^1?pQm`T0U}9v96zNcx zLTxuOvM@oagD_0jH8e2>B}{mQgrNd%zp)Wg?nSZR7&%7J>^BCLcDPN~H8e3XGD5@* z*j%(kXKG-E6tOd&ItAQfQm!(>og4(jwnQogRCsWEaKL*oV%FS>@N z=Ah~kmY&g*nW?!Yl9M34NEAou8k$-dAg7Z2f=bAg3M9Yk8k(6KA<1L<8?@{Pl3~nE z%#lJK8op?@nVXp)IS90Nt*8tw2kIJ{n!pnp)t@rJ%7G@I*dBwV4q~ zszKoknpX$SwL{aUk&%HZC_TeEDIl}qL#^qlCAvmN2B54B3qEkbq68i&0qGhU8G(EU zQw1sOQA=i!8gon35I_vBK&&zXO@ShEaZY}^k*<-E3CIBm(LB(~Gw5J2W|$b6f{JwF zRU?-QNO{)C*w6x}V=-+tF|b4`8^M8;n3I{Fmztt$WMYY&GNEY;B?xtmObrat^`omW zG)Bsupt1)=0i+BvGBq(qYIlIsov8_O(uN8lFXM#@St4aVoW`4i0tG3SQ!%r@k*OI* zi3H6_rYLnFtn>g?oJOW*W=QtOgRiCmtp6As4-(|jvO;EZN>SCx<;lJ$kiYyJV146T7G^>Y7u(6HnlK8ayyz8mWD_X0yYQH zQZh2NG)5}cU=BcuSY0DCW8~r#IgOebBeyot4L3J5KuR%SXQ7x3%DCW?-^d)L^aHDe zr(Sbo3#60@vIEr+&`K>`BXbj!2uLi46fe+JX>NjC$>H#(xrqrE}0jOVxoHCJe4fy^gT_X!a z_d1HKr5Tcw(DhmxBFlo46j-yak);uGf&$CHqtg=H!~?Ct1FbtOfh~pA%g;-VPs~d% zs*F!5Pb^9U?d`x+l$2Pc3!Ym;TSyDmU0jk{plbxGeb8l-QY-WGQgp!;DS`F2dTIIj z25`&qt;_|fG=#f`kV+%C%iv2SL48BWf>flXyn3Ly&&<4%Vz?WKP!C?gQVe$s5jr4a z+{JK5L8j$F{Zl6obMAt`okz7q%W0va(pOJR`9rJ~2KG zw5%g3H77H*EEVBn91D*1z^hLnt7qUA5Th36P-4`=(ho6eVd)8%+QgI;U2vBvGfxkn z8gSzbkD8SH(xjYJ&{C_!++tmD3looOaCU=aM003nz-c*T3@23=wptyR!qkd_#Jm(; zaBB&V)di&`x}cp-;EapQEYQ9YT~JeqpsIM#!lw#dP_c+tEod7LXupcCA)y#a%g@(^ z^ilEnBDXY07t}HU+X)%SL|Wdimy($hpO{=&npupju1rm7O zF+3xJM@K+Hux0al$wm3ah`fO*pOllB0k?v{YInW-f>iLfIk4XdDF!WiE-gxh8;-Kf z9pbKdqZD``V3RgZ!J!)z6R^C7su5Ji!{U*YMecgwgr8d(4_-oFl3xUO7-^;;82~Fd zFqfd~LHCLn!Y#qA#t0q+xYZcL695)9Y5Do_hVa@8hXNybQA1!|JhT{1%1qD9D*-tl z`$~8{XpIdT7tK#5LLF!j735O_#zFdxAn!ugLhGR{=LRjc1+Ah5r+DltKs6*pi6PS3 zS>&~@dXQ=2Jn+&ZkkdgcC*u)IQ$eM1aVnAkObuwwC3F!c$P6emJ|#0PEfqYkk(!s1 znV1J!cUF*-SORi6vR3dKOvv(J&=S*>)D-AiSWHD}X+??2px^>I4P-4uZyG305DNgo zYY#!==aBubppp<$i0C0NHq?uc&&kXyt$;4eglwAwl_B70gRN#Gw0KSrx`_?sR+9CA z`VY{BbVS<&YFd)22h;^5RS&3-K&l?l_$aA*KpjL<^?*8#r0M~UI+3ae)N>(K52z+5 zJt2^j5DS_Iot zm6BLl9G{d5+6D;Tb^_kH6rW~j23`k^EM#niA!KHPCInuLPz>Esl$e~HT2KO-yG;k} z?E~*Jf{KCG1R!mIaq)Eb3<-|+@eg+m(lrE+5@zP>p^BP=_Nszvq4;=Y3CJ!1xL9aF zfNKya46v;#DN4{081NydpS_uzK#*`o*}M5jv=1@e!=lUj(#rwzVQJ; zp1!U~b_6-Pct*sBI6Cswyri0&N{E13L&j3kKd_7!TQvh$?9SifmX`fXp9(Hju$~Wb5i7 zrz2fMBU2-!asrQfa1*;2qyc##Gd(9iDKRG=$NW5KSP?0BkrM%O;s_0PbwSMP5jIk# zB&Q5~$Ow^UBdL#%R{>{u(4i*a0W$D`B?uu9s~DREX!HlGM1ERYacT)xDe$lfR+*B- zbeK3SsuGLRi{s-#J_2=Ii$F8F;L;N$0?kvQ!LISXo<2UVLGeM3PM&`8{(e4@&|F+v zoLU6hZk(G~0^3v$)dfnHn5h=L90VHFAhs@eY8!l57Xt&suX{WP7#PGv8NkPQfkj1r z-Q!_mU=U+uU;%aj8CI%iTA3w#}0F!4-NzKjI11$(` zeSEV)epaiM&+&w^%YQdAo%;RdH^0xuruN(Yi&+>Re0^8Qa3=WcteQ=_yc*3et8-`l zoK$BL$n`;R{~a+CUhSm}B5Y@DI;DKO%)jjLT#@muVbVm`*VU~jWG%{1E?4!4x4t;v z_ul*DA07=%B9|xbeCK*R)Lr0BbW3{B()HOq&Ou9GnckV5+!?Va$mOW`Vy+F`Q|Fpb z4S8FADdme*jkvc4-?M-nN~iLYihsE-~N`5|6FBnz?E~4!pk@1Fob*B1;lFjo=e@Q{3fhxo;`bK zhP#8{9D_YFV$V4nUf6WpxV~+hIZqUmyZl7M{gq3mObrcFxp(CE@rnQDN7T)q*M4)( zfki>*4xjS3KRzLIn{qy$ zHQUYD@+oEJ3K{XOHak-0M_=08@8YX5t@2V!n`+vR88^E3AE{vaF<1? zW(zC)s7p5XJhIpEOybF}tKCFjtlv=6W?Fc5+TOh{s}CII-fDZ$WAT$;7E$Lt7MGgz zO?+IwA-h%JyY;Iq!9M9Cx&5b;OvRZTb77>wfnd^UuD%FVqn{_VYv?`v zRb`z2G+1i+Z3d;=c>zM=$1m=86?+(M|Jr7OgJ*z^!Ry=g^SS4q`7&4Qd1CR-Nwb5$ z?`^p-o5Q_YMgEl0jIu9}oYVVc_TB2*)b{?sPt)6{>>ar*9jBF1cQHLbB$y0_U!(lyWYu&sC|@`wknbu5l6S+vCQOa_e=KhVYkN**@BH_C58p zt-jo7q4em{W=Geq$tjzIg^f1qwD<*Gyb;jrnjF5lOJDa|pGC>rSNoecHLkk7c!7u9 z&gA+y-Ft5C!&W;zwPy__X*zRU%#|O_V6-|9My8@Auu(TzdHxU&Ynzhc8as zrwNG%uz&M7+sG}~-#7D0|FL^~w|XZSc{*Pz`>2ANK8xgcZ07q!#WmV2bJOM9kL3$rl?dmoKVxc;zCrGbmE6LA9x)L%BLDJdwk>O( zmSOnn-McBDT$bm~d4BDu`r(bjA*+9{zBu7v;6F9PTjpU!OTSMmk7734Hbv#NW`pX7 zj*SaKS!}P*%!r-dsI>n}3`3UOH;zwcUYaS7e|PQIT=e=tnEWjJ(&uY8R5p~v#Bb=j z@#tKR$|S$l&LL;C-OJ40O`0IIgu}(4o&EjmgdcxpG#*X*QYqbH&+vZpE_a`jcQ0qE zGrZJvauQ`{b6mGct?Sx+XUkU~UzslQS87&wRo)n+_(gkb!4dJ@x>iRy<;3=1npN~l zgJr(XUVY6kVeO00ig9N*Sv1x!v~y?r?ELCZl%%wS{t-84l@k*utp2{dg=?quql#r5 zyHgf^J7_ItrY5w^WJatiN3KG&8ROHf>m_cgu_tZ*f2U(|(sq{n0vio;H>~}3hWE8$ z(e2IO+g_DtA6UHJW07*d>VJbpT&eS=C!b+$@h&V~V6t4b%63uywBi<}z=E~971uw{ zeSahERR64}ya&PsX9P`LDDa0{QGnsfVxz;4Kepa+XFrm&v+?)7jgB{_Bp>JoNy&&|Jo~E-`0d}+I@8$_tV+wGn{fWdBb0wD&xAHA-;Ua(~aSA z8BtA}_wvl(u}IweC;O7cU(01@w;rGR{RjJvtOcje@RdbOEEUP9n0sG%&y@Sct5^g+ z1bQ;{?zva8cAwP;Z6y!Us&xmaXl<-?U#j*mJMsOiEq=W#$~b>d{mC));gk<278o8n z9g&ikUE%apen*Sf>%dbNPTKLmFWg+5_5JD9pmk=3TR(o0%UH_E-nVkyv9jL7Y;(5g zZMnN+)}x%BhZ*y-EV>naYm3il#1!FE-b>tj=!O@6?=&(faU9;KGzbCRCb?UG6S-9(BlXc!c zhBI^hL=unMt@*ZepZ2@|@4jXBX75k=+Osi=`Tdpl524Mc5_`XSm}Z>H-1I5+o}v1G(5kAr;Z~om>KJG1q*(vD zF>}Sv#OM<}8a11e8T3}1?fiYL^7oFym!0dUW?pbPFwreTa_)Aa(|_57v;5^A%RcuE zUKzr-;x~_m&G-4YrNXDX@;X0AjazM?|5fOMo<`wDuSIKSl<6<6IX>6<=$U=%(xVLg z8YCY63kfMce`@F6;__?THwa9A+PGVB{<~MrZ=Sx$Oxf}$Bx2nhrtVYbZnKv3e0wRV z_4#U2=N)D-hWFp>Vw((tKRx+->$sLM}>? z7AgyK7XCLoU=en;?fz-byT`DZHksXtYUKhG4kW0|9E#!P`d^V)ui&N|+cae&t~P(<^$rbFAk)r!1- zECV+@zJ5z}vCGMybLMWdJ)gQHVf(t^OzG`ixp$7eTkD}ZJ^#bk?ce4J&RHMe)S;u` zn!R4CnoWAkA8#q1yOVux>^{M){pyfM!4lJnUvvc5|C_-$!|ch0<(~u@FQnXRxRw^K zdyMJeJMPZ?j3=XfvM+sAes${I9q%W{*QY%@UVm|u%K4%ip`0Ms{m+k|oAcax*Zuw1 zX6TpMZ}gmft)Sh4(Pd3d-9^76H|8k$S)Ol>_x^ZnT7<&Jx{KRY?Y?*3@s3UuRD5B* zCYD2G|K2>qs|kGkJ0+QJeymS=!l~8h@9}+0oc;O!1F!k_?%BHjiDOBh&IGRb%-K66 zyk4zYexUNIOP66e!`kEg^MWLWl$ILKo;#Uy`k50_yxt+18El81bako!`rPb==4nkmAs zJn_Q1Emxm59J*WP^(BJO_P_hQyyC6SmA;a8mWS3X3hoeoSi6Vo3QJJU^$kZ3O`MW1 zboEN^Zq>CHwHrFZWHUT$6C&MsF==$ma6fE|qqxPf1N) z+wZ56WVwIl%SGmlQ}P|8DovBD#s8eJX%I7 zBj2>dRja#a%3im$7w23raPf=GYr6T_Z|6EbudRD0-Yh>J?`*HA^^ueP)|n?F&WkpO zrQJ>t&Yknd!FB)3?5xC@f^lqbHZ5W}rKj&*HG_WswYy9H4%eU^E3by$g4z~LOf5wDQ_$t2M zEIQt`a_2hsKSpixM-o@eJi?u(+;C#)nR)*iT~GBLoT#*#v-tM(%qx4|Bxz?aOAwpz z$o7leh4kh3{t9e1GCyjU@Mz1S2Nv7k-M`lK_UMsAKVEUZ`+Im!?4zl%pHIc!TvED3 zZl0$1zp`9A$Ji(t2g~)V(|-N__iod8NNRqvk4vDRdq}5Jnhjlg|0?dbFLQwTO-A0yFDnsTx@u=j^)-p z*Ll~D&bgHGIOfV7i4E-1yX@s8%nG*OGW_T?i>0XAefH|#Sru~Me=B4OyB^uJd#Qi- zvI_T-YrM^M=^I&f+wS&vmA$-WpDiysb;I|>)93E`zB;Q}sTM!!${w3mHz$M6$_tX4 z8ZRAiKY29e>SQm$-QM*NqOMCyJ`_mT%XQ+p*B{WB{Z?73A*a{!$L|@RJi8Yhn&$B| z@|b?LMZxa4+44TmZ;LGQ_?^}6BE>DWRnf{}YX32@#L@?CXXUdpDwldj_-#Jae&EIZ z(%SiR&)hHHeChM|sL*-xix+7X#XdE16FM1jY0nK``?dYjXERdG9v$*&{rUg=?>YXP z&5K&&ysoBq1S?+Zue!me%E@~F0r%D0ooi<{t$MfX=BItPbf>KM-MqM2RrSktr#p`y znqAu}Qr^5t{8H(KpX)lp77B~Zdi1w>kMnH-CgG#r79zfX3jeGV$Pi(_UDHkrL+>>XYYeVb zxX!un%|89g)p<;s%mqcIQMsFx{M`@D47Ar!acZ9Qb#ceLkMlP&YIw0N&SgK}vG(N7 zH;Y!?&U?s^KX=D@#Tt&|-N_4V)k`OI;Z?){f$I+E@ zT|S=qDgQy(%*#_Ya&p+tUClQvJ{!hg+qtCsYk-T1#KXDrH~v(#n6GJg!X)B(JBRl0ESYGf&uKGXtewND7(rW~lMHRoS{ z(fF3sYK6~NkNsObb+VkY+Y;@B69Rj6Ev>q@y1fp#s~mCbQh5L;N7=^A-GbGOh7-K6 zOg2I~Sn~3l%z>v@w_n$po%XaglWF?J1O0qT zK3fcxFUlX;c=pQk!`J41FfHL;7`<(++ZMjxzpFeigld1XJhAY4&u81jy=#RN-RtBI zeft(7_Puz<=SvbtC+8#e=r9-TVN zDV4XZSvTY2;*94}e-*O7%6lc&s@;!R*KtUu$jKprk^7Uw{X53Y7d^LYF1eY%d*;&H zwnYoF%Wg5$t(~EG{>YX8bys%C&su$W?NlR`qUW{~HTHj&5Z_i6Bss(0dhy5ksXiAq zt6s<7FXnhA$g5Y;{US$>o&tBaF$PHIF-Ep_Fkp$&k~D++q&*A(>)wfdRP7U=Ofcs zi3Q$n(aD*isC8xf|K+^p^K{ycHD9`$-`W0(&&ORX@aYL@QI<`NzhuOO-`?n(crowh z+v22Ig6z-JG@nV%J>akMmjA^sx2-#@mKX?hDA!p^J`rl~ShxDM#-$~h;>Ut6wN6c_ znU$Ky!Rgwwc+Ts!W*lp*SXMnu-OJy??VP++q(4e$zLZah>zrSqnGaMG?%sU8q97n> zJ>X!V=ibF)e0`}gkaysl9j+g6^+ji1}TRaj-uLB_b>eE*nbOIQD1 z-+kxndFlA9GVNQJ8IuoXCf*a}T$mRj9#PI6#rZ5{PN7Dfd*9>OyAPgkQA$=>xk}hb QO=srBZEM{+UrsXw00uvViU0rr From 7e0c359f993bb595ac794518bf882414133cd1c2 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 13 May 2022 15:03:40 +0200 Subject: [PATCH 211/245] Fix thread pool join. --- core/thread/thread_pool.odin | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index af80da9aa..2ff3a6a52 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -39,6 +39,7 @@ Pool :: struct { threads: []^Thread, + tasks: [dynamic]Task, tasks_done: [dynamic]Task, } @@ -102,8 +103,15 @@ pool_join :: proc(pool: ^Pool) { yield() - for t in pool.threads { - join(t) + started_count: int + for started_count < len(pool.threads) { + started_count = 0 + for t in pool.threads { + if .Started in t.flags { + join(t) + started_count += 1 + } + } } } From 58fc305b11f1f4fb4b5f7de037947f905e05f849 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 13 May 2022 15:11:33 +0200 Subject: [PATCH 212/245] Do a bit less work for pool_join. --- core/thread/thread_pool.odin | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 2ff3a6a52..840cecfec 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -103,14 +103,18 @@ pool_join :: proc(pool: ^Pool) { yield() + // Because we already stopped the pool, there's no need to take a lock here. + started_count: int for started_count < len(pool.threads) { started_count = 0 for t in pool.threads { if .Started in t.flags { - join(t) started_count += 1 } + if .Joined not_in t.flags { + join(t) + } } } } From 42371f7aea986f7719972e7d3d7c4f93f3f4c490 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Fri, 13 May 2022 15:25:20 +0200 Subject: [PATCH 213/245] Fix fix. --- core/thread/thread_pool.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 840cecfec..4fd5c90d1 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -111,9 +111,9 @@ pool_join :: proc(pool: ^Pool) { for t in pool.threads { if .Started in t.flags { started_count += 1 - } - if .Joined not_in t.flags { - join(t) + if .Joined not_in t.flags { + join(t) + } } } } From 6c0e2e2a53412b4d7ba8b2b3b9bd485af240589b Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 14 May 2022 13:18:38 +0200 Subject: [PATCH 214/245] pool_join should look at .Done. --- core/thread/thread_pool.odin | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 4fd5c90d1..d27ae4255 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -101,16 +101,13 @@ pool_join :: proc(pool: ^Pool) { intrinsics.atomic_store(&pool.is_running, false) sync.post(&pool.sem_available, len(pool.threads)) - yield() - // Because we already stopped the pool, there's no need to take a lock here. - - started_count: int - for started_count < len(pool.threads) { - started_count = 0 + done_count: int + for done_count < len(pool.threads) { + done_count = 0 for t in pool.threads { - if .Started in t.flags { - started_count += 1 + if .Done in t.flags { + done_count += 1 if .Joined not_in t.flags { join(t) } From 3b842ffe29b272ffeccb7fea30d86bca97cb2fce Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 12:27:21 +0100 Subject: [PATCH 215/245] Remove semicolons --- core/builtin/builtin.odin | 132 +++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/core/builtin/builtin.odin b/core/builtin/builtin.odin index 259fdef37..d1cdfa6e7 100644 --- a/core/builtin/builtin.odin +++ b/core/builtin/builtin.odin @@ -1,90 +1,90 @@ // This is purely for documentation package builtin -nil :: nil; -false :: 0!=0; -true :: 0==0; +nil :: nil +false :: 0!=0 +true :: 0==0 -ODIN_OS :: ODIN_OS; -ODIN_ARCH :: ODIN_ARCH; -ODIN_ENDIAN :: ODIN_ENDIAN; -ODIN_VENDOR :: ODIN_VENDOR; -ODIN_VERSION :: ODIN_VERSION; -ODIN_ROOT :: ODIN_ROOT; -ODIN_DEBUG :: ODIN_DEBUG; +ODIN_OS :: ODIN_OS +ODIN_ARCH :: ODIN_ARCH +ODIN_ENDIAN :: ODIN_ENDIAN +ODIN_VENDOR :: ODIN_VENDOR +ODIN_VERSION :: ODIN_VERSION +ODIN_ROOT :: ODIN_ROOT +ODIN_DEBUG :: ODIN_DEBUG -byte :: u8; // alias +byte :: u8 // alias -bool :: bool; -b8 :: b8; -b16 :: b16; -b32 :: b32; -b64 :: b64; +bool :: bool +b8 :: b8 +b16 :: b16 +b32 :: b32 +b64 :: b64 -i8 :: i8; -u8 :: u8; -i16 :: i16; -u16 :: u16; -i32 :: i32; -u32 :: u32; -i64 :: i64; -u64 :: u64; +i8 :: i8 +u8 :: u8 +i16 :: i16 +u16 :: u16 +i32 :: i32 +u32 :: u32 +i64 :: i64 +u64 :: u64 -i128 :: i128; -u128 :: u128; +i128 :: i128 +u128 :: u128 -rune :: rune; +rune :: rune -f16 :: f16; -f32 :: f32; -f64 :: f64; +f16 :: f16 +f32 :: f32 +f64 :: f64 -complex32 :: complex32; -complex64 :: complex64; -complex128 :: complex128; +complex32 :: complex32 +complex64 :: complex64 +complex128 :: complex128 -quaternion64 :: quaternion64; -quaternion128 :: quaternion128; -quaternion256 :: quaternion256; +quaternion64 :: quaternion64 +quaternion128 :: quaternion128 +quaternion256 :: quaternion256 -int :: int; -uint :: uint; -uintptr :: uintptr; +int :: int +uint :: uint +uintptr :: uintptr -rawptr :: rawptr; -string :: string; -cstring :: cstring; -any :: any; +rawptr :: rawptr +string :: string +cstring :: cstring +any :: any -typeid :: typeid; +typeid :: typeid // Endian Specific Types -i16le :: i16le; -u16le :: u16le; -i32le :: i32le; -u32le :: u32le; -i64le :: i64le; -u64le :: u64le; -i128le :: i128le; -u128le :: u128le; +i16le :: i16le +u16le :: u16le +i32le :: i32le +u32le :: u32le +i64le :: i64le +u64le :: u64le +i128le :: i128le +u128le :: u128le -i16be :: i16be; -u16be :: u16be; -i32be :: i32be; -u32be :: u32be; -i64be :: i64be; -u64be :: u64be; -i128be :: i128be; -u128be :: u128be; +i16be :: i16be +u16be :: u16be +i32be :: i32be +u32be :: u32be +i64be :: i64be +u64be :: u64be +i128be :: i128be +u128be :: u128be -f16le :: f16le; -f32le :: f32le; -f64le :: f64le; +f16le :: f16le +f32le :: f32le +f64le :: f64le -f16be :: f16be; -f32be :: f32be; -f64be :: f64be; +f16be :: f16be +f32be :: f32be +f64be :: f64be From 85edcf9cc204751ac8e7a8ac541df712caeb4014 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 14 May 2022 13:34:52 +0200 Subject: [PATCH 216/245] Revert. --- core/thread/thread_pool.odin | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index d27ae4255..820de8ad4 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -101,13 +101,14 @@ pool_join :: proc(pool: ^Pool) { intrinsics.atomic_store(&pool.is_running, false) sync.post(&pool.sem_available, len(pool.threads)) - // Because we already stopped the pool, there's no need to take a lock here. - done_count: int - for done_count < len(pool.threads) { - done_count = 0 + yield() + +started_count: int + for started_count < len(pool.threads) { + started_count = 0 for t in pool.threads { - if .Done in t.flags { - done_count += 1 + if .Started in t.flags { + started_count += 1 if .Joined not_in t.flags { join(t) } From 0cca42a1f4666767d6a138c66ba6b9db4ffa448a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 13:46:10 +0100 Subject: [PATCH 217/245] Add `image.which` file format testing procedures --- core/image/which.odin | 150 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 core/image/which.odin diff --git a/core/image/which.odin b/core/image/which.odin new file mode 100644 index 000000000..771506332 --- /dev/null +++ b/core/image/which.odin @@ -0,0 +1,150 @@ +package image + +import "core:os" + +Which_File_Type :: enum { + Unknown, + + BMP, + EXR, + GIF, + HDR, // Radiance RGBE HDR + JPEG, + PBM, PGM, PPM, // NetPBM family + PIC, // Softimage PIC + PNG, + PSD, // Photoshop PSD + QOI, + SGI_RGB, // Silicon Graphics Image RGB file format + Sun_Rast, // Sun Raster Graphic + TGA, // Targa Truevision + TIFF, + WebP, + XBM, // X BitMap +} + +which :: proc{ + which_bytes, + which_file, +} + +which_bytes :: proc(data: []byte) -> Which_File_Type { + test_tga :: proc(s: string) -> bool { + get8 :: #force_inline proc(s: ^string) -> u8 { + v := s[0] + s^ = s[1:] + return v + } + get16le :: #force_inline proc(s: ^string) -> u16 { + v := u16(s[0]) | u16(s[1])<<16 + s^ = s[2:] + return v + } + s := s + s = s[1:] // skip offset + + color_type := get8(&s) + if color_type > 1 { + return false + } + image_type := get8(&s) // image type + if color_type == 1 { // Colormap (Paletted) Image + if image_type != 1 && image_type != 9 { // color type requires 1 or 9 + return false + } + s = s[4:] // skip index of first colormap + bpcme := get8(&s) // check bits per colormap entry + if bpcme != 8 && bpcme != 15 && bpcme != 16 && bpcme != 24 && bpcme != 32 { + return false + } + s = s[4:] // skip image origin (x, y) + } else { // Normal image without colormap + if image_type != 2 && image_type != 3 && image_type != 10 && image_type != 11 { + return false + } + s = s[9:] // skip colormap specification + } + if get16le(&s) < 1 || get16le(&s) < 1 { // test width and height + return false + } + bpp := get8(&s) // bits per pixel + if color_type == 1 && bpp != 8 && bpp != 16 { + return false + } + if bpp != 8 && bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32 { + return false + } + return true + } + + header: [128]byte + copy(header[:], data) + s := string(header[:]) + + switch { + case s[:2] == "BM": + return .BMP + case s[:4] == "\x76\x2f\x31\x01": + return .EXR + case s[:6] == "GIF87a", s[:6] == "GIF89a": + return .GIF + case s[6:10] == "JFIF", s[6:10] == "Exif": + return .JPEG + case s[:4] == "\xff\xd8\xff\xdb": + return .JPEG + case s[0] == 'P': + switch s[2] { + case '\t', '\n', '\r': + switch s[1] { + case '1', '4': + return .PBM + case '2', '5': + return .PGM + case '3', '6': + return .PPM + } + } + case s[:8] == "\x89PNG\r\n\x1a\n": + return .PNG + case s[:4] == "qoif": + return .QOI + case s[:2] == "\x01\xda": + return .SGI_RGB + case s[:4] == "\x59\xA6\x6A\x95": + return .Sun_Rast + case s[:2] == "MM", s[:2] == "II": + return .TIFF + case s[:4] == "RIFF" && s[8:12] == "WEBP": + return .WebP + case s[:8] == "#define ": + return .XBM + + case s[:11] == "#?RADIANCE\n", s[:7] == "#?RGBE\n": + return .HDR + case s[:4] == "\x38\x42\x50\x53": + return .PSD + case s[:4] != "\x53\x80\xF6\x34" && s[88:92] == "PICT": + return .PIC + case: + // More complex formats + if test_tga(s) { + return .TGA + } + + + } + return .Unknown +} + + +which_file :: proc(path: string) -> Which_File_Type { + f, err := os.open(path) + if err != 0 { + return .Unknown + } + header: [128]byte + os.read(f, header[:]) + file_type := which_bytes(header[:]) + os.close(f) + return file_type +} \ No newline at end of file From f17a9dd5e7921ddf288de266b463ac01a680ca48 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 13:59:49 +0100 Subject: [PATCH 218/245] Add even more file formats --- core/image/which.odin | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/core/image/which.odin b/core/image/which.odin index 771506332..c34f7fe35 100644 --- a/core/image/which.odin +++ b/core/image/which.odin @@ -7,18 +7,22 @@ Which_File_Type :: enum { BMP, EXR, + FLIF, GIF, HDR, // Radiance RGBE HDR + ICNS, // Apple Icon Image JPEG, + JPEG_2000, + JPEG_XL, PBM, PGM, PPM, // NetPBM family PIC, // Softimage PIC - PNG, + PNG, // Portable Network Graphics PSD, // Photoshop PSD - QOI, + QOI, // Quite Okay Image SGI_RGB, // Silicon Graphics Image RGB file format Sun_Rast, // Sun Raster Graphic TGA, // Targa Truevision - TIFF, + TIFF, // Tagged Image File Format WebP, XBM, // X BitMap } @@ -90,8 +94,19 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { return .GIF case s[6:10] == "JFIF", s[6:10] == "Exif": return .JPEG - case s[:4] == "\xff\xd8\xff\xdb": - return .JPEG + case s[:3] == "\xff\xd8\xff": + switch s[4] { + case 0xdb, 0xee, 0xe1, 0xe0: + return .JPEG + } + switch { + case s[:12] == "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01": + return .JPEG + } + case s[:4] == "\xff\x4f\xff\x51", s[:12] == "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a": + return .JPEG_2000 + case s[:12] == "\x00\x00\x00\x0c\x4a\x58\x4c\x20\x0d\x0a\x87\x0a": + return .JPEG_XL case s[0] == 'P': switch s[2] { case '\t', '\n', '\r': @@ -112,7 +127,7 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { return .SGI_RGB case s[:4] == "\x59\xA6\x6A\x95": return .Sun_Rast - case s[:2] == "MM", s[:2] == "II": + case s[:4] == "MM\x2a\x00", s[:4] == "II\x00\x2A": return .TIFF case s[:4] == "RIFF" && s[8:12] == "WEBP": return .WebP @@ -125,6 +140,10 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { return .PSD case s[:4] != "\x53\x80\xF6\x34" && s[88:92] == "PICT": return .PIC + case s[:4] == "\x69\x63\x6e\x73": + return .ICNS + case s[:4] == "\x46\x4c\x49\x46": + return .FLIF case: // More complex formats if test_tga(s) { From 7057f5fc115db9413b33a60833e9b02fb4234842 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 14 May 2022 15:17:37 +0200 Subject: [PATCH 219/245] Add PAM and PFM to format detection. --- core/image/which.odin | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/image/which.odin b/core/image/which.odin index c34f7fe35..30cb78405 100644 --- a/core/image/which.odin +++ b/core/image/which.odin @@ -14,7 +14,7 @@ Which_File_Type :: enum { JPEG, JPEG_2000, JPEG_XL, - PBM, PGM, PPM, // NetPBM family + PBM, PGM, PPM, PAM, PFM, // NetPBM family PIC, // Softimage PIC PNG, // Portable Network Graphics PSD, // Photoshop PSD @@ -117,6 +117,10 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { return .PGM case '3', '6': return .PPM + case '7': + return .PAM + case 'F', 'f': + return .PFM } } case s[:8] == "\x89PNG\r\n\x1a\n": From 9921ac01cca70d30bbb551070d72bc8e7f651def Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:26:11 +0100 Subject: [PATCH 220/245] Add more NetPBM variants --- core/image/which.odin | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/image/which.odin b/core/image/which.odin index c34f7fe35..c3caef621 100644 --- a/core/image/which.odin +++ b/core/image/which.odin @@ -14,7 +14,7 @@ Which_File_Type :: enum { JPEG, JPEG_2000, JPEG_XL, - PBM, PGM, PPM, // NetPBM family + PBM, PGM, PPM, PAM, PFM, // NetPBM family PIC, // Softimage PIC PNG, // Portable Network Graphics PSD, // Photoshop PSD @@ -117,6 +117,10 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { return .PGM case '3', '6': return .PPM + case '7': + return .PAM + case 'f', 'F': + return .PFM } } case s[:8] == "\x89PNG\r\n\x1a\n": From 01e8e682c0a6021c117553c53f181487be1c841c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:38:26 +0100 Subject: [PATCH 221/245] Generalized `core:image` loader ```odin import "core:image" import "core:image/png" ... img, err := image.load_from_file("path.png") ``` --- core/image/common.odin | 1 + core/image/general_loader.odin | 39 ++++++++++++++++++++++++++++++++++ core/image/netpbm/netpbm.odin | 12 +++++++++++ core/image/png/png.odin | 6 ++++++ core/image/qoi/qoi.odin | 5 +++++ 5 files changed, 63 insertions(+) create mode 100644 core/image/general_loader.odin diff --git a/core/image/common.odin b/core/image/common.odin index 4085a0a05..75a649e52 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -172,6 +172,7 @@ General_Image_Error :: enum { Unable_To_Write_File, // Invalid + Unsupported_Format, Invalid_Signature, Invalid_Input_Image, Image_Dimensions_Too_Large, diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin new file mode 100644 index 000000000..73f50f055 --- /dev/null +++ b/core/image/general_loader.odin @@ -0,0 +1,39 @@ +package image + +import "core:mem" +import "core:os" + +Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) + +@(private) +_internal_loaders: [Which_File_Type]Loader_Proc + +register_loader :: proc(kind: Which_File_Type, loader: Loader_Proc) { + assert(_internal_loaders[kind] == nil) + _internal_loaders[kind] = loader +} + +load :: proc{ + load_from_slice, + load_from_file, +} + +load_from_slice :: proc(data: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + loader := _internal_loaders[which(data)] + if loader == nil { + return nil, .Unsupported_Format + } + return loader(data, options, allocator) +} + + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + data, ok := os.read_entire_file(filename, allocator) + defer delete(data, allocator) + if ok { + return load_from_slice(data, options, allocator) + } else { + img = new(Image, allocator) + return img, .Unable_To_Read_File + } +} diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 9574faa26..bcc78c402 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -748,4 +748,16 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for // We couldn't find a suitable format return {}, false +} + +@(init, private) +_register :: proc() { + loader :: proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { + return load_from_buffer(data, allocator) + } + register_loader(.PBM, loader) + register_loader(.PGM, loader) + register_loader(.PPM, loader) + register_loader(.PAM, loader) + register_loader(.PFM, loader) } \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index d526dfb27..3dcd0df38 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1640,3 +1640,9 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH } load :: proc{load_from_file, load_from_slice, load_from_context} + + +@(init, private) +_register :: proc() { + image.register_loader(.PNG, load_from_slice) +} \ No newline at end of file diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 83b212be8..346356094 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -403,4 +403,9 @@ qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) { i4 := u16(pixel.a) * 11 return u8((i1 + i2 + i3 + i4) & 63) +} + +@(init, private) +_register :: proc() { + image.register_loader(.QOI, load_from_slice) } \ No newline at end of file From 5af7004f442c9790b176b46053185c42f9d65704 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:43:50 +0100 Subject: [PATCH 222/245] Add image packages to examples/all --- core/image/netpbm/netpbm.odin | 10 +++++----- examples/all/all_main.odin | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index bcc78c402..fb88cdc8c 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -755,9 +755,9 @@ _register :: proc() { loader :: proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { return load_from_buffer(data, allocator) } - register_loader(.PBM, loader) - register_loader(.PGM, loader) - register_loader(.PPM, loader) - register_loader(.PAM, loader) - register_loader(.PFM, loader) + image.register_loader(.PBM, loader) + image.register_loader(.PGM, loader) + image.register_loader(.PPM, loader) + image.register_loader(.PAM, loader) + image.register_loader(.PFM, loader) } \ No newline at end of file diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 36acf7714..5a0bc4d3e 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -62,8 +62,10 @@ import fmt "core:fmt" import hash "core:hash" import image "core:image" +import netpbm "core:image/netpbm" import png "core:image/png" import qoi "core:image/qoi" +import tga "core:image/tga" import io "core:io" import log "core:log" From 5bc866e420d8eb9e909db71e230d1283c6116d7e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:44:24 +0100 Subject: [PATCH 223/245] Allow for `import _ "foo"` to allow for `@(init)` procedures; Remove `using import` code --- src/checker.cpp | 48 ++++++++++-------------------------------------- src/parser.cpp | 14 ++++---------- src/parser.hpp | 1 - 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index d186163e4..da9a97622 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4356,6 +4356,9 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { } String import_name = path_to_entity_name(id->import_name.string, id->fullpath, false); + if (is_blank_ident(import_name)) { + force_use = true; + } // NOTE(bill, 2019-05-19): If the directory path is not a valid entity name, force the user to assign a custom one // if (import_name.len == 0 || import_name == "_") { @@ -4363,17 +4366,13 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { // } if (import_name.len == 0 || is_blank_ident(import_name)) { - if (id->is_using) { - // TODO(bill): Should this be a warning? - } else { - if (id->import_name.string == "") { - String invalid_name = id->fullpath; - invalid_name = get_invalid_import_name(invalid_name); + if (id->import_name.string == "") { + String invalid_name = id->fullpath; + invalid_name = get_invalid_import_name(invalid_name); - error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import \"%.*s\" ", LIT(invalid_name), LIT(invalid_name)); - } else { - error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string)); - } + error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import \"%.*s\" ", LIT(invalid_name), LIT(invalid_name)); + } else { + error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string)); } } else { GB_ASSERT(id->import_name.pos.line != 0); @@ -4383,38 +4382,11 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { scope); add_entity(ctx, parent_scope, nullptr, e); - if (force_use || id->is_using) { + if (force_use) { add_entity_use(ctx, nullptr, e); } } - if (id->is_using) { - if (parent_scope->flags & ScopeFlag_Global) { - error(id->import_name, "built-in package imports cannot use using"); - return; - } - - // NOTE(bill): Add imported entities to this file's scope - for_array(elem_index, scope->elements.entries) { - String name = scope->elements.entries[elem_index].key.string; - Entity *e = scope->elements.entries[elem_index].value; - if (e->scope == parent_scope) continue; - - if (is_entity_exported(e, true)) { - Entity *found = scope_lookup_current(parent_scope, name); - if (found != nullptr) { - // NOTE(bill): - // Date: 2019-03-17 - // The order has to be the other way around as `using` adds the entity into the that - // file scope otherwise the error would be the wrong way around - redeclaration_error(name, found, e); - } else { - add_entity_with_name(ctx, parent_scope, e->identifier, e, name); - } - } - } - } - scope->flags |= ScopeFlag_HasBeenImported; } diff --git a/src/parser.cpp b/src/parser.cpp index df7f908a6..1f4093e5f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1160,11 +1160,10 @@ Ast *ast_package_decl(AstFile *f, Token token, Token name, CommentGroup *docs, C return result; } -Ast *ast_import_decl(AstFile *f, Token token, bool is_using, Token relpath, Token import_name, +Ast *ast_import_decl(AstFile *f, Token token, Token relpath, Token import_name, CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ImportDecl); result->ImportDecl.token = token; - result->ImportDecl.is_using = is_using; result->ImportDecl.relpath = relpath; result->ImportDecl.import_name = import_name; result->ImportDecl.docs = docs; @@ -4382,7 +4381,6 @@ Ast *parse_import_decl(AstFile *f, ImportDeclKind kind) { CommentGroup *docs = f->lead_comment; Token token = expect_token(f, Token_import); Token import_name = {}; - bool is_using = kind != ImportDecl_Standard; switch (f->curr_token.kind) { case Token_Ident: @@ -4393,22 +4391,18 @@ Ast *parse_import_decl(AstFile *f, ImportDeclKind kind) { break; } - if (!is_using && is_blank_ident(import_name)) { - syntax_error(import_name, "Illegal import name: '_'"); - } - Token file_path = expect_token_after(f, Token_String, "import"); Ast *s = nullptr; if (f->curr_proc != nullptr) { - syntax_error(import_name, "You cannot use 'import' within a procedure. This must be done at the file scope"); + syntax_error(import_name, "Cannot use 'import' within a procedure. This must be done at the file scope"); s = ast_bad_decl(f, import_name, file_path); } else { - s = ast_import_decl(f, token, is_using, file_path, import_name, docs, f->line_comment); + s = ast_import_decl(f, token, file_path, import_name, docs, f->line_comment); array_add(&f->imports, s); } - if (is_using) { + if (kind != ImportDecl_Standard) { syntax_error(import_name, "'using import' is not allowed, please use the import name explicitly"); } diff --git a/src/parser.hpp b/src/parser.hpp index c7b4fd0d8..698ed7623 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -585,7 +585,6 @@ AST_KIND(_DeclBegin, "", bool) \ Token import_name; \ CommentGroup *docs; \ CommentGroup *comment; \ - bool is_using; \ }) \ AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \ Token token; \ From e46d87b2210a1e2f0aa95827808f3b69b11f17dc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:47:58 +0100 Subject: [PATCH 224/245] Fix type and keep -vet happy --- core/image/netpbm/netpbm.odin | 2 +- core/image/tga/tga.odin | 1 - examples/all/all_main.odin | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index fb88cdc8c..83c8a2f59 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -752,7 +752,7 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for @(init, private) _register :: proc() { - loader :: proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { + loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { return load_from_buffer(data, allocator) } image.register_loader(.PBM, loader) diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 0539706b3..67a088eb5 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -12,7 +12,6 @@ package tga import "core:mem" import "core:image" -import "core:compress" import "core:bytes" import "core:os" diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 5a0bc4d3e..36326b48e 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -166,8 +166,10 @@ _ :: xml _ :: fmt _ :: hash _ :: image +_ :: netpbm _ :: png _ :: qoi +_ :: tga _ :: io _ :: log _ :: math From 9c1f270bd56e367a34691517daa11194d2ef14e9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 14:55:15 +0100 Subject: [PATCH 225/245] Rename `load_from_slice` to `load_from_bytes` across `core` --- core/compress/gzip/example.odin | 2 +- core/compress/gzip/gzip.odin | 8 ++++---- core/image/general_loader.odin | 6 +++--- core/image/png/png.odin | 14 ++++++-------- core/image/qoi/qoi.odin | 10 +++++----- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/core/compress/gzip/example.odin b/core/compress/gzip/example.odin index 0e2c2b9f6..c010d5979 100644 --- a/core/compress/gzip/example.odin +++ b/core/compress/gzip/example.odin @@ -45,7 +45,7 @@ main :: proc() { if len(args) < 2 { stderr("No input file specified.\n") - err := load(slice=TEST, buf=&buf, known_gzip_size=len(TEST)) + err := load(data=TEST, buf=&buf, known_gzip_size=len(TEST)) if err == nil { stdout("Displaying test vector: ") stdout(bytes.buffer_to_string(&buf)) diff --git a/core/compress/gzip/gzip.odin b/core/compress/gzip/gzip.odin index 4482d4a7e..4de4d1b63 100644 --- a/core/compress/gzip/gzip.odin +++ b/core/compress/gzip/gzip.odin @@ -102,7 +102,7 @@ E_Deflate :: compress.Deflate_Error GZIP_MAX_PAYLOAD_SIZE :: i64(max(u32le)) -load :: proc{load_from_slice, load_from_file, load_from_context} +load :: proc{load_from_bytes, load_from_file, load_from_context} load_from_file :: proc(filename: string, buf: ^bytes.Buffer, expected_output_size := -1, allocator := context.allocator) -> (err: Error) { context.allocator = allocator @@ -112,16 +112,16 @@ load_from_file :: proc(filename: string, buf: ^bytes.Buffer, expected_output_siz err = E_General.File_Not_Found if ok { - err = load_from_slice(data, buf, len(data), expected_output_size) + err = load_from_bytes(data, buf, len(data), expected_output_size) } return } -load_from_slice :: proc(slice: []u8, buf: ^bytes.Buffer, known_gzip_size := -1, expected_output_size := -1, allocator := context.allocator) -> (err: Error) { +load_from_bytes :: proc(data: []byte, buf: ^bytes.Buffer, known_gzip_size := -1, expected_output_size := -1, allocator := context.allocator) -> (err: Error) { buf := buf z := &compress.Context_Memory_Input{ - input_data = slice, + input_data = data, output = buf, } return load_from_context(z, buf, known_gzip_size, expected_output_size, allocator) diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index 73f50f055..4cc8569ab 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -14,11 +14,11 @@ register_loader :: proc(kind: Which_File_Type, loader: Loader_Proc) { } load :: proc{ - load_from_slice, + load_from_bytes, load_from_file, } -load_from_slice :: proc(data: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { +load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { loader := _internal_loaders[which(data)] if loader == nil { return nil, .Unsupported_Format @@ -31,7 +31,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont data, ok := os.read_entire_file(filename, allocator) defer delete(data, allocator) if ok { - return load_from_slice(data, options, allocator) + return load_from_bytes(data, options, allocator) } else { img = new(Image, allocator) return img, .Unable_To_Read_File diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 3dcd0df38..f91ad2b66 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -18,7 +18,6 @@ import "core:compress/zlib" import "core:image" import "core:os" -import "core:strings" import "core:hash" import "core:bytes" import "core:io" @@ -318,13 +317,12 @@ read_header :: proc(ctx: ^$C) -> (image.PNG_IHDR, Error) { } chunk_type_to_name :: proc(type: ^image.PNG_Chunk_Type) -> string { - t := transmute(^u8)type - return strings.string_from_ptr(t, 4) + return string(([^]u8)(type)[:4]) } -load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { +load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { ctx := &compress.Context_Memory_Input{ - input_data = slice, + input_data = data, } /* @@ -344,7 +342,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont defer delete(data) if ok { - return load_from_slice(data, options) + return load_from_bytes(data, options) } else { img = new(Image) return img, .Unable_To_Read_File @@ -1639,10 +1637,10 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH return nil } -load :: proc{load_from_file, load_from_slice, load_from_context} +load :: proc{load_from_file, load_from_bytes, load_from_context} @(init, private) _register :: proc() { - image.register_loader(.PNG, load_from_slice) + image.register_loader(.PNG, load_from_bytes) } \ No newline at end of file diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 346356094..884f4963b 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -180,9 +180,9 @@ save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocato save :: proc{save_to_memory, save_to_file} -load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { +load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { ctx := &compress.Context_Memory_Input{ - input_data = slice, + input_data = data, } img, err = load_from_context(ctx, options, allocator) @@ -196,7 +196,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont defer delete(data) if ok { - return load_from_slice(data, options) + return load_from_bytes(data, options) } else { img = new(Image) return img, .Unable_To_Read_File @@ -359,7 +359,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return } -load :: proc{load_from_file, load_from_slice, load_from_context} +load :: proc{load_from_file, load_from_bytes, load_from_context} /* Cleanup of image-specific data. @@ -407,5 +407,5 @@ qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) { @(init, private) _register :: proc() { - image.register_loader(.QOI, load_from_slice) + image.register_loader(.QOI, load_from_bytes) } \ No newline at end of file From 4e080057fb0f24e66bb6ad4eccb931f1f325da9b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:01:17 +0100 Subject: [PATCH 226/245] Rename `load_from_buffer` to `load_from_bytes` --- core/image/netpbm/netpbm.odin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 83c8a2f59..bfaf49fc6 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -28,7 +28,7 @@ BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM load :: proc { load_from_file, - load_from_buffer, + load_from_bytes, } load_from_file :: proc(filename: string, allocator := context.allocator) -> (img: ^Image, err: Error) { @@ -40,10 +40,10 @@ load_from_file :: proc(filename: string, allocator := context.allocator) -> (img return } - return load_from_buffer(data) + return load_from_bytes(data) } -load_from_buffer :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { +load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator img = new(Image) @@ -753,7 +753,7 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for @(init, private) _register :: proc() { loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { - return load_from_buffer(data, allocator) + return load_from_bytes(data, allocator) } image.register_loader(.PBM, loader) image.register_loader(.PGM, loader) From 3aa0a733f3b59388ae320f07cfabb1f4e7f0cec2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:06:55 +0100 Subject: [PATCH 227/245] Add `destroy` with loader --- core/image/general_loader.odin | 12 +++++++++--- core/image/netpbm/netpbm.odin | 13 ++++++++----- core/image/png/png.odin | 5 ++--- core/image/qoi/qoi.odin | 5 ++--- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index 4cc8569ab..3acffb452 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -4,13 +4,20 @@ import "core:mem" import "core:os" Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) +Destroy_Proc :: #type proc(img: ^Image) @(private) _internal_loaders: [Which_File_Type]Loader_Proc +_internal_destroyers: [Which_File_Type]Destroy_Proc -register_loader :: proc(kind: Which_File_Type, loader: Loader_Proc) { +register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) { + assert(loader != nil) + assert(destroyer != nil) assert(_internal_loaders[kind] == nil) _internal_loaders[kind] = loader + + assert(_internal_destroyers[kind] == nil) + _internal_destroyers[kind] = destroyer } load :: proc{ @@ -33,7 +40,6 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont if ok { return load_from_bytes(data, options, allocator) } else { - img = new(Image, allocator) - return img, .Unable_To_Read_File + return nil, .Unable_To_Read_File } } diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index bfaf49fc6..778ec2c5e 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -755,9 +755,12 @@ _register :: proc() { loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { return load_from_bytes(data, allocator) } - image.register_loader(.PBM, loader) - image.register_loader(.PGM, loader) - image.register_loader(.PPM, loader) - image.register_loader(.PAM, loader) - image.register_loader(.PFM, loader) + destroyer :: proc(img: ^Image) { + _ = destroy(img) + } + image.register(.PBM, loader, destroyer) + image.register(.PGM, loader, destroyer) + image.register(.PPM, loader, destroyer) + image.register(.PAM, loader, destroyer) + image.register(.PFM, loader, destroyer) } \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index f91ad2b66..ea888d0ad 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -344,8 +344,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont if ok { return load_from_bytes(data, options) } else { - img = new(Image) - return img, .Unable_To_Read_File + return nil, .Unable_To_Read_File } } @@ -1642,5 +1641,5 @@ load :: proc{load_from_file, load_from_bytes, load_from_context} @(init, private) _register :: proc() { - image.register_loader(.PNG, load_from_bytes) + image.register(.PNG, load_from_bytes, destroy) } \ No newline at end of file diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 884f4963b..f10f2ff56 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -198,8 +198,7 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont if ok { return load_from_bytes(data, options) } else { - img = new(Image) - return img, .Unable_To_Read_File + return nil, .Unable_To_Read_File } } @@ -407,5 +406,5 @@ qoi_hash :: #force_inline proc(pixel: RGBA_Pixel) -> (index: u8) { @(init, private) _register :: proc() { - image.register_loader(.QOI, load_from_bytes) + image.register(.QOI, load_from_bytes, destroy) } \ No newline at end of file From c516fb947f7aafd00363dfcdaefa79f96e4f4ee5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:11:23 +0100 Subject: [PATCH 228/245] Add `image.destroy` --- core/image/common.odin | 1 + core/image/general_loader.odin | 13 +++++++++++++ core/image/netpbm/netpbm.odin | 7 ++----- core/image/png/png.odin | 1 + core/image/qoi/qoi.odin | 1 + core/image/which.odin | 22 +++++++++++----------- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/core/image/common.odin b/core/image/common.odin index 75a649e52..28129a6e1 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -54,6 +54,7 @@ Image :: struct { */ background: Maybe(RGB_Pixel_16), metadata: Image_Metadata, + which: Which_File_Type, } Image_Metadata :: union { diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index 3acffb452..79f5fb737 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -43,3 +43,16 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont return nil, .Unable_To_Read_File } } + +destroy :: proc(img: ^Image, allocator := context.allocator) -> bool { + if img == nil { + return true + } + context.allocator = allocator + destroyer := _internal_destroyers[img.which] + if destroyer != nil { + destroyer(img) + } + free(img) + return true +} \ No newline at end of file diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index 778ec2c5e..5a504cd7c 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -47,6 +47,7 @@ load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^ context.allocator = allocator img = new(Image) + img.which = .NetPBM header: Header; defer header_destroy(&header) header_size: int @@ -758,9 +759,5 @@ _register :: proc() { destroyer :: proc(img: ^Image) { _ = destroy(img) } - image.register(.PBM, loader, destroyer) - image.register(.PGM, loader, destroyer) - image.register(.PPM, loader, destroyer) - image.register(.PAM, loader, destroyer) - image.register(.PFM, loader, destroyer) + image.register(.NetPBM, loader, destroyer) } \ No newline at end of file diff --git a/core/image/png/png.odin b/core/image/png/png.odin index ea888d0ad..35fdb58d8 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -372,6 +372,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a if img == nil { img = new(Image) } + img.which = .PNG info := new(image.PNG_Info) img.metadata = info diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index f10f2ff56..29a17d4f4 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -224,6 +224,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a if img == nil { img = new(Image) } + img.which = .QOI if .return_metadata in options { info := new(image.QOI_Info) diff --git a/core/image/which.odin b/core/image/which.odin index 30cb78405..82cb03ce6 100644 --- a/core/image/which.odin +++ b/core/image/which.odin @@ -14,7 +14,7 @@ Which_File_Type :: enum { JPEG, JPEG_2000, JPEG_XL, - PBM, PGM, PPM, PAM, PFM, // NetPBM family + NetPBM, // NetPBM family PIC, // Softimage PIC PNG, // Portable Network Graphics PSD, // Photoshop PSD @@ -111,16 +111,16 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { switch s[2] { case '\t', '\n', '\r': switch s[1] { - case '1', '4': - return .PBM - case '2', '5': - return .PGM - case '3', '6': - return .PPM - case '7': - return .PAM - case 'F', 'f': - return .PFM + case '1', '4': // PBM + return .NetPBM + case '2', '5': // PGM + return .NetPBM + case '3', '6': // PPM + return .NetPBM + case '7': // PAM + return .NetPBM + case 'F', 'f': // PFM + return .NetPBM } } case s[:8] == "\x89PNG\r\n\x1a\n": From e8485ee7e7b5487bad1e195235a93543c82b630a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:15:04 +0100 Subject: [PATCH 229/245] Correction to `image.destroy` --- core/image/common.odin | 2 +- core/image/general_loader.odin | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/image/common.odin b/core/image/common.odin index 28129a6e1..baacd64d9 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -57,7 +57,7 @@ Image :: struct { which: Which_File_Type, } -Image_Metadata :: union { +Image_Metadata :: union #shared_nil { ^Netpbm_Info, ^PNG_Info, ^QOI_Info, diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index 79f5fb737..bf0061311 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -52,7 +52,9 @@ destroy :: proc(img: ^Image, allocator := context.allocator) -> bool { destroyer := _internal_destroyers[img.which] if destroyer != nil { destroyer(img) + } else { + assert(img.metadata == nil) + free(img) } - free(img) return true } \ No newline at end of file From 22dc02064795a72d5ea4704195638e6f10d7b434 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:16:14 +0100 Subject: [PATCH 230/245] Destroy pixel buffer --- core/image/general_loader.odin | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index bf0061311..21a662967 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -2,6 +2,7 @@ package image import "core:mem" import "core:os" +import "core:bytes" Loader_Proc :: #type proc(data: []byte, options: Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) Destroy_Proc :: #type proc(img: ^Image) @@ -54,6 +55,7 @@ destroy :: proc(img: ^Image, allocator := context.allocator) -> bool { destroyer(img) } else { assert(img.metadata == nil) + bytes.buffer_destroy(&img.pixels) free(img) } return true From d74e4b427d873b56bf6069c674107197fc44774b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:16:56 +0100 Subject: [PATCH 231/245] Remove `bool` return on `image.destroy` --- core/image/general_loader.odin | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/image/general_loader.odin b/core/image/general_loader.odin index 21a662967..36629c39e 100644 --- a/core/image/general_loader.odin +++ b/core/image/general_loader.odin @@ -45,9 +45,9 @@ load_from_file :: proc(filename: string, options := Options{}, allocator := cont } } -destroy :: proc(img: ^Image, allocator := context.allocator) -> bool { +destroy :: proc(img: ^Image, allocator := context.allocator) { if img == nil { - return true + return } context.allocator = allocator destroyer := _internal_destroyers[img.which] @@ -58,5 +58,4 @@ destroy :: proc(img: ^Image, allocator := context.allocator) -> bool { bytes.buffer_destroy(&img.pixels) free(img) } - return true } \ No newline at end of file From f7b18cd86ebce34f4b62ba313a998bc45c513d04 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 14 May 2022 15:32:28 +0100 Subject: [PATCH 232/245] Add DjVu --- core/image/which.odin | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/image/which.odin b/core/image/which.odin index 82cb03ce6..ab608174f 100644 --- a/core/image/which.odin +++ b/core/image/which.odin @@ -6,6 +6,7 @@ Which_File_Type :: enum { Unknown, BMP, + DjVu, // AT&T DjVu file format EXR, FLIF, GIF, @@ -88,6 +89,11 @@ which_bytes :: proc(data: []byte) -> Which_File_Type { switch { case s[:2] == "BM": return .BMP + case s[:8] == "AT&TFORM": + switch s[12:16] { + case "DJVU", "DJVM": + return .DjVu + } case s[:4] == "\x76\x2f\x31\x01": return .EXR case s[:6] == "GIF87a", s[:6] == "GIF89a": From b5b329378f8b90f2de199a51d8b88056ffe7980a Mon Sep 17 00:00:00 2001 From: Tetralux Date: Sat, 14 May 2022 19:17:58 +0000 Subject: [PATCH 233/245] [os] Linux: Add os.exists(), os.get_env(), os.lookup_env(), os.set_env() exists() does the access() syscall. Renames getenv() to get_env() to match Windows. --- core/os/os_linux.odin | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 9b712cecc..e4ce37567 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -415,6 +415,7 @@ foreign libc { @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr --- @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- + @(link_name="putenv") _unix_putenv :: proc(cstring) -> c.int --- @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- @@ -579,6 +580,11 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_file :: proc {is_file_path, is_file_handle} is_dir :: proc {is_dir_path, is_dir_handle} +exists :: proc(path: string) -> bool { + cpath := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_access(cpath, O_RDONLY) + return res == 0 +} // NOTE(bill): Uses startup to initialize it @@ -764,13 +770,28 @@ heap_free :: proc(ptr: rawptr) { _unix_free(ptr) } -getenv :: proc(name: string) -> (string, bool) { - path_str := strings.clone_to_cstring(name, context.temp_allocator) +lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { + path_str := strings.clone_to_cstring(key, context.temp_allocator) + // NOTE(tetra): Lifetime of 'cstr' is unclear, but _unix_free(cstr) segfaults. cstr := _unix_getenv(path_str) if cstr == nil { return "", false } - return string(cstr), true + return strings.clone(string(cstr), allocator), true +} + +get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { + value, _ = lookup_env(key, allocator) + return +} + +set_env :: proc(key, value: string) -> Errno { + s := strings.concatenate({key, "=", value, "\x00"}, context.temp_allocator) + res := _unix_putenv(strings.unsafe_string_to_cstring(s)) + if res < 0 { + return Errno(get_last_error()) + } + return ERROR_NONE } get_current_directory :: proc() -> string { From 23cb96de022f91e1798f73b920f972845081b370 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 16:37:05 +0100 Subject: [PATCH 234/245] Commit `import _` changes --- src/checker.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index da9a97622..8afc6eb14 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4365,15 +4365,12 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { // import_name = scope->pkg->name; // } - if (import_name.len == 0 || is_blank_ident(import_name)) { - if (id->import_name.string == "") { - String invalid_name = id->fullpath; - invalid_name = get_invalid_import_name(invalid_name); + if (import_name.len == 0) { + String invalid_name = id->fullpath; + invalid_name = get_invalid_import_name(invalid_name); - error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import \"%.*s\" ", LIT(invalid_name), LIT(invalid_name)); - } else { - error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string)); - } + error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import \"%.*s\" ", LIT(invalid_name), LIT(invalid_name)); + error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string)); } else { GB_ASSERT(id->import_name.pos.line != 0); id->import_name.string = import_name; From be2c7b5c9b7db56c9e72a7b8ba6ba861999ee3be Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 21:53:16 +0100 Subject: [PATCH 235/245] Add numerous different random distribution procedures --- core/math/rand/rand.odin | 252 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 19e475835..7f81dc6b2 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -1,6 +1,7 @@ package rand import "core:intrinsics" +import "core:math" Rand :: struct { state: u64, @@ -119,11 +120,262 @@ int_max :: proc(n: int, r: ^Rand = nil) -> int { } } +// Uniform random distribution [0, 1) float64 :: proc(r: ^Rand = nil) -> f64 { return f64(int63_max(1<<53, r)) / (1 << 53) } +// Uniform random distribution [0, 1) float32 :: proc(r: ^Rand = nil) -> f32 { return f32(float64(r)) } float64_range :: proc(lo, hi: f64, r: ^Rand = nil) -> f64 { return (hi-lo)*float64(r) + lo } float32_range :: proc(lo, hi: f32, r: ^Rand = nil) -> f32 { return (hi-lo)*float32(r) + lo } +float64_uniform :: float64_range +float32_uniform :: float32_range + + +// Triangular Distribution +// See: http://wikipedia.org/wiki/Triangular_distribution +float64_trianglular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 { + if hi-lo == 0 { + return lo + } + lo, hi := lo, hi + u := float64(r) + c := f64(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) + if u > c { + u = 1-u + c = 1-c + lo, hi = hi, lo + } + return lo + (hi - lo) * math.sqrt(u * c) + +} +// Triangular Distribution +// See: http://wikipedia.org/wiki/Triangular_distribution +float32_trianglular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { + + if hi-lo == 0 { + return lo + } + lo, hi := lo, hi + u := float32(r) + c := f32(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) + if u > c { + u = 1-u + c = 1-c + lo, hi = hi, lo + } + return lo + (hi - lo) * math.sqrt(u * c) +} + + +// Normal/Gaussian Distribution +float64_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { + return norm_float64(r) * stddev + mean +} +// Normal/Gaussian Distribution +float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { + return f32(float64_normal(f64(mean), f64(stddev), r)) +} + + +// Log Normal Distribution +float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { + return math.ln(float64_normal(mean, stddev, r)) +} +// Log Normal Distribution +float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { + return f32(float64_log_normal(f64(mean), f64(stddev), r)) +} + + +// Exponential Distribution +// `lambda` is 1.0/(desired mean). It should be non-zero. +// Return values range from +// 0 to positive infinity if lambda > 0 +// negative infinity to 0 if lambda <= 0 +float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 { + return - math.ln(1 - float64(r)) / lambda +} +// Exponential Distribution +// `lambda` is 1.0/(desired mean). It should be non-zero. +// Return values range from +// 0 to positive infinity if lambda > 0 +// negative infinity to 0 if lambda <= 0 +float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 { + return f32(float64_exponential(f64(lambda), r)) +} + + +// Gamma Distribution (NOT THE GAMMA FUNCTION) +// +// Required: alpha > 0 and beta > 0 +// +// math.pow(x, alpha-1) * math.exp(-x / beta) +// pdf(x) = -------------------------------------------- +// math.gamma(alpha) * math.pow(beta, alpha) +// +// mean is alpha*beta, variance is math.pow(alpha*beta, 2) +float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + if alpha <= 0 || beta <= 0 { + panic(#procedure + ": alpha and beta must be > 0.0") + } + + LOG4 :: 1.3862943611198906188344642429163531361510002687205105082413600189 + SG_MAGIC_CONST :: 2.5040773967762740733732583523868748412194809812852436493487 + + switch { + case alpha > 1: + // R.C.H. Cheng, "The generation of Gamma variables with non-integral shape parameters", Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv := math.sqrt(2 * alpha - 1) + bbb := alpha - LOG4 + ccc := alpha + ainv + for { + u1 := float64(r) + if !(1e-7 < u1 && u1 < 0.9999999) { + continue + } + u2 := 1 - float64(r) + v := math.ln(u1 / (1 - u1)) / ainv + x := alpha * math.exp(v) + z := u1 * u1 * u2 + t := bbb + ccc*v - x + if t + SG_MAGIC_CONST - 4.5 * z >= 0 || t >= math.ln(z) { + return x * beta + } + } + case alpha == 1: + // float64_exponential(1/beta) + return -math.ln(1 - float64(r)) * beta + case: + // ALGORITHM GS of Statistical Computing - Kennedy & Gentle + x: f64 + for { + u := float64(r) + b := (math.e + alpha) / math.e + p := b * u + if p <= 1 { + x = math.pow(p, 1/alpha) + } else { + x = -math.ln((b - p) / alpha) + } + u1 := float64(r) + if p > 1 { + if u1 <= math.pow(x, alpha-1) { + break + } + } else if u1 <= math.exp(-x) { + break + } + } + return x * beta + } +} +// Gamma Distribution (NOT THE GAMMA FUNCTION) +// +// Required: alpha > 0 and beta > 0 +// +// math.pow(x, alpha-1) * math.exp(-x / beta) +// pdf(x) = -------------------------------------------- +// math.gamma(alpha) * math.pow(beta, alpha) +// +// mean is alpha*beta, variance is math.pow(alpha*beta, 2) +float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_gamma(f64(alpha), f64(beta), r)) +} + + +// Beta Distribution +// +// Required: alpha > 0 and beta > 0 +// +// Return values range between 0 and 1 +float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + if alpha <= 0 || beta <= 0 { + panic(#procedure + ": alpha and beta must be > 0.0") + } + // Knuth Vol 2 Ed 3 pg 134 "the beta distribution" + y := float64_gamma(alpha, 1.0, r) + if y != 0 { + return y / (y + float64_gamma(beta, 1.0, r)) + } + return 0 +} +// Beta Distribution +// +// Required: alpha > 0 and beta > 0 +// +// Return values range between 0 and 1 +float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_beta(f64(alpha), f64(beta), r)) +} + + +// Pareto distribution, `alpha` is the shape parameter. +// https://wikipedia.org/wiki/Pareto_distribution +float64_pareto :: proc(alpha: f64, r: ^Rand = nil) -> f64 { + return math.pow(1 - float64(r), -1.0 / alpha) +} +// Pareto distribution, `alpha` is the shape parameter. +// https://wikipedia.org/wiki/Pareto_distribution +float32_pareto :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_pareto(f64(alpha), r)) +} + + +// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. +float64_weibull :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + u := 1 - float64(r) + return alpha * math.pow(-math.ln(u), 1.0/beta) +} +// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. +float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_weibull(f64(alpha), f64(beta), r)) +} + + +// Circular Data (von Mises) Distribution +// `mean_angle` is the in mean angle between 0 and 2pi radians +// `kappa` is the concentration parameter which must be >= 0 +// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi +float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 { + // Fisher, N.I., "Statistical Analysis of Circular Data", Cambridge University Press, 1993. + + mu := mean_angle + if kappa <= 1e-6 { + return math.TAU * float64(r) + } + + s := 0.5 / kappa + t := s + math.sqrt(1 + s*s) + z: f64 + for { + u1 := float64(r) + z = math.cos(math.TAU * 0.5 * u1) + + d := z / (t + z) + u2 := float64(r) + if u2 < 1 - d*d || u2 <= (1-d)*math.exp(d) { + break + } + } + + q := 1.0 / t + f := (q + z) / (1 + q*z) + u3 := float64(r) + if u3 > 0.5 { + return math.mod(mu + math.acos(f), math.TAU) + } else { + return math.mod(mu - math.acos(f), math.TAU) + } +} +// Circular Data (von Mises) Distribution +// `mean_angle` is the in mean angle between 0 and 2pi radians +// `kappa` is the concentration parameter which must be >= 0 +// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi +float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 { + return f32(float64_von_mises(f64(mean_angle), f64(kappa), r)) +} + read :: proc(p: []byte, r: ^Rand = nil) -> (n: int) { From 6c6de2a07d23079acd134ee3fe421784173d72fe Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 22:20:25 +0100 Subject: [PATCH 236/245] Move distributions to a separate file --- core/math/rand/distributions.odin | 251 ++++++++++++++++++++++++++++++ core/math/rand/rand.odin | 251 ------------------------------ 2 files changed, 251 insertions(+), 251 deletions(-) create mode 100644 core/math/rand/distributions.odin diff --git a/core/math/rand/distributions.odin b/core/math/rand/distributions.odin new file mode 100644 index 000000000..6bfff64d8 --- /dev/null +++ b/core/math/rand/distributions.odin @@ -0,0 +1,251 @@ +package rand + +import "core:math" + +float64_uniform :: float64_range +float32_uniform :: float32_range + +// Triangular Distribution +// See: http://wikipedia.org/wiki/Triangular_distribution +float64_trianglular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 { + if hi-lo == 0 { + return lo + } + lo, hi := lo, hi + u := float64(r) + c := f64(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) + if u > c { + u = 1-u + c = 1-c + lo, hi = hi, lo + } + return lo + (hi - lo) * math.sqrt(u * c) + +} +// Triangular Distribution +// See: http://wikipedia.org/wiki/Triangular_distribution +float32_trianglular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { + + if hi-lo == 0 { + return lo + } + lo, hi := lo, hi + u := float32(r) + c := f32(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) + if u > c { + u = 1-u + c = 1-c + lo, hi = hi, lo + } + return lo + (hi - lo) * math.sqrt(u * c) +} + + +// Normal/Gaussian Distribution +float64_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { + return norm_float64(r) * stddev + mean +} +// Normal/Gaussian Distribution +float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { + return f32(float64_normal(f64(mean), f64(stddev), r)) +} + + +// Log Normal Distribution +float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { + return math.ln(float64_normal(mean, stddev, r)) +} +// Log Normal Distribution +float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { + return f32(float64_log_normal(f64(mean), f64(stddev), r)) +} + + +// Exponential Distribution +// `lambda` is 1.0/(desired mean). It should be non-zero. +// Return values range from +// 0 to positive infinity if lambda > 0 +// negative infinity to 0 if lambda <= 0 +float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 { + return - math.ln(1 - float64(r)) / lambda +} +// Exponential Distribution +// `lambda` is 1.0/(desired mean). It should be non-zero. +// Return values range from +// 0 to positive infinity if lambda > 0 +// negative infinity to 0 if lambda <= 0 +float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 { + return f32(float64_exponential(f64(lambda), r)) +} + + +// Gamma Distribution (NOT THE GAMMA FUNCTION) +// +// Required: alpha > 0 and beta > 0 +// +// math.pow(x, alpha-1) * math.exp(-x / beta) +// pdf(x) = -------------------------------------------- +// math.gamma(alpha) * math.pow(beta, alpha) +// +// mean is alpha*beta, variance is math.pow(alpha*beta, 2) +float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + if alpha <= 0 || beta <= 0 { + panic(#procedure + ": alpha and beta must be > 0.0") + } + + LOG4 :: 1.3862943611198906188344642429163531361510002687205105082413600189 + SG_MAGIC_CONST :: 2.5040773967762740733732583523868748412194809812852436493487 + + switch { + case alpha > 1: + // R.C.H. Cheng, "The generation of Gamma variables with non-integral shape parameters", Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv := math.sqrt(2 * alpha - 1) + bbb := alpha - LOG4 + ccc := alpha + ainv + for { + u1 := float64(r) + if !(1e-7 < u1 && u1 < 0.9999999) { + continue + } + u2 := 1 - float64(r) + v := math.ln(u1 / (1 - u1)) / ainv + x := alpha * math.exp(v) + z := u1 * u1 * u2 + t := bbb + ccc*v - x + if t + SG_MAGIC_CONST - 4.5 * z >= 0 || t >= math.ln(z) { + return x * beta + } + } + case alpha == 1: + // float64_exponential(1/beta) + return -math.ln(1 - float64(r)) * beta + case: + // ALGORITHM GS of Statistical Computing - Kennedy & Gentle + x: f64 + for { + u := float64(r) + b := (math.e + alpha) / math.e + p := b * u + if p <= 1 { + x = math.pow(p, 1/alpha) + } else { + x = -math.ln((b - p) / alpha) + } + u1 := float64(r) + if p > 1 { + if u1 <= math.pow(x, alpha-1) { + break + } + } else if u1 <= math.exp(-x) { + break + } + } + return x * beta + } +} +// Gamma Distribution (NOT THE GAMMA FUNCTION) +// +// Required: alpha > 0 and beta > 0 +// +// math.pow(x, alpha-1) * math.exp(-x / beta) +// pdf(x) = -------------------------------------------- +// math.gamma(alpha) * math.pow(beta, alpha) +// +// mean is alpha*beta, variance is math.pow(alpha*beta, 2) +float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_gamma(f64(alpha), f64(beta), r)) +} + + +// Beta Distribution +// +// Required: alpha > 0 and beta > 0 +// +// Return values range between 0 and 1 +float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + if alpha <= 0 || beta <= 0 { + panic(#procedure + ": alpha and beta must be > 0.0") + } + // Knuth Vol 2 Ed 3 pg 134 "the beta distribution" + y := float64_gamma(alpha, 1.0, r) + if y != 0 { + return y / (y + float64_gamma(beta, 1.0, r)) + } + return 0 +} +// Beta Distribution +// +// Required: alpha > 0 and beta > 0 +// +// Return values range between 0 and 1 +float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_beta(f64(alpha), f64(beta), r)) +} + + +// Pareto distribution, `alpha` is the shape parameter. +// https://wikipedia.org/wiki/Pareto_distribution +float64_pareto :: proc(alpha: f64, r: ^Rand = nil) -> f64 { + return math.pow(1 - float64(r), -1.0 / alpha) +} +// Pareto distribution, `alpha` is the shape parameter. +// https://wikipedia.org/wiki/Pareto_distribution +float32_pareto :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_pareto(f64(alpha), r)) +} + + +// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. +float64_weibull :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { + u := 1 - float64(r) + return alpha * math.pow(-math.ln(u), 1.0/beta) +} +// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. +float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { + return f32(float64_weibull(f64(alpha), f64(beta), r)) +} + + +// Circular Data (von Mises) Distribution +// `mean_angle` is the in mean angle between 0 and 2pi radians +// `kappa` is the concentration parameter which must be >= 0 +// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi +float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 { + // Fisher, N.I., "Statistical Analysis of Circular Data", Cambridge University Press, 1993. + + mu := mean_angle + if kappa <= 1e-6 { + return math.TAU * float64(r) + } + + s := 0.5 / kappa + t := s + math.sqrt(1 + s*s) + z: f64 + for { + u1 := float64(r) + z = math.cos(math.TAU * 0.5 * u1) + + d := z / (t + z) + u2 := float64(r) + if u2 < 1 - d*d || u2 <= (1-d)*math.exp(d) { + break + } + } + + q := 1.0 / t + f := (q + z) / (1 + q*z) + u3 := float64(r) + if u3 > 0.5 { + return math.mod(mu + math.acos(f), math.TAU) + } else { + return math.mod(mu - math.acos(f), math.TAU) + } +} +// Circular Data (von Mises) Distribution +// `mean_angle` is the in mean angle between 0 and 2pi radians +// `kappa` is the concentration parameter which must be >= 0 +// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi +float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 { + return f32(float64_von_mises(f64(mean_angle), f64(kappa), r)) +} diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 7f81dc6b2..80fd8de33 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -1,7 +1,6 @@ package rand import "core:intrinsics" -import "core:math" Rand :: struct { state: u64, @@ -127,256 +126,6 @@ float32 :: proc(r: ^Rand = nil) -> f32 { return f32(float64(r)) } float64_range :: proc(lo, hi: f64, r: ^Rand = nil) -> f64 { return (hi-lo)*float64(r) + lo } float32_range :: proc(lo, hi: f32, r: ^Rand = nil) -> f32 { return (hi-lo)*float32(r) + lo } -float64_uniform :: float64_range -float32_uniform :: float32_range - - -// Triangular Distribution -// See: http://wikipedia.org/wiki/Triangular_distribution -float64_trianglular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 { - if hi-lo == 0 { - return lo - } - lo, hi := lo, hi - u := float64(r) - c := f64(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) - if u > c { - u = 1-u - c = 1-c - lo, hi = hi, lo - } - return lo + (hi - lo) * math.sqrt(u * c) - -} -// Triangular Distribution -// See: http://wikipedia.org/wiki/Triangular_distribution -float32_trianglular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { - - if hi-lo == 0 { - return lo - } - lo, hi := lo, hi - u := float32(r) - c := f32(0.5) if mode == nil else clamp((mode.?-lo) / (hi-lo), 0, 1) - if u > c { - u = 1-u - c = 1-c - lo, hi = hi, lo - } - return lo + (hi - lo) * math.sqrt(u * c) -} - - -// Normal/Gaussian Distribution -float64_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { - return norm_float64(r) * stddev + mean -} -// Normal/Gaussian Distribution -float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { - return f32(float64_normal(f64(mean), f64(stddev), r)) -} - - -// Log Normal Distribution -float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { - return math.ln(float64_normal(mean, stddev, r)) -} -// Log Normal Distribution -float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { - return f32(float64_log_normal(f64(mean), f64(stddev), r)) -} - - -// Exponential Distribution -// `lambda` is 1.0/(desired mean). It should be non-zero. -// Return values range from -// 0 to positive infinity if lambda > 0 -// negative infinity to 0 if lambda <= 0 -float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 { - return - math.ln(1 - float64(r)) / lambda -} -// Exponential Distribution -// `lambda` is 1.0/(desired mean). It should be non-zero. -// Return values range from -// 0 to positive infinity if lambda > 0 -// negative infinity to 0 if lambda <= 0 -float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 { - return f32(float64_exponential(f64(lambda), r)) -} - - -// Gamma Distribution (NOT THE GAMMA FUNCTION) -// -// Required: alpha > 0 and beta > 0 -// -// math.pow(x, alpha-1) * math.exp(-x / beta) -// pdf(x) = -------------------------------------------- -// math.gamma(alpha) * math.pow(beta, alpha) -// -// mean is alpha*beta, variance is math.pow(alpha*beta, 2) -float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { - if alpha <= 0 || beta <= 0 { - panic(#procedure + ": alpha and beta must be > 0.0") - } - - LOG4 :: 1.3862943611198906188344642429163531361510002687205105082413600189 - SG_MAGIC_CONST :: 2.5040773967762740733732583523868748412194809812852436493487 - - switch { - case alpha > 1: - // R.C.H. Cheng, "The generation of Gamma variables with non-integral shape parameters", Applied Statistics, (1977), 26, No. 1, p71-74 - - ainv := math.sqrt(2 * alpha - 1) - bbb := alpha - LOG4 - ccc := alpha + ainv - for { - u1 := float64(r) - if !(1e-7 < u1 && u1 < 0.9999999) { - continue - } - u2 := 1 - float64(r) - v := math.ln(u1 / (1 - u1)) / ainv - x := alpha * math.exp(v) - z := u1 * u1 * u2 - t := bbb + ccc*v - x - if t + SG_MAGIC_CONST - 4.5 * z >= 0 || t >= math.ln(z) { - return x * beta - } - } - case alpha == 1: - // float64_exponential(1/beta) - return -math.ln(1 - float64(r)) * beta - case: - // ALGORITHM GS of Statistical Computing - Kennedy & Gentle - x: f64 - for { - u := float64(r) - b := (math.e + alpha) / math.e - p := b * u - if p <= 1 { - x = math.pow(p, 1/alpha) - } else { - x = -math.ln((b - p) / alpha) - } - u1 := float64(r) - if p > 1 { - if u1 <= math.pow(x, alpha-1) { - break - } - } else if u1 <= math.exp(-x) { - break - } - } - return x * beta - } -} -// Gamma Distribution (NOT THE GAMMA FUNCTION) -// -// Required: alpha > 0 and beta > 0 -// -// math.pow(x, alpha-1) * math.exp(-x / beta) -// pdf(x) = -------------------------------------------- -// math.gamma(alpha) * math.pow(beta, alpha) -// -// mean is alpha*beta, variance is math.pow(alpha*beta, 2) -float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { - return f32(float64_gamma(f64(alpha), f64(beta), r)) -} - - -// Beta Distribution -// -// Required: alpha > 0 and beta > 0 -// -// Return values range between 0 and 1 -float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { - if alpha <= 0 || beta <= 0 { - panic(#procedure + ": alpha and beta must be > 0.0") - } - // Knuth Vol 2 Ed 3 pg 134 "the beta distribution" - y := float64_gamma(alpha, 1.0, r) - if y != 0 { - return y / (y + float64_gamma(beta, 1.0, r)) - } - return 0 -} -// Beta Distribution -// -// Required: alpha > 0 and beta > 0 -// -// Return values range between 0 and 1 -float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { - return f32(float64_beta(f64(alpha), f64(beta), r)) -} - - -// Pareto distribution, `alpha` is the shape parameter. -// https://wikipedia.org/wiki/Pareto_distribution -float64_pareto :: proc(alpha: f64, r: ^Rand = nil) -> f64 { - return math.pow(1 - float64(r), -1.0 / alpha) -} -// Pareto distribution, `alpha` is the shape parameter. -// https://wikipedia.org/wiki/Pareto_distribution -float32_pareto :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { - return f32(float64_pareto(f64(alpha), r)) -} - - -// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. -float64_weibull :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 { - u := 1 - float64(r) - return alpha * math.pow(-math.ln(u), 1.0/beta) -} -// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter. -float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 { - return f32(float64_weibull(f64(alpha), f64(beta), r)) -} - - -// Circular Data (von Mises) Distribution -// `mean_angle` is the in mean angle between 0 and 2pi radians -// `kappa` is the concentration parameter which must be >= 0 -// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi -float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 { - // Fisher, N.I., "Statistical Analysis of Circular Data", Cambridge University Press, 1993. - - mu := mean_angle - if kappa <= 1e-6 { - return math.TAU * float64(r) - } - - s := 0.5 / kappa - t := s + math.sqrt(1 + s*s) - z: f64 - for { - u1 := float64(r) - z = math.cos(math.TAU * 0.5 * u1) - - d := z / (t + z) - u2 := float64(r) - if u2 < 1 - d*d || u2 <= (1-d)*math.exp(d) { - break - } - } - - q := 1.0 / t - f := (q + z) / (1 + q*z) - u3 := float64(r) - if u3 > 0.5 { - return math.mod(mu + math.acos(f), math.TAU) - } else { - return math.mod(mu - math.acos(f), math.TAU) - } -} -// Circular Data (von Mises) Distribution -// `mean_angle` is the in mean angle between 0 and 2pi radians -// `kappa` is the concentration parameter which must be >= 0 -// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi -float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 { - return f32(float64_von_mises(f64(mean_angle), f64(kappa), r)) -} - - read :: proc(p: []byte, r: ^Rand = nil) -> (n: int) { pos := i8(0) From 50ddd8dd2649ddbe14d587d6fea4e724842cd92c Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 22:45:05 +0100 Subject: [PATCH 237/245] Fix typo --- core/math/rand/distributions.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/math/rand/distributions.odin b/core/math/rand/distributions.odin index 6bfff64d8..05ab084a3 100644 --- a/core/math/rand/distributions.odin +++ b/core/math/rand/distributions.odin @@ -7,7 +7,7 @@ float32_uniform :: float32_range // Triangular Distribution // See: http://wikipedia.org/wiki/Triangular_distribution -float64_trianglular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 { +float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 { if hi-lo == 0 { return lo } @@ -24,7 +24,7 @@ float64_trianglular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f6 } // Triangular Distribution // See: http://wikipedia.org/wiki/Triangular_distribution -float32_trianglular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { +float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { if hi-lo == 0 { return lo From 500150b12a05a1c757414724d285cdea8f925bda Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 22:52:11 +0100 Subject: [PATCH 238/245] Correct log normal --- core/math/rand/distributions.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/math/rand/distributions.odin b/core/math/rand/distributions.odin index 05ab084a3..9e38f6517 100644 --- a/core/math/rand/distributions.odin +++ b/core/math/rand/distributions.odin @@ -53,7 +53,7 @@ float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { // Log Normal Distribution float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 { - return math.ln(float64_normal(mean, stddev, r)) + return math.exp(float64_normal(mean, stddev, r)) } // Log Normal Distribution float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 { From 5142955f00fb22cd3b7b69b2836b85867a5c69a2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 22:58:39 +0100 Subject: [PATCH 239/245] Add more distributions --- core/math/rand/distributions.odin | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/core/math/rand/distributions.odin b/core/math/rand/distributions.odin index 9e38f6517..a42893bf4 100644 --- a/core/math/rand/distributions.odin +++ b/core/math/rand/distributions.odin @@ -249,3 +249,44 @@ float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 { float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 { return f32(float64_von_mises(f64(mean_angle), f64(kappa), r)) } + + +// Cauchy-Lorentz Distribution +// `x_0` is the location, `gamma` is the scale where `gamma` > 0 +float64_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 { + assert(gamma > 0) + + // Calculated from the inverse CDF + + return math.tan(math.PI * (float64(r) - 0.5))*gamma + x_0 +} +// Cauchy-Lorentz Distribution +// `x_0` is the location, `gamma` is the scale where `gamma` > 0 +float32_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 { + return f32(float64_cauchy_lorentz(f64(x_0), f64(gamma), r)) +} + + +// Log Cauchy-Lorentz Distribution +// `x_0` is the location, `gamma` is the scale where `gamma` > 0 +float64_log_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 { + assert(gamma > 0) + return math.exp(math.tan(math.PI * (float64(r) - 0.5))*gamma + x_0) +} +// Log Cauchy-Lorentz Distribution +// `x_0` is the location, `gamma` is the scale where `gamma` > 0 +float32_log_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 { + return f32(float64_log_cauchy_lorentz(f64(x_0), f64(gamma), r)) +} + + +// Laplace Distribution +// `b` is the scale where `b` > 0 +float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 { + assert(b > 0) + p := float64(r)-0.5 + return -math.sign(p)*math.ln(1 - 2*abs(p))*b + mean +} +float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 { + return f32(float64_laplace(f64(mean), f64(b), r)) +} \ No newline at end of file From fdcf08410cc7b43bfe69b7ded7d030d95d24284f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 23:03:01 +0100 Subject: [PATCH 240/245] Add Gompertz Distribution --- core/math/rand/distributions.odin | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/core/math/rand/distributions.odin b/core/math/rand/distributions.odin index a42893bf4..ada89afad 100644 --- a/core/math/rand/distributions.odin +++ b/core/math/rand/distributions.odin @@ -25,7 +25,6 @@ float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 // Triangular Distribution // See: http://wikipedia.org/wiki/Triangular_distribution float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 { - if hi-lo == 0 { return lo } @@ -287,6 +286,27 @@ float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 { p := float64(r)-0.5 return -math.sign(p)*math.ln(1 - 2*abs(p))*b + mean } +// Laplace Distribution +// `b` is the scale where `b` > 0 float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 { return f32(float64_laplace(f64(mean), f64(b), r)) -} \ No newline at end of file +} + + +// Gompertz Distribution +// `eta` is the shape, `b` is the scale +// Both `eta` and `b` must be > 0 +float64_gompertz :: proc(eta, b: f64, r: ^Rand = nil) -> f64 { + if eta <= 0 || b <= 0 { + panic(#procedure + ": eta and b must be > 0.0") + } + + p := float64(r) + return math.ln(1 - math.ln(1 - p)/eta)/b +} +// Gompertz Distribution +// `eta` is the shape, `b` is the scale +// Both `eta` and `b` must be > 0 +float32_gompertz :: proc(eta, b: f32, r: ^Rand = nil) -> f32 { + return f32(float64_gompertz(f64(eta), f64(b), r)) +} From 2a58bceb5674c9af75dd217a7891869b4316f2f9 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 23:43:20 +0100 Subject: [PATCH 241/245] Add `rand.init_as_system` to allow for system-level based random number generation --- core/math/rand/rand.odin | 17 +++++++++++++++++ core/math/rand/system_linux.odin | 27 +++++++++++++++++++++++++++ core/math/rand/system_windows.odin | 12 ++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 core/math/rand/system_linux.odin create mode 100644 core/math/rand/system_windows.odin diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 80fd8de33..f7dfcb3b8 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -5,6 +5,7 @@ import "core:intrinsics" Rand :: struct { state: u64, inc: u64, + is_system: bool, } @@ -29,6 +30,16 @@ init :: proc(r: ^Rand, seed: u64) { _random(r) } +init_as_system :: proc(r: ^Rand) { + if !#defined(_system_random) { + panic(#procedure + " is not supported on this platform yet") + } + r.state = 0 + r.inc = 0 + r.is_system = true +} + +@(private) _random :: proc(r: ^Rand) -> u32 { r := r if r == nil { @@ -36,6 +47,12 @@ _random :: proc(r: ^Rand) -> u32 { // enforce the global random state if necessary with `nil` r = &global_rand } + when #defined(_system_random) { + if r.is_system { + return _system_random() + } + } + old_state := r.state r.state = old_state * 6364136223846793005 + (r.inc|1) xor_shifted := u32(((old_state>>18) ~ old_state) >> 27) diff --git a/core/math/rand/system_linux.odin b/core/math/rand/system_linux.odin new file mode 100644 index 000000000..bfdc8872b --- /dev/null +++ b/core/math/rand/system_linux.odin @@ -0,0 +1,27 @@ +package rand + +import "core:sys/unix" + +_system_random :: proc() -> u32 { + for { + value: u32 + ret := unix.sys_getrandom(([^]u8)(&value), 4, 0) + if ret < 0 { + switch ret { + case -4: // EINTR + // Call interupted by a signal handler, just retry the request. + continue + case -38: // ENOSYS + // The kernel is apparently prehistoric (< 3.17 circa 2014) + // and does not support getrandom. + panic("getrandom not available in kernel") + case: + // All other failures are things that should NEVER happen + // unless the kernel interface changes (ie: the Linux + // developers break userland). + panic("getrandom failed") + } + } + return value + } +} \ No newline at end of file diff --git a/core/math/rand/system_windows.odin b/core/math/rand/system_windows.odin new file mode 100644 index 000000000..ee9cd0294 --- /dev/null +++ b/core/math/rand/system_windows.odin @@ -0,0 +1,12 @@ +package rand + +import win32 "core:sys/windows" + +_system_random :: proc() -> u32 { + value: u32 + status := win32.BCryptGenRandom(nil, ([^]u8)(&value), 4, win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG) + if status < 0 { + panic("BCryptGenRandom failed") + } + return value +} \ No newline at end of file From 4eba2bb8d9f4f4ec246d268ee382788062cfff16 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 23:46:32 +0100 Subject: [PATCH 242/245] Add `_system_random` for Darwin --- core/math/rand/system_darwin.odin | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 core/math/rand/system_darwin.odin diff --git a/core/math/rand/system_darwin.odin b/core/math/rand/system_darwin.odin new file mode 100644 index 000000000..f51e4473e --- /dev/null +++ b/core/math/rand/system_darwin.odin @@ -0,0 +1,21 @@ +package rand + +import "core:sys/darwin" + +_system_random :: proc() -> u32 { + for { + value: u32 + ret := darwin.syscall_getentropy(([^]u8)(&value), 4) + if ret < 0 { + switch ret { + case -4: // EINTR + continue + case -78: // ENOSYS + panic("getentropy not available in kernel") + case: + panic("getentropy failed") + } + } + return value + } +} \ No newline at end of file From 5451c9672d16f7a1db26d6c47e9e44b970f1e2c8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 23:48:11 +0100 Subject: [PATCH 243/245] Fix `dynamic_pool_destroy` --- core/mem/allocators.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 118a7f7e6..235391bcd 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -662,6 +662,7 @@ dynamic_pool_destroy :: proc(using pool: ^Dynamic_Pool) { dynamic_pool_free_all(pool) delete(unused_blocks) delete(used_blocks) + delete(out_band_allocations) zero(pool, size_of(pool^)) } From e10105a780d98c31faf4f2bce60a2a9dfabec7ab Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 May 2022 23:50:51 +0100 Subject: [PATCH 244/245] Correct logic for tracking allocator proc for freeing a nil pointer --- core/mem/allocators.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 235391bcd..d006e4574 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -858,7 +858,7 @@ tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, result: []byte err: Allocator_Error - if mode == .Free && old_memory not_in data.allocation_map { + if mode == .Free && old_memory != nil && old_memory not_in data.allocation_map { append(&data.bad_free_array, Tracking_Allocator_Bad_Free_Entry{ memory = old_memory, location = loc, From 33895b6d927c70167f3bfa64c6cc1c15c4e428c5 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 16 May 2022 01:43:43 +0100 Subject: [PATCH 245/245] Convert all uses of `*_from_slice` to `*_from_bytes` where appropriate --- core/bytes/bytes.odin | 3 ++- core/fmt/fmt.odin | 6 +++--- core/log/file_console_logger.odin | 2 +- core/os/os2/file.odin | 21 +++++++++++-------- core/strings/builder.odin | 5 +++-- core/sys/darwin/xnu_system_call_wrappers.odin | 2 +- core/sys/unix/syscalls_linux.odin | 2 +- core/sys/windows/bcrypt.odin | 2 +- core/text/i18n/gettext.odin | 6 +++--- core/text/i18n/qt_linguist.odin | 6 +++--- vendor/microui/microui.odin | 2 +- 11 files changed, 31 insertions(+), 26 deletions(-) diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index 66fd20829..f1737f3c5 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -16,7 +16,8 @@ clone_safe :: proc(s: []byte, allocator := context.allocator, loc := #caller_loc return c[:len(s)], nil } -ptr_from_slice :: proc(str: []byte) -> ^byte { +ptr_from_slice :: ptr_from_bytes +ptr_from_bytes :: proc(str: []byte) -> ^byte { d := transmute(mem.Raw_String)str return d.data } diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index d006d0ef8..4f78cfcce 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -119,17 +119,17 @@ tprintf :: proc(fmt: string, args: ..any) -> string { // bprint procedures return a string using a buffer from an array bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string { - sb := strings.builder_from_slice(buf[0:len(buf)]) + sb := strings.builder_from_bytes(buf[0:len(buf)]) return sbprint(buf=&sb, args=args, sep=sep) } // bprintln procedures return a string using a buffer from an array bprintln :: proc(buf: []byte, args: ..any, sep := " ") -> string { - sb := strings.builder_from_slice(buf[0:len(buf)]) + sb := strings.builder_from_bytes(buf[0:len(buf)]) return sbprintln(buf=&sb, args=args, sep=sep) } // bprintf procedures return a string using a buffer from an array bprintf :: proc(buf: []byte, fmt: string, args: ..any) -> string { - sb := strings.builder_from_slice(buf[0:len(buf)]) + sb := strings.builder_from_bytes(buf[0:len(buf)]) return sbprintf(&sb, fmt, ..args) } diff --git a/core/log/file_console_logger.odin b/core/log/file_console_logger.odin index cc019617f..7f0d3b07a 100644 --- a/core/log/file_console_logger.odin +++ b/core/log/file_console_logger.odin @@ -67,7 +67,7 @@ file_console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string h = data.file_handle } backing: [1024]byte //NOTE(Hoej): 1024 might be too much for a header backing, unless somebody has really long paths. - buf := strings.builder_from_slice(backing[:]) + buf := strings.builder_from_bytes(backing[:]) do_level_header(options, level, &buf) diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 4b271b9ea..eb6d9e366 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -34,17 +34,20 @@ File_Flag :: enum { Trunc, Sparse, Close_On_Exec, + + Unbuffered_IO, } -O_RDONLY :: File_Flags{.Read} -O_WRONLY :: File_Flags{.Write} -O_RDWR :: File_Flags{.Read, .Write} -O_APPEND :: File_Flags{.Append} -O_CREATE :: File_Flags{.Create} -O_EXCL :: File_Flags{.Excl} -O_SYNC :: File_Flags{.Sync} -O_TRUNC :: File_Flags{.Trunc} -O_SPARSE :: File_Flags{.Sparse} +O_RDONLY :: File_Flags{.Read} +O_WRONLY :: File_Flags{.Write} +O_RDWR :: File_Flags{.Read, .Write} +O_APPEND :: File_Flags{.Append} +O_CREATE :: File_Flags{.Create} +O_EXCL :: File_Flags{.Excl} +O_SYNC :: File_Flags{.Sync} +O_TRUNC :: File_Flags{.Trunc} +O_SPARSE :: File_Flags{.Sparse} +O_CLOEXEC :: File_Flags{.Close_On_Exec} diff --git a/core/strings/builder.odin b/core/strings/builder.odin index d6065cf70..d51e21827 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -124,11 +124,11 @@ reset_builder :: proc(b: ^Builder) { used in `fmt.bprint*` bytes: [8]byte // <-- gets filled - builder := strings.builder_from_slice(bytes[:]) + builder := strings.builder_from_bytes(bytes[:]) strings.write_byte(&builder, 'a') -> "a" strings.write_byte(&builder, 'b') -> "ab" */ -builder_from_slice :: proc(backing: []byte) -> Builder { +builder_from_bytes :: proc(backing: []byte) -> Builder { s := transmute(mem.Raw_Slice)backing d := mem.Raw_Dynamic_Array{ data = s.data, @@ -140,6 +140,7 @@ builder_from_slice :: proc(backing: []byte) -> Builder { buf = transmute([dynamic]byte)d, } } +builder_from_slice :: builder_from_bytes // cast the builder byte buffer to a string and return it to_string :: proc(b: Builder) -> string { diff --git a/core/sys/darwin/xnu_system_call_wrappers.odin b/core/sys/darwin/xnu_system_call_wrappers.odin index 4e4227f1f..685f75ffa 100644 --- a/core/sys/darwin/xnu_system_call_wrappers.odin +++ b/core/sys/darwin/xnu_system_call_wrappers.odin @@ -402,7 +402,7 @@ syscall_openat :: #force_inline proc(fd: int, path: cstring, oflag: u32, mode: u return cast(c.int)intrinsics.syscall(unix_offset_syscall(.openat), uintptr(fd), transmute(uintptr)path, uintptr(oflag), uintptr(mode)) } -syscall_getentropy :: #force_inline proc(buf: ^u8, buflen: u64) -> c.int { +syscall_getentropy :: #force_inline proc(buf: [^]u8, buflen: u64) -> c.int { return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getentropy), uintptr(buf), uintptr(buflen)) } diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index f50ae825b..7300193df 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -1522,6 +1522,6 @@ sys_gettid :: proc "contextless" () -> int { return cast(int)intrinsics.syscall(SYS_gettid) } -sys_getrandom :: proc "contextless" (buf: ^byte, buflen: int, flags: uint) -> int { +sys_getrandom :: proc "contextless" (buf: [^]byte, buflen: int, flags: uint) -> int { return cast(int)intrinsics.syscall(SYS_getrandom, buf, cast(uintptr)(buflen), cast(uintptr)(flags)) } diff --git a/core/sys/windows/bcrypt.odin b/core/sys/windows/bcrypt.odin index ed28d5b7f..52eb4b1b6 100644 --- a/core/sys/windows/bcrypt.odin +++ b/core/sys/windows/bcrypt.odin @@ -7,5 +7,5 @@ BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD : 0x00000002 @(default_calling_convention="stdcall") foreign bcrypt { - BCryptGenRandom :: proc(hAlgorithm: LPVOID, pBuffer: ^u8, cbBuffer: ULONG, dwFlags: ULONG) -> LONG --- + BCryptGenRandom :: proc(hAlgorithm: LPVOID, pBuffer: [^]u8, cbBuffer: ULONG, dwFlags: ULONG) -> LONG --- } diff --git a/core/text/i18n/gettext.odin b/core/text/i18n/gettext.odin index eed73855b..d99ec1c9b 100644 --- a/core/text/i18n/gettext.odin +++ b/core/text/i18n/gettext.odin @@ -18,7 +18,7 @@ import "core:os" import "core:strings" import "core:bytes" -parse_mo_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_mo_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator /* An MO file should have at least a 4-byte magic, 2 x 2 byte version info, @@ -126,10 +126,10 @@ parse_mo_file :: proc(filename: string, options := DEFAULT_PARSE_OPTIONS, plural if !data_ok { return {}, .File_Error } - return parse_mo_from_slice(data, options, pluralizer, allocator) + return parse_mo_from_bytes(data, options, pluralizer, allocator) } -parse_mo :: proc { parse_mo_file, parse_mo_from_slice } +parse_mo :: proc { parse_mo_file, parse_mo_from_bytes } /* Helpers. diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin index 15a88a42f..036a89eeb 100644 --- a/core/text/i18n/qt_linguist.odin +++ b/core/text/i18n/qt_linguist.odin @@ -27,7 +27,7 @@ TS_XML_Options := xml.Options{ expected_doctype = "TS", } -parse_qt_linguist_from_slice :: proc(data: []u8, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { +parse_qt_linguist_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, pluralizer: proc(int) -> int = nil, allocator := context.allocator) -> (translation: ^Translation, err: Error) { context.allocator = allocator ts, xml_err := xml.parse(data, TS_XML_Options) @@ -150,7 +150,7 @@ parse_qt_linguist_file :: proc(filename: string, options := DEFAULT_PARSE_OPTION if !data_ok { return {}, .File_Error } - return parse_qt_linguist_from_slice(data, options, pluralizer, allocator) + return parse_qt_linguist_from_bytes(data, options, pluralizer, allocator) } -parse_qt :: proc { parse_qt_linguist_file, parse_qt_linguist_from_slice } \ No newline at end of file +parse_qt :: proc { parse_qt_linguist_file, parse_qt_linguist_from_bytes } \ No newline at end of file diff --git a/vendor/microui/microui.odin b/vendor/microui/microui.odin index 947f59f40..09a6b8430 100644 --- a/vendor/microui/microui.odin +++ b/vendor/microui/microui.odin @@ -309,7 +309,7 @@ init :: proc(ctx: ^Context) { ctx.draw_frame = default_draw_frame ctx._style = default_style ctx.style = &ctx._style - ctx.text_input = strings.builder_from_slice(ctx._text_store[:]) + ctx.text_input = strings.builder_from_bytes(ctx._text_store[:]) } begin :: proc(ctx: ^Context) {

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%0DJR!j^W4EdXw80?)r9R1u~K?>qsTzy9G>jUym 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

+ Odin logo +
+ The Data-Oriented Language for Sane Software Development. +
+
+
+ + + + + +
+ + + + + + +