diff --git a/.gitignore b/.gitignore index bb782b7..31284c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -*target* +target/ *.pem gurty.toml -certs \ No newline at end of file +certs +search_indexes +config.toml \ No newline at end of file diff --git a/dns/frontend/dashboard.lua b/dns/frontend/dashboard.lua index 43093e3..c6feba5 100644 --- a/dns/frontend/dashboard.lua +++ b/dns/frontend/dashboard.lua @@ -74,7 +74,7 @@ end local function loadDomains() print('Loading domains...') - local response = fetch('gurt://localhost:8877/auth/domains?page=1&size=100', { + local response = fetch('gurt://localhost:8877/auth/domains?page=1&limit=100', { headers = { Authorization = 'Bearer ' .. authToken } diff --git a/dns/frontend/domain.lua b/dns/frontend/domain.lua index 986cc9a..ab73ced 100644 --- a/dns/frontend/domain.lua +++ b/dns/frontend/domain.lua @@ -325,7 +325,7 @@ gurt.select('#add-record-btn'):on('click', function() local recordType = gurt.select('#record-type').value local recordName = gurt.select('#record-name').value local recordValue = gurt.select('#record-value').value - local recordTTL = tonumber(gurt.select('#record-ttl').value) or '' + local recordTTL = tonumber(gurt.select('#record-ttl').value) or 'none' if not recordValue or recordValue == '' then showError('record-error', 'Record value is required') diff --git a/dns/frontend/index.html b/dns/frontend/index.html index 3de60b0..c8f6168 100644 --- a/dns/frontend/index.html +++ b/dns/frontend/index.html @@ -20,7 +20,7 @@ } input { - w-full p-3 border border-gray-600 rounded-md bg-[#374151] text-white mb-4 placeholder:text-[#999999] outline-none active:border-red-500 + text-xs w-full p-3 border border-gray-600 rounded-md bg-[#374151] text-white mb-4 placeholder:text-[#999999] outline-none active:border-red-500 } button { @@ -51,4 +51,4 @@

- \ No newline at end of file + diff --git a/dns/frontend/register.lua b/dns/frontend/register.lua index 29c2f01..7206d1d 100644 --- a/dns/frontend/register.lua +++ b/dns/frontend/register.lua @@ -39,9 +39,9 @@ local function renderTLDSelector() local total = #tlds local intervalId - intervalId = gurt.setInterval(function() + intervalId = setInterval(function() if i > total then - gurt.clearInterval(intervalId) + clearInterval(intervalId) return end diff --git a/dns/migrations/010_add_search_crawl_status.sql b/dns/migrations/010_add_search_crawl_status.sql new file mode 100644 index 0000000..6605012 --- /dev/null +++ b/dns/migrations/010_add_search_crawl_status.sql @@ -0,0 +1,28 @@ +-- Search engine domain crawl status tracking +CREATE TABLE IF NOT EXISTS domain_crawl_status ( + domain_id INTEGER PRIMARY KEY REFERENCES domains(id) ON DELETE CASCADE, + last_crawled_at TIMESTAMPTZ, + next_crawl_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + crawl_status VARCHAR(20) DEFAULT 'pending' CHECK (crawl_status IN ('pending', 'crawling', 'completed', 'failed', 'disabled')), + error_message TEXT, + pages_found INTEGER DEFAULT 0, + updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX IF NOT EXISTS idx_domain_crawl_status_next_crawl ON domain_crawl_status(next_crawl_at); +CREATE INDEX IF NOT EXISTS idx_domain_crawl_status_status ON domain_crawl_status(crawl_status); + +-- Function to update the updated_at column +CREATE OR REPLACE FUNCTION update_updated_at_column() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_at = CURRENT_TIMESTAMP; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +-- Trigger for updated_at +DROP TRIGGER IF EXISTS update_domain_crawl_status_updated_at ON domain_crawl_status; +CREATE TRIGGER update_domain_crawl_status_updated_at + BEFORE UPDATE ON domain_crawl_status + FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); \ No newline at end of file diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 01eab1a..819c93b 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -141,7 +141,7 @@ const config: Config = { prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, - additionalLanguages: ['lua', 'bash', 'http'], + additionalLanguages: ['lua', 'bash', 'http', "toml"], }, } satisfies Preset.ThemeConfig, }; diff --git a/docs/sidebars.ts b/docs/sidebars.ts index 0e5a52c..e73decf 100644 --- a/docs/sidebars.ts +++ b/docs/sidebars.ts @@ -31,6 +31,7 @@ const sidebars: SidebarsConfig = { items: [ 'dns-system', 'flumi-browser', + 'search-engine' ], }, { diff --git a/flumi/Scenes/Tags/img.tscn b/flumi/Scenes/Tags/img.tscn index 7092cb6..a88b238 100644 --- a/flumi/Scenes/Tags/img.tscn +++ b/flumi/Scenes/Tags/img.tscn @@ -5,6 +5,6 @@ [node name="TextureRect" type="TextureRect"] size_flags_horizontal = 0 size_flags_vertical = 0 -expand_mode = 1 +expand_mode = 2 stretch_mode = 2 script = ExtResource("1_clm6l") diff --git a/flumi/Scripts/AutoSizingFlexContainer.gd b/flumi/Scripts/AutoSizingFlexContainer.gd index eb396af..75b629b 100644 --- a/flumi/Scripts/AutoSizingFlexContainer.gd +++ b/flumi/Scripts/AutoSizingFlexContainer.gd @@ -12,8 +12,11 @@ func _resort() -> void: if has_meta("should_fill_horizontal"): size_flags_horizontal = Control.SIZE_FILL else: - if not has_meta("size_flags_set_by_style_manager"): - size_flags_horizontal = Control.SIZE_SHRINK_BEGIN + if size_flags_horizontal == Control.SIZE_EXPAND_FILL and has_meta("size_flags_set_by_style_manager"): + pass + else: + if not has_meta("size_flags_set_by_style_manager"): + size_flags_horizontal = Control.SIZE_SHRINK_BEGIN # Check if we should fill vertically (for h-full) if has_meta("should_fill_vertical"): diff --git a/flumi/Scripts/B9/CSSParser.gd b/flumi/Scripts/B9/CSSParser.gd index 8755f6a..7c0a2b4 100644 --- a/flumi/Scripts/B9/CSSParser.gd +++ b/flumi/Scripts/B9/CSSParser.gd @@ -6,8 +6,9 @@ class CSSRule: var event_prefix: String = "" var properties: Dictionary = {} var specificity: int = 0 - var selector_type: String = "simple" # simple, descendant, child, adjacent_sibling, general_sibling, attribute - var selector_parts: Array = [] # For complex selectors + var selector_type: String = "simple" # simple, descendant, child, adjacent_sibling, general_sibling, attribute + var selector_parts: Array = [] # For complex selectors + var is_user_css: bool = false func init(sel: String = ""): selector = sel @@ -52,9 +53,9 @@ class CSSRule: func calculate_specificity(): specificity = 1 if selector.begins_with("."): - specificity += 10 + specificity += 20 if selector.contains("["): - specificity += 10 # Attribute selectors + specificity += 10 match selector_type: "child": specificity += 8 @@ -68,6 +69,10 @@ class CSSRule: specificity += 4 if event_prefix.length() > 0: specificity += 10 + + if is_user_css: + specificity += 100 + class CSSStylesheet: var rules: Array[CSSRule] = [] @@ -287,7 +292,7 @@ func init(css_content: String = ""): stylesheet = CSSStylesheet.new() css_text = css_content -func parse() -> void: +func parse(is_user_css: bool = false) -> void: if css_text.is_empty(): return @@ -295,7 +300,7 @@ func parse() -> void: var rules = extract_rules(cleaned_css) for rule_data in rules: - var rule = parse_rule(rule_data) + var rule = parse_rule(rule_data, is_user_css) if rule: stylesheet.add_rule(rule) @@ -355,9 +360,10 @@ func find_matching_brace(css: String, start_pos: int) -> int: return -1 -func parse_rule(rule_data: Dictionary) -> CSSRule: +func parse_rule(rule_data: Dictionary, is_user_css: bool = false) -> CSSRule: var rule = CSSRule.new() rule.selector = rule_data.selector + rule.is_user_css = is_user_css rule.init(rule.selector) var properties_text = rule_data.properties @@ -397,6 +403,7 @@ func parse_utility_class(rule: CSSRule, utility_name: String) -> void: pseudo_rule.event_prefix = pseudo pseudo_rule.selector_type = rule.selector_type pseudo_rule.selector_parts = rule.selector_parts.duplicate() + pseudo_rule.is_user_css = rule.is_user_css pseudo_rule.calculate_specificity() pseudo_rule.specificity += 100 diff --git a/flumi/Scripts/B9/HTMLParser.gd b/flumi/Scripts/B9/HTMLParser.gd index 86d9bed..5f689f7 100644 --- a/flumi/Scripts/B9/HTMLParser.gd +++ b/flumi/Scripts/B9/HTMLParser.gd @@ -25,20 +25,20 @@ class HTMLElement: return get_attribute("id") func get_collapsed_text() -> String: - var collapsed = text_content.strip_edges() + var collapsed = HTMLParser.unescape_html_entities(text_content).strip_edges() # Replace multiple whitespace characters with single space var regex = RegEx.new() regex.compile("\\s+") return regex.sub(collapsed, " ", true) func get_preserved_text() -> String: - return text_content + return HTMLParser.unescape_html_entities(text_content) func get_bbcode_formatted_text(parser: HTMLParser) -> String: var styles = {} if parser != null: styles = parser.get_element_styles_with_inheritance(self, "", []) - return HTMLParser.get_bbcode_with_styles(self, styles, parser) + return HTMLParser.get_bbcode_with_styles(self, styles, parser, []) func is_inline_element() -> bool: return tag_name in ["b", "i", "u", "small", "mark", "code", "span", "a", "input"] @@ -68,10 +68,69 @@ var bitcode: PackedByteArray var parse_result: ParseResult func _init(data: PackedByteArray): - bitcode = data + var html_string = data.get_string_from_utf8() + html_string = preprocess_html_entities(html_string) + bitcode = html_string.to_utf8_buffer() xml_parser = XMLParser.new() parse_result = ParseResult.new() +static func unescape_html_entities(text: String) -> String: + return text.replace("<", "<").replace(">", ">").replace(""", "\"").replace("'", "'").replace("&", "&") + +static func preprocess_html_entities(html: String) -> String: + var result = "" + var i = 0 + var in_tag = false + + while i < html.length(): + var char = html[i] + + if char == "<": + # Check if this starts a valid HTML tag + var tag_end = html.find(">", i) + if tag_end != -1: + var potential_tag = html.substr(i, tag_end - i + 1) + # Simple check for valid tag pattern + if is_valid_tag_pattern(potential_tag): + result += potential_tag + i = tag_end + 1 + continue + # If not a valid tag, escape it + result += "<" + elif char == ">": + # Escape standalone > that's not part of a tag + result += ">" + else: + result += char + + i += 1 + + return result + +static func is_valid_tag_pattern(tag: String) -> bool: + if tag.length() < 3: # Minimum: + return false + + if not tag.begins_with("<") or not tag.ends_with(">"): + return false + + var inner = tag.substr(1, tag.length() - 2).strip_edges() + + if inner.begins_with("/"): + inner = inner.substr(1).strip_edges() + + # Handle self-closing tags + if inner.ends_with("/"): + inner = inner.substr(0, inner.length() - 1).strip_edges() + + # Extract tag name (first part before space or attributes) + var tag_name = inner.split(" ")[0].split("\t")[0] + + # Valid tag names contain only letters, numbers, and hyphens + var regex = RegEx.new() + regex.compile("^[a-zA-Z][a-zA-Z0-9-]*$") + return regex.search(tag_name) != null + # Main parsing function func parse() -> ParseResult: xml_parser.open_buffer(bitcode) @@ -408,7 +467,7 @@ func apply_element_styles(node: Control, element: HTMLElement, parser: HTMLParse var styles = parser.get_element_styles_with_inheritance(element, "", []) if node.get("rich_text_label"): var label = node.rich_text_label - var text = HTMLParser.get_bbcode_with_styles(element, styles, parser) + var text = HTMLParser.get_bbcode_with_styles(element, styles, parser, []) label.text = text static func apply_element_bbcode_formatting(element: HTMLElement, styles: Dictionary, content: String, parser: HTMLParser = null) -> String: @@ -478,7 +537,13 @@ static func apply_element_bbcode_formatting(element: HTMLElement, styles: Dictio return formatted_content -static func get_bbcode_with_styles(element: HTMLElement, styles: Dictionary, parser: HTMLParser) -> String: +static func get_bbcode_with_styles(element: HTMLElement, styles: Dictionary, parser: HTMLParser, visited_elements: Array = []) -> String: + if element in visited_elements: + return "" + + var new_visited = visited_elements.duplicate() + new_visited.append(element) + var text = "" if element.text_content.length() > 0: text += element.get_collapsed_text() @@ -486,8 +551,8 @@ static func get_bbcode_with_styles(element: HTMLElement, styles: Dictionary, par for child in element.children: var child_styles = styles if parser != null: - child_styles = parser.get_element_styles_with_inheritance(child, "", []) - var child_content = HTMLParser.get_bbcode_with_styles(child, child_styles, parser) + child_styles = parser.get_element_styles_with_inheritance(child, "", new_visited) + var child_content = HTMLParser.get_bbcode_with_styles(child, child_styles, parser, new_visited) child_content = apply_element_bbcode_formatting(child, child_styles, child_content, parser) text += child_content diff --git a/flumi/Scripts/B9/Lua.gd b/flumi/Scripts/B9/Lua.gd index e04ca64..249fab1 100644 --- a/flumi/Scripts/B9/Lua.gd +++ b/flumi/Scripts/B9/Lua.gd @@ -642,8 +642,6 @@ func execute_lua_script(code: String, vm: LuauVM): script_start_time = Time.get_ticks_msec() / 1000.0 threaded_vm.execute_script_async(code) - - func _on_threaded_script_completed(result: Dictionary): var execution_time = (Time.get_ticks_msec() / 1000.0) - script_start_time @@ -689,6 +687,10 @@ func _handle_dom_operation(operation: Dictionary): LuaDOMUtils.handle_insert_after(operation, dom_parser, self) "replace_child": LuaDOMUtils.handle_replace_child(operation, dom_parser, self) + "focus_element": + _handle_element_focus(operation) + "unfocus_element": + _handle_element_unfocus(operation) _: pass # Unknown operation type, ignore @@ -786,6 +788,53 @@ func _handle_text_getting(operation: Dictionary): return element.text_content return "" +func _handle_element_focus(operation: Dictionary): + var element_id: String = operation.element_id + + var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null) + if not dom_node: + return + + var focusable_control = _find_focusable_control(dom_node) + if focusable_control and focusable_control.has_method("grab_focus"): + focusable_control.call_deferred("grab_focus") + +func _handle_element_unfocus(operation: Dictionary): + var element_id: String = operation.element_id + + var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null) + if not dom_node: + return + + var focusable_control = _find_focusable_control(dom_node) + if focusable_control and focusable_control.has_method("release_focus"): + focusable_control.call_deferred("release_focus") + +func _find_focusable_control(node: Node) -> Control: + if not node: + return null + + if node is Control and node.focus_mode != Control.FOCUS_NONE and node.has_method("grab_focus"): + return node + + if node.has_method("get_children"): + for child in node.get_children(): + if child.visible and child is Control: + if child is LineEdit or child is TextEdit or child is SpinBox or child is OptionButton: + if child.focus_mode != Control.FOCUS_NONE: + return child + + if child is SpinBox: + var line_edit = child.get_line_edit() + if line_edit and line_edit.focus_mode != Control.FOCUS_NONE: + return line_edit + + var focusable_child = _find_focusable_control(child) + if focusable_child: + return focusable_child + + return null + func _handle_body_event_registration(operation: Dictionary): var event_name: String = operation.event_name var callback_ref: int = operation.callback_ref diff --git a/flumi/Scripts/Constants.gd b/flumi/Scripts/Constants.gd index fde9ec0..f93bb24 100644 --- a/flumi/Scripts/Constants.gd +++ b/flumi/Scripts/Constants.gd @@ -21,6 +21,7 @@ code { text-xl font-mono } a { text-[#1a0dab] } pre { text-xl font-mono } +img { object-fill } button { text-[16px] bg-[#1b1b1b] rounded-md text-white hover:bg-[#2a2a2a] active:bg-[#101010] px-3 py-1.5 } button[disabled] { bg-[#666666] text-[#999999] cursor-not-allowed } @@ -29,7 +30,7 @@ select:active { text-[#000000] border-[3px] border-[#000000] } input[type="color"] { w-32 } input[type="range"] { w-32 } -input[type="text"] { w-64 } +input[type="text"] { text-[16px] w-64 } input[type="number"] { w-32 text-[16px] bg-transparent border border-[#000000] rounded-[3px] text-[#000000] hover:border-[3px] hover:border-[#000000] px-3 py-1.5 } input[type="date"] { w-28 text-[16px] bg-[#1b1b1b] rounded-md text-white hover:bg-[#2a2a2a] active:bg-[#101010] px-3 py-1.5 } """ diff --git a/flumi/Scripts/GurtProtocol.gd b/flumi/Scripts/GurtProtocol.gd index 4672678..2500cea 100644 --- a/flumi/Scripts/GurtProtocol.gd +++ b/flumi/Scripts/GurtProtocol.gd @@ -1,10 +1,8 @@ extends RefCounted class_name GurtProtocol -const DNS_API_URL = "gurt://localhost:8877" - -# DNS resolution cache: domain.tld -> IP address -static var _dns_cache: Dictionary = {} +const DNS_SERVER_IP: String = "135.125.163.131" +const DNS_SERVER_PORT: int = 8877 static func is_gurt_domain(url: String) -> bool: if url.begins_with("gurt://"): @@ -16,65 +14,13 @@ static func is_gurt_domain(url: String) -> bool: return false -static func parse_gurt_domain(url: String) -> Dictionary: - var domain_part = url - var path = "/" +static func is_direct_address(domain: String) -> bool: + # Check if it's already an IP address or localhost + if domain.contains(":"): + var parts = domain.split(":") + domain = parts[0] - if url.begins_with("gurt://"): - domain_part = url.substr(7) - - # Extract path from domain_part (e.g., "test.dawg/script.lua" -> "test.dawg" + "/script.lua") - var path_start = domain_part.find("/") - if path_start != -1: - path = domain_part.substr(path_start) - domain_part = domain_part.substr(0, path_start) - - # Check if domain is cached (resolved before) - var domain_key = domain_part - if _dns_cache.has(domain_key): - return { - "direct_address": _dns_cache[domain_key], - "display_url": domain_part + path, - "is_direct": true, - "path": path, - "full_domain": domain_part - } - - if domain_part.contains(":") or domain_part.begins_with("127.0.0.1") or domain_part.begins_with("localhost") or is_ip_address(domain_part): - return { - "direct_address": domain_part, - "display_url": domain_part + path, - "is_direct": true, - "path": path, - "full_domain": domain_part - } - - var parts = domain_part.split(".") - if parts.size() < 2: - return {} - - # Support subdomains (e.g., api.blog.example.com) - if parts.size() == 2: - return { - "name": parts[0], - "tld": parts[1], - "display_url": domain_part + path, - "is_direct": false, - "path": path, - "full_domain": domain_part, - "is_subdomain": false - } - else: - return { - "name": parts[parts.size() - 2], # The domain name part - "tld": parts[parts.size() - 1], # The TLD part - "display_url": domain_part + path, - "is_direct": false, - "path": path, - "full_domain": domain_part, - "is_subdomain": true, - "subdomain_parts": parts.slice(0, parts.size() - 2) - } + return domain == "localhost" or domain == "127.0.0.1" or is_ip_address(domain) static func is_ip_address(address: String) -> bool: var parts = address.split(".") @@ -90,329 +36,25 @@ static func is_ip_address(address: String) -> bool: return true -static func fetch_domain_info(name: String, tld: String) -> Dictionary: - var request_data = JSON.stringify({"name": name, "tld": tld}) - var result = await fetch_dns_post_working("localhost:8877", "/resolve", request_data) +static func resolve_gurt_domain(domain: String) -> String: + if is_direct_address(domain): + if domain == "localhost": + return "127.0.0.1" + return domain - if result.has("error"): - return {"error": result.error} - - if not result.has("content"): - return {"error": "No content in DNS response"} - - var content_str = result.content.get_string_from_utf8() - var json = JSON.new() - var parse_result = json.parse(content_str) - - if parse_result != OK: - return {"error": "Invalid JSON in DNS response"} - - return json.data - -static func fetch_full_domain_info(full_domain: String, record_type: String = "") -> Dictionary: - var request_data = {"domain": full_domain} - if not record_type.is_empty(): - request_data["record_type"] = record_type - - var json_data = JSON.stringify(request_data) - var result = await fetch_dns_post_working("localhost:8877", "/resolve-full", json_data) - - if result.has("error"): - return {"error": result.error} - - if not result.has("content"): - return {"error": "No content in DNS response"} - - var content_str = result.content.get_string_from_utf8() - var json = JSON.new() - var parse_result = json.parse(content_str) - - if parse_result != OK: - return {"error": "Invalid JSON in DNS response"} - - return json.data - -static func fetch_dns_post_working(server: String, path: String, json_data: String) -> Dictionary: - var shared_result = {"finished": false} - var thread = Thread.new() - var mutex = Mutex.new() - - var thread_func = func(): - var local_result = {} - var client = GurtProtocolClient.new() - - for ca_cert in CertificateManager.trusted_ca_certificates: - client.add_ca_certificate(ca_cert) - - if not client.create_client(10): - local_result = {"error": "Failed to create client"} - else: - var url = "gurt://" + server + path - - # Prepare request options - var options = { - "method": "POST", - "headers": {"Content-Type": "application/json"}, - "body": json_data - } - - var response = client.request(url, options) - - client.disconnect() - - if not response: - local_result = {"error": "No response from server"} - elif not response.is_success: - local_result = {"error": "Server error: " + str(response.status_code) + " " + str(response.status_message)} - else: - local_result = {"content": response.body} - - mutex.lock() - shared_result.clear() - for key in local_result: - shared_result[key] = local_result[key] - shared_result["finished"] = true - mutex.unlock() - - thread.start(thread_func) - - # Non-blocking wait - while not shared_result.get("finished", false): - await Engine.get_main_loop().process_frame - - thread.wait_to_finish() - - mutex.lock() - var final_result = {} - for key in shared_result: - if key != "finished": - final_result[key] = shared_result[key] - mutex.unlock() - - return final_result - -static func fetch_content_via_gurt(ip: String, path: String = "/") -> Dictionary: - var client = GurtProtocolClient.new() - - for ca_cert in CertificateManager.trusted_ca_certificates: - client.add_ca_certificate(ca_cert) - - if not client.create_client(30): - return {"error": "Failed to create GURT client"} - - var gurt_url = "gurt://" + ip + ":4878" + path - - var response = client.request(gurt_url, {"method": "GET"}) - - client.disconnect() - - if not response: - return {"error": "No response from GURT server"} - - if not response.is_success: - var error_msg = "Server returned status " + str(response.status_code) + ": " + response.status_message - return {"error": error_msg} - - var content = response.body - return {"content": content, "headers": response.headers} - -static func fetch_content_via_gurt_direct(address: String, path: String = "/") -> Dictionary: - var shared_result = {"finished": false} - var thread = Thread.new() - var mutex = Mutex.new() - - var thread_func = func(): - var local_result = {} - var client = GurtProtocolClient.new() - - for ca_cert in CertificateManager.trusted_ca_certificates: - client.add_ca_certificate(ca_cert) - - if not client.create_client(10): - local_result = {"error": "Failed to create GURT client"} - else: - var gurt_url: String - if address.contains(":"): - gurt_url = "gurt://" + address + path - else: - gurt_url = "gurt://" + address + ":4878" + path - - var response = client.request(gurt_url, {"method": "GET"}) - - client.disconnect() - - if not response: - local_result = {"error": "No response from GURT server"} - else: - var content = response.body - - if not response.is_success: - var error_msg = "Server returned status " + str(response.status_code) + ": " + response.status_message - local_result = {"error": error_msg, "content": content, "headers": response.headers} - else: - local_result = {"content": content, "headers": response.headers} - - mutex.lock() - shared_result.clear() - for key in local_result: - shared_result[key] = local_result[key] - shared_result["finished"] = true - mutex.unlock() - - thread.start(thread_func) - - # Non-blocking wait using signals instead of polling - while not shared_result.get("finished", false): - await Engine.get_main_loop().process_frame - # Yield control back to the main thread without blocking delays - - thread.wait_to_finish() - - mutex.lock() - var final_result = {} - for key in shared_result: - if key != "finished": - final_result[key] = shared_result[key] - mutex.unlock() - - return final_result - -static func handle_gurt_domain(url: String) -> Dictionary: - var parsed = parse_gurt_domain(url) - if parsed.is_empty(): - return {"error": "Invalid domain format. Use: domain.tld or IP:port", "html": create_error_page("Invalid domain format. Use: domain.tld or IP:port")} - - var target_address: String - var path = parsed.get("path", "/") - - if parsed.get("is_direct", false): - target_address = parsed.direct_address - else: - var domain_info: Dictionary - - # Use the new full domain resolution for subdomains - if parsed.get("is_subdomain", false): - domain_info = await fetch_full_domain_info(parsed.full_domain) - else: - domain_info = await fetch_domain_info(parsed.name, parsed.tld) - - if domain_info.has("error"): - return {"error": domain_info.error, "html": create_error_page(domain_info.error)} - - # Process DNS records to find target address - var target_result = await resolve_target_address(domain_info, parsed.full_domain) - if target_result.has("error"): - return {"error": target_result.error, "html": create_error_page(target_result.error)} - - target_address = target_result.address - - # Cache the resolved address - var domain_key = parsed.full_domain - _dns_cache[domain_key] = target_address - - var content_result = await fetch_content_via_gurt_direct(target_address, path) - if content_result.has("error"): - var error_msg = "Failed to fetch content from " + target_address + path + " via GURT protocol - " + content_result.error - if content_result.has("content") and not content_result.content.is_empty(): - return {"html": content_result.content, "display_url": parsed.display_url} - return {"error": error_msg, "html": create_error_page(error_msg)} - - if not content_result.has("content"): - var error_msg = "No content received from " + target_address + path - return {"error": error_msg, "html": create_error_page(error_msg)} - - var html_content = content_result.content - if html_content.is_empty(): - var error_msg = "Empty content received from " + target_address + path - return {"error": error_msg, "html": create_error_page(error_msg)} - - return {"html": html_content, "display_url": parsed.display_url} - -static func resolve_target_address(domain_info: Dictionary, original_domain: String) -> Dictionary: - if not domain_info.has("records") or domain_info.records == null: - return {"error": "No DNS records found for domain"} - - var records = domain_info.records - var max_cname_depth = 5 # Prevent infinite CNAME loops - var cname_depth = 0 - - # First pass: Look for direct A/AAAA records - var a_records = [] - var aaaa_records = [] - var cname_records = [] - var ns_records = [] - - for record in records: - if not record.has("type") or not record.has("value"): - continue - - match record.type: - "A": - a_records.append(record.value) - "AAAA": - aaaa_records.append(record.value) - "CNAME": - cname_records.append(record.value) - "NS": - ns_records.append(record.value) - - # If we have direct A records, use the first one - if not a_records.is_empty(): - return {"address": a_records[0]} - - # If we have IPv6 AAAA records and no A records, we need to handle this - if not aaaa_records.is_empty() and a_records.is_empty(): - return {"error": "Only IPv6 (AAAA) records found, but IPv4 required for GURT protocol"} - - # Follow CNAME chain - if not cname_records.is_empty(): - var current_cname = cname_records[0] - - while cname_depth < max_cname_depth: - cname_depth += 1 - - # Try to resolve the CNAME target - var cname_info = await fetch_full_domain_info(current_cname, "A") - if cname_info.has("error"): - return {"error": "Failed to resolve CNAME target: " + current_cname + " - " + cname_info.error} - - if not cname_info.has("records") or cname_info.records == null: - return {"error": "No records found for CNAME target: " + current_cname} - - # Look for A records in the CNAME target - var found_next_cname = false - for record in cname_info.records: - if record.has("type") and record.type == "A" and record.has("value"): - return {"address": record.value} - elif record.has("type") and record.type == "CNAME" and record.has("value"): - # Another CNAME, continue the chain - current_cname = record.value - found_next_cname = true - break - - if not found_next_cname: - # No more CNAMEs found, but also no A record - return {"error": "CNAME chain ended without A record for: " + current_cname} - - return {"error": "CNAME chain too deep (max " + str(max_cname_depth) + " levels)"} - - # If we have NS records, this indicates delegation - if not ns_records.is_empty(): - return {"error": "Domain is delegated to nameservers: " + str(ns_records) + ". Cannot resolve directly."} - - return {"error": "No A record found for domain"} + return domain static func get_error_type(error_message: String) -> Dictionary: if "DNS server is not responding" in error_message or "Domain not found" in error_message: - return {"code": "ERR_NAME_NOT_RESOLVED", "title": "This site can't be reached", "icon": "🌐"} + return {"code": "ERR_NAME_NOT_RESOLVED", "title": "This site can't be reached", "icon": "? :("} elif "timeout" in error_message.to_lower() or "timed out" in error_message.to_lower(): - return {"code": "ERR_CONNECTION_TIMED_OUT", "title": "This site can't be reached", "icon": "⏰"} + return {"code": "ERR_CONNECTION_TIMED_OUT", "title": "This site can't be reached", "icon": "...?"} elif "Failed to fetch" in error_message or "No response" in error_message: - return {"code": "ERR_CONNECTION_REFUSED", "title": "This site can't be reached", "icon": "🚫"} + return {"code": "ERR_CONNECTION_REFUSED", "title": "This site can't be reached", "icon": ">:("} elif "Invalid domain format" in error_message: - return {"code": "ERR_INVALID_URL", "title": "This page isn't working", "icon": "⚠️"} + return {"code": "ERR_INVALID_URL", "title": "This page isn't working", "icon": ":|"} else: - return {"code": "ERR_UNKNOWN", "title": "Something went wrong", "icon": "❌"} + return {"code": "ERR_UNKNOWN", "title": "Something went wrong", "icon": ">_<"} static func create_error_page(error_message: String) -> PackedByteArray: var error_info = get_error_type(error_message) diff --git a/flumi/Scripts/Network.gd b/flumi/Scripts/Network.gd index b0105a5..4f5bc66 100644 --- a/flumi/Scripts/Network.gd +++ b/flumi/Scripts/Network.gd @@ -112,13 +112,40 @@ func fetch_gurt_resource(url: String) -> String: if not GurtProtocol.is_gurt_domain(url): return "" - var result = await GurtProtocol.handle_gurt_domain(url) + var gurt_url = url + if not gurt_url.begins_with("gurt://"): + gurt_url = "gurt://" + gurt_url - if result.has("error"): - print("GURT resource error: ", result.error) + if gurt_url.contains("localhost"): + gurt_url = gurt_url.replace("localhost", "127.0.0.1") + + var client = GurtProtocolClient.new() + + for ca_cert in CertificateManager.trusted_ca_certificates: + client.add_ca_certificate(ca_cert) + + if not client.create_client(30): + print("GURT resource error: Failed to create client") return "" - if result.has("html"): - return result.html.get_string_from_utf8() + var host_domain = gurt_url + if host_domain.begins_with("gurt://"): + host_domain = host_domain.substr(7) + var slash_pos = host_domain.find("/") + if slash_pos != -1: + host_domain = host_domain.substr(0, slash_pos) - return "" + var response = client.request(gurt_url, { + "method": "GET", + "headers": {"Host": host_domain} + }) + client.disconnect() + + if not response or not response.is_success: + var error_msg = "Failed to load GURT resource" + if response: + error_msg += ": " + str(response.status_code) + " " + response.status_message + print("GURT resource error: ", error_msg) + return "" + + return response.body.get_string_from_utf8() diff --git a/flumi/Scripts/StyleManager.gd b/flumi/Scripts/StyleManager.gd index c12811e..01880bf 100644 --- a/flumi/Scripts/StyleManager.gd +++ b/flumi/Scripts/StyleManager.gd @@ -67,6 +67,7 @@ static func apply_element_styles(node: Control, element: HTMLParser.HTMLElement, if width is String and width == "100%": node.size_flags_horizontal = Control.SIZE_EXPAND_FILL node.custom_minimum_size.x = 0 + node.set_meta("size_flags_set_by_style_manager", true) else: node.custom_minimum_size.x = width node.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN @@ -75,6 +76,7 @@ static func apply_element_styles(node: Control, element: HTMLParser.HTMLElement, if height is String and height == "100%": node.size_flags_vertical = Control.SIZE_EXPAND_FILL node.custom_minimum_size.y = 0 + node.set_meta("size_flags_set_by_style_manager", true) else: node.custom_minimum_size.y = height node.size_flags_vertical = Control.SIZE_SHRINK_BEGIN diff --git a/flumi/Scripts/Tags/img.gd b/flumi/Scripts/Tags/img.gd index bb18566..1a2f5d3 100644 --- a/flumi/Scripts/Tags/img.gd +++ b/flumi/Scripts/Tags/img.gd @@ -33,6 +33,3 @@ func load_image_async(src: String, element: HTMLParser.HTMLElement, parser: HTML size_flags_horizontal = Control.SIZE_EXPAND_FILL size_flags_vertical = Control.SIZE_EXPAND_FILL custom_minimum_size = Vector2.ZERO - else: - custom_minimum_size = Vector2(1, 1) - size = Vector2(100, 100) # StyleManager will handle this diff --git a/flumi/Scripts/Tags/input.gd b/flumi/Scripts/Tags/input.gd index a936ecf..e61c464 100644 --- a/flumi/Scripts/Tags/input.gd +++ b/flumi/Scripts/Tags/input.gd @@ -444,6 +444,16 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) -> var placeholder_color = Color(text_color.r, text_color.g, text_color.b, text_color.a * 0.6) line_edit.add_theme_color_override("font_placeholder_color", placeholder_color) + if styles.has("font-size"): + var font_size = int(styles["font-size"]) + if active_child is LineEdit: + active_child.add_theme_font_size_override("font_size", font_size) + elif active_child is SpinBox: + active_child.add_theme_font_size_override("font_size", font_size) + var line_edit = active_child.get_line_edit() + if line_edit: + line_edit.add_theme_font_size_override("font_size", font_size) + # Apply stylebox for borders, background, padding, etc. if BackgroundUtils.needs_background_wrapper(styles) or active_child is SpinBox: apply_stylebox_to_input(active_child, styles) @@ -464,7 +474,7 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) -> var new_height = max(active_child.custom_minimum_size.y, active_child.size.y) if width: - if typeof(width) == TYPE_STRING and width == "100%": + if typeof(width) == TYPE_STRING and (width == "100%" or width == "full"): active_child.size_flags_horizontal = Control.SIZE_EXPAND_FILL size_flags_horizontal = Control.SIZE_EXPAND_FILL new_width = 0 @@ -483,7 +493,7 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) -> active_child.custom_minimum_size = new_child_size - if width and not (typeof(width) == TYPE_STRING and width == "100%"): + if width and not (typeof(width) == TYPE_STRING and (width == "100%" or width == "full")): active_child.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN if height: active_child.size_flags_vertical = Control.SIZE_SHRINK_BEGIN @@ -494,7 +504,7 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) -> custom_minimum_size = new_child_size # Root Control adjusts size flags to match child - if width and not (typeof(width) == TYPE_STRING and width == "100%"): + if width and not (typeof(width) == TYPE_STRING and (width == "100%" or width == "full")): size_flags_horizontal = Control.SIZE_SHRINK_BEGIN else: size_flags_horizontal = Control.SIZE_EXPAND_FILL diff --git a/flumi/Scripts/Tags/p.gd b/flumi/Scripts/Tags/p.gd index c8f24d1..d5aa743 100644 --- a/flumi/Scripts/Tags/p.gd +++ b/flumi/Scripts/Tags/p.gd @@ -4,18 +4,19 @@ extends HBoxContainer var _element: HTMLParser.HTMLElement var _parser: HTMLParser -func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void: +const BROWSER_THEME = preload("res://Scenes/Styles/BrowserText.tres") + +func init(element, parser: HTMLParser) -> void: _element = element _parser = parser size_flags_horizontal = Control.SIZE_EXPAND_FILL size_flags_vertical = Control.SIZE_SHRINK_BEGIN + + mouse_filter = Control.MOUSE_FILTER_PASS if get_child_count() > 0: return - var content_parts = [] - var current_text = "" - var element_text = element.text_content var child_texts = [] @@ -27,7 +28,7 @@ func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void: parent_only_text = parent_only_text.replace(child_text, "") if not parent_only_text.strip_edges().is_empty(): - var parent_label = create_styled_label(parent_only_text.strip_edges(), element, parser) + create_styled_label(parent_only_text.strip_edges(), element, parser) for child in element.children: var child_label = create_styled_label(child.get_bbcode_formatted_text(parser), element, parser) @@ -35,13 +36,30 @@ func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void: if contains_hyperlink(child): child_label.meta_clicked.connect(_on_meta_clicked) -func create_styled_label(text: String, element: HTMLParser.HTMLElement, parser: HTMLParser) -> RichTextLabel: +func create_styled_label(text: String, element, parser: HTMLParser) -> RichTextLabel: var label = RichTextLabel.new() + + label.theme = BROWSER_THEME + label.focus_mode = Control.FOCUS_ALL + label.add_theme_color_override("default_color", Color.BLACK) + label.bbcode_enabled = true label.fit_content = true + label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + label.selection_enabled = true + + var parent_cursor_shape = Control.CURSOR_IBEAM + if element.parent: + var parent_styles = parser.get_element_styles_with_inheritance(element.parent, "", []) + if parent_styles.has("cursor"): + parent_cursor_shape = StyleManager.get_cursor_shape_from_type(parent_styles["cursor"]) + + label.mouse_default_cursor_shape = parent_cursor_shape + label.mouse_filter = Control.MOUSE_FILTER_PASS + label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART label.size_flags_horizontal = Control.SIZE_EXPAND_FILL label.size_flags_vertical = Control.SIZE_SHRINK_CENTER - label.bbcode_enabled = true + add_child(label) var styles = parser.get_element_styles_with_inheritance(element, "", []) @@ -51,12 +69,17 @@ func create_styled_label(text: String, element: HTMLParser.HTMLElement, parser: return label func _apply_auto_resize_to_label(label: RichTextLabel): + if not is_instance_valid(label) or not is_instance_valid(self): + return + if not label.is_inside_tree(): await label.tree_entered + if not is_instance_valid(label) or not is_instance_valid(self): + return + var min_width = 20 var max_width = 800 - var min_height = 30 label.fit_content = true @@ -65,8 +88,11 @@ func _apply_auto_resize_to_label(label: RichTextLabel): await get_tree().process_frame + if not is_instance_valid(label) or not is_instance_valid(self): + return + var natural_width = label.size.x - natural_width *= 1.0 # font weight multiplier simplified + natural_width *= 1.0 var desired_width = clampf(natural_width, min_width, max_width) @@ -74,6 +100,9 @@ func _apply_auto_resize_to_label(label: RichTextLabel): await get_tree().process_frame + if not is_instance_valid(label) or not is_instance_valid(self): + return + label.custom_minimum_size = Vector2(desired_width, 0) label.queue_redraw() @@ -110,18 +139,35 @@ func set_text(new_text: String) -> void: child.queue_free() if _element and _parser: - var label = create_styled_label(new_text, _element, _parser) + create_styled_label(new_text, _element, _parser) else: - var label = create_label(new_text) + create_label(new_text) func create_label(text: String) -> RichTextLabel: var label = RichTextLabel.new() - label.text = text + + label.theme = BROWSER_THEME + label.focus_mode = Control.FOCUS_ALL + label.add_theme_color_override("default_color", Color.BLACK) + label.bbcode_enabled = true label.fit_content = true + label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + label.selection_enabled = true + + var parent_cursor_shape = Control.CURSOR_IBEAM + if _element and _parser and _element.parent: + var parent_styles = _parser.get_element_styles_with_inheritance(_element.parent, "", []) + if parent_styles.has("cursor"): + parent_cursor_shape = StyleManager.get_cursor_shape_from_type(parent_styles["cursor"]) + + label.mouse_default_cursor_shape = parent_cursor_shape + label.mouse_filter = Control.MOUSE_FILTER_PASS + + label.text = text label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART label.size_flags_horizontal = Control.SIZE_EXPAND_FILL label.size_flags_vertical = Control.SIZE_SHRINK_CENTER - label.bbcode_enabled = true + add_child(label) call_deferred("_apply_auto_resize_to_label", label) return label diff --git a/flumi/Scripts/Utils/BackgroundUtils.gd b/flumi/Scripts/Utils/BackgroundUtils.gd index d83c7f5..0dc5b14 100644 --- a/flumi/Scripts/Utils/BackgroundUtils.gd +++ b/flumi/Scripts/Utils/BackgroundUtils.gd @@ -195,12 +195,42 @@ static func setup_panel_hover_support(panel: PanelContainer, normal_styles: Dict panel.set_meta("hover_stylebox", hover_stylebox) panel.set_meta("normal_styles", normal_styles.duplicate(true)) panel.set_meta("hover_styles", merged_hover_styles.duplicate(true)) + panel.set_meta("is_hovering", false) # Connect mouse events panel.mouse_entered.connect(_on_panel_mouse_entered.bind(panel)) - panel.mouse_exited.connect(_on_panel_mouse_exited.bind(panel)) + panel.mouse_exited.connect(_on_panel_mouse_exited_with_delay.bind(panel)) + + _setup_child_hover_listeners(panel) + +static func _setup_child_hover_listeners(panel: PanelContainer): + for child in panel.get_children(): + _connect_child_hover_events(child, panel) + + panel.child_entered_tree.connect(_on_child_added.bind(panel)) + +static func _connect_child_hover_events(child: Node, panel: PanelContainer): + if child is Control: + # Only connect if not already connected + if not child.mouse_entered.is_connected(_on_child_mouse_entered.bind(panel)): + child.mouse_entered.connect(_on_child_mouse_entered.bind(panel)) + if not child.mouse_exited.is_connected(_on_child_mouse_exited.bind(panel)): + child.mouse_exited.connect(_on_child_mouse_exited.bind(panel)) + + for grandchild in child.get_children(): + _connect_child_hover_events(grandchild, panel) + +static func _on_child_added(child: Node, panel: PanelContainer): + _connect_child_hover_events(child, panel) + +static func _on_child_mouse_entered(panel: PanelContainer): + _on_panel_mouse_entered(panel) + +static func _on_child_mouse_exited(panel: PanelContainer): + panel.get_tree().create_timer(0.01).timeout.connect(func(): _check_panel_hover(panel)) static func _on_panel_mouse_entered(panel: PanelContainer): + panel.set_meta("is_hovering", true) if panel.has_meta("hover_stylebox"): var hover_stylebox = panel.get_meta("hover_stylebox") panel.add_theme_stylebox_override("panel", hover_stylebox) @@ -210,15 +240,27 @@ static func _on_panel_mouse_entered(panel: PanelContainer): var transform_target = find_transform_target_for_panel(panel) StyleManager.apply_transform_properties_direct(transform_target, hover_styles) -static func _on_panel_mouse_exited(panel: PanelContainer): - if panel.has_meta("normal_stylebox"): - var normal_stylebox = panel.get_meta("normal_stylebox") - panel.add_theme_stylebox_override("panel", normal_stylebox) +static func _on_panel_mouse_exited_with_delay(panel: PanelContainer): + panel.get_tree().create_timer(0.01).timeout.connect(func(): _check_panel_hover(panel)) + +static func _check_panel_hover(panel: PanelContainer): + if not panel or not is_instance_valid(panel): + return - if panel.has_meta("normal_styles"): - var normal_styles = panel.get_meta("normal_styles") - var transform_target = find_transform_target_for_panel(panel) - StyleManager.apply_transform_properties_direct(transform_target, normal_styles) + var mouse_pos = panel.get_global_mouse_position() + var panel_rect = panel.get_global_rect() + var is_mouse_over = panel_rect.has_point(mouse_pos) + + if not is_mouse_over and panel.get_meta("is_hovering", false): + panel.set_meta("is_hovering", false) + if panel.has_meta("normal_stylebox"): + var normal_stylebox = panel.get_meta("normal_stylebox") + panel.add_theme_stylebox_override("panel", normal_stylebox) + + if panel.has_meta("normal_styles"): + var normal_styles = panel.get_meta("normal_styles") + var transform_target = find_transform_target_for_panel(panel) + StyleManager.apply_transform_properties_direct(transform_target, normal_styles) static func find_transform_target_for_panel(panel: PanelContainer) -> Control: var parent = panel.get_parent() diff --git a/flumi/Scripts/Utils/FlexUtils.gd b/flumi/Scripts/Utils/FlexUtils.gd index cf99212..3f6594b 100644 --- a/flumi/Scripts/Utils/FlexUtils.gd +++ b/flumi/Scripts/Utils/FlexUtils.gd @@ -64,6 +64,7 @@ static func apply_flex_container_properties(node, styles: Dictionary) -> void: if width_val == "full" or width_val == "100%": # For flex containers, w-full should expand to fill parent node.set_meta("should_fill_horizontal", true) + node.set_meta("size_flags_set_by_style_manager", true) elif typeof(width_val) == TYPE_STRING and width_val.ends_with("%"): node.set_meta("custom_css_width_percentage", width_val) else: @@ -73,6 +74,7 @@ static func apply_flex_container_properties(node, styles: Dictionary) -> void: if height_val == "full": # For flex containers, h-full should expand to fill parent node.set_meta("should_fill_vertical", true) + node.set_meta("size_flags_set_by_style_manager", true) elif typeof(height_val) == TYPE_STRING and height_val.ends_with("%"): node.set_meta("custom_css_height_percentage", height_val) else: diff --git a/flumi/Scripts/Utils/Lua/Class.gd b/flumi/Scripts/Utils/Lua/Class.gd index 6b1afb8..1ed41b3 100644 --- a/flumi/Scripts/Utils/Lua/Class.gd +++ b/flumi/Scripts/Utils/Lua/Class.gd @@ -278,7 +278,7 @@ static func update_div_hover_styles(dom_node: Control, element: HTMLParser.HTMLE if dom_node.mouse_entered.is_connected(BackgroundUtils._on_panel_mouse_entered): dom_node.mouse_entered.disconnect(BackgroundUtils._on_panel_mouse_entered) - if dom_node.mouse_exited.is_connected(BackgroundUtils._on_panel_mouse_exited): - dom_node.mouse_exited.disconnect(BackgroundUtils._on_panel_mouse_exited) + if dom_node.mouse_exited.is_connected(BackgroundUtils._on_panel_mouse_exited_with_delay): + dom_node.mouse_exited.disconnect(BackgroundUtils._on_panel_mouse_exited_with_delay) update_element_text_content(dom_node, element, dom_parser) diff --git a/flumi/Scripts/Utils/Lua/DOM.gd b/flumi/Scripts/Utils/Lua/DOM.gd index 6b3b9bb..49d3106 100644 --- a/flumi/Scripts/Utils/Lua/DOM.gd +++ b/flumi/Scripts/Utils/Lua/DOM.gd @@ -640,6 +640,12 @@ static func add_element_methods(vm: LuauVM, lua_api: LuaAPI) -> void: vm.lua_pushcallable(LuaDOMUtils._element_hide_wrapper, "element.hide") vm.lua_setfield(-2, "hide") + vm.lua_pushcallable(LuaDOMUtils._element_focus_wrapper, "element.focus") + vm.lua_setfield(-2, "focus") + + vm.lua_pushcallable(LuaDOMUtils._element_unfocus_wrapper, "element.unfocus") + vm.lua_setfield(-2, "unfocus") + _add_classlist_support(vm, lua_api) vm.lua_newtable() @@ -1420,6 +1426,48 @@ static func _element_hide_wrapper(vm: LuauVM) -> int: return 0 +static func _element_focus_wrapper(vm: LuauVM) -> int: + var lua_api = vm.get_meta("lua_api") as LuaAPI + if not lua_api: + vm.lua_pushboolean(false) + return 1 + + vm.luaL_checktype(1, vm.LUA_TTABLE) + + vm.lua_getfield(1, "_element_id") + var element_id: String = vm.lua_tostring(-1) + vm.lua_pop(1) + + var operation = { + "type": "focus_element", + "element_id": element_id + } + + emit_dom_operation(lua_api, operation) + vm.lua_pushboolean(true) + return 1 + +static func _element_unfocus_wrapper(vm: LuauVM) -> int: + var lua_api = vm.get_meta("lua_api") as LuaAPI + if not lua_api: + vm.lua_pushboolean(false) + return 1 + + vm.luaL_checktype(1, vm.LUA_TTABLE) + + vm.lua_getfield(1, "_element_id") + var element_id: String = vm.lua_tostring(-1) + vm.lua_pop(1) + + var operation = { + "type": "unfocus_element", + "element_id": element_id + } + + emit_dom_operation(lua_api, operation) + vm.lua_pushboolean(true) + return 1 + static func _element_create_tween_wrapper(vm: LuauVM) -> int: var lua_api = vm.get_meta("lua_api") as LuaAPI if not lua_api: diff --git a/flumi/Scripts/Utils/Lua/Regex.gd b/flumi/Scripts/Utils/Lua/Regex.gd index 163139e..3d61c8e 100644 --- a/flumi/Scripts/Utils/Lua/Regex.gd +++ b/flumi/Scripts/Utils/Lua/Regex.gd @@ -118,6 +118,12 @@ static func string_replace_all_handler(vm: LuauVM) -> int: return 1 +static func string_trim_handler(vm: LuauVM) -> int: + var subject: String = vm.luaL_checkstring(1) + var trimmed = subject.strip_edges() + vm.lua_pushstring(trimmed) + return 1 + static func setup_regex_api(vm: LuauVM) -> void: vm.lua_newtable() @@ -139,4 +145,7 @@ static func setup_regex_api(vm: LuauVM) -> void: vm.lua_pushcallable(string_replace_all_handler, "string.replaceAll") vm.lua_setfield(-2, "replaceAll") + vm.lua_pushcallable(string_trim_handler, "string.trim") + vm.lua_setfield(-2, "trim") + vm.lua_pop(1) diff --git a/flumi/Scripts/Utils/Lua/ThreadedVM.gd b/flumi/Scripts/Utils/Lua/ThreadedVM.gd index d70996a..76f7e88 100644 --- a/flumi/Scripts/Utils/Lua/ThreadedVM.gd +++ b/flumi/Scripts/Utils/Lua/ThreadedVM.gd @@ -53,6 +53,7 @@ func stop_lua_thread(): while lua_thread.is_alive() and (Time.get_ticks_msec() - timeout_start) < 500: OS.delay_msec(10) + lua_thread.wait_to_finish() lua_thread = null func execute_script_async(script_code: String): @@ -356,6 +357,7 @@ func _setup_additional_lua_apis(): LuaAudioUtils.setup_audio_api(lua_vm) LuaCrumbsUtils.setup_crumbs_api(lua_vm) LuaRegexUtils.setup_regex_api(lua_vm) + LuaURLUtils.setup_url_api(lua_vm) func _table_tostring_handler(vm: LuauVM) -> int: vm.luaL_checktype(1, vm.LUA_TTABLE) diff --git a/flumi/Scripts/Utils/Lua/URL.gd b/flumi/Scripts/Utils/Lua/URL.gd new file mode 100644 index 0000000..fa884f5 --- /dev/null +++ b/flumi/Scripts/Utils/Lua/URL.gd @@ -0,0 +1,21 @@ +class_name LuaURLUtils +extends RefCounted + +static func url_encode_handler(vm: LuauVM) -> int: + var input: String = vm.luaL_checkstring(1) + var encoded = input.uri_encode() + vm.lua_pushstring(encoded) + return 1 + +static func url_decode_handler(vm: LuauVM) -> int: + var input: String = vm.luaL_checkstring(1) + var decoded = input.uri_decode() + vm.lua_pushstring(decoded) + return 1 + +static func setup_url_api(vm: LuauVM) -> void: + vm.lua_pushcallable(url_encode_handler, "urlEncode") + vm.lua_setglobal("urlEncode") + + vm.lua_pushcallable(url_decode_handler, "urlDecode") + vm.lua_setglobal("urlDecode") diff --git a/flumi/Scripts/Utils/Lua/URL.gd.uid b/flumi/Scripts/Utils/Lua/URL.gd.uid new file mode 100644 index 0000000..d81298d --- /dev/null +++ b/flumi/Scripts/Utils/Lua/URL.gd.uid @@ -0,0 +1 @@ +uid://bjiiw0qfqg2he diff --git a/flumi/Scripts/main.gd b/flumi/Scripts/main.gd index 118a406..8cc1369 100644 --- a/flumi/Scripts/main.gd +++ b/flumi/Scripts/main.gd @@ -83,33 +83,78 @@ func _on_search_submitted(url: String) -> void: var tab = tab_container.tabs[tab_container.active_tab] tab.start_loading() - var result = await GurtProtocol.handle_gurt_domain(url) + var gurt_url = url + if not gurt_url.begins_with("gurt://"): + gurt_url = "gurt://" + gurt_url - if result.has("error"): - print("GURT domain error: ", result.error) - const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") - tab.stop_loading() - tab.set_icon(GLOBE_ICON) - return - - var html_bytes = result.html - - if result.has("display_url"): - current_domain = result.display_url - if not current_domain.begins_with("gurt://"): - current_domain = "gurt://" + current_domain - if not search_bar.has_focus(): - search_bar.text = result.display_url # Show clean version in search bar - else: - current_domain = url - - render_content(html_bytes) - - # Stop loading spinner after successful render - tab.stop_loading() + await fetch_gurt_content_async(gurt_url, tab, url) else: print("Non-GURT URL entered: ", url) +func fetch_gurt_content_async(gurt_url: String, tab: Tab, original_url: String) -> void: + var thread = Thread.new() + var request_data = {"gurt_url": gurt_url} + + thread.start(_perform_gurt_request_threaded.bind(request_data)) + + while thread.is_alive(): + await get_tree().process_frame + + var result = thread.wait_to_finish() + + _handle_gurt_result(result, tab, original_url, gurt_url) + +func _perform_gurt_request_threaded(request_data: Dictionary) -> Dictionary: + var gurt_url: String = request_data.gurt_url + var client = GurtProtocolClient.new() + + for ca_cert in CertificateManager.trusted_ca_certificates: + client.add_ca_certificate(ca_cert) + + if not client.create_client_with_dns(30, GurtProtocol.DNS_SERVER_IP, GurtProtocol.DNS_SERVER_PORT): + client.disconnect() + return {"success": false, "error": "Failed to connect to GURT DNS server"} + + var response = client.request(gurt_url, { + "method": "GET" + }) + client.disconnect() + + if not response or not response.is_success: + var error_msg = "Connection failed" + if response: + error_msg = "GURT %d: %s" % [response.status_code, response.status_message] + elif not response: + error_msg = "Request timed out or connection failed" + return {"success": false, "error": error_msg} + + return {"success": true, "html_bytes": response.body} + +func _handle_gurt_result(result: Dictionary, tab: Tab, original_url: String, gurt_url: String) -> void: + if not result.success: + print("GURT request failed: ", result.error) + handle_gurt_error(result.error, tab) + return + + var html_bytes = result.html_bytes + + current_domain = gurt_url + if not search_bar.has_focus(): + search_bar.text = original_url # Show the original input in search bar + + render_content(html_bytes) + + tab.stop_loading() + +func handle_gurt_error(error_message: String, tab: Tab) -> void: + var error_html = GurtProtocol.create_error_page(error_message) + + render_content(error_html) + + const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") + tab.stop_loading() + tab.set_icon(GLOBE_ICON) + func _on_search_focus_entered() -> void: if not current_domain.is_empty(): search_bar.text = current_domain @@ -298,7 +343,7 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) -> if is_grid_container: if element.tag_name == "div": - if BackgroundUtils.needs_background_wrapper(styles) or hover_styles.size() > 0: + if BackgroundUtils.needs_background_wrapper(styles) or BackgroundUtils.needs_background_wrapper(hover_styles): final_node = BackgroundUtils.create_panel_container_with_background(styles, hover_styles) var grid_container = GridContainer.new() grid_container.name = "Grid_" + element.tag_name @@ -316,21 +361,24 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) -> elif is_flex_container: # The element's primary identity IS a flex container. if element.tag_name == "div": - if BackgroundUtils.needs_background_wrapper(styles) or hover_styles.size() > 0: + if BackgroundUtils.needs_background_wrapper(styles) or BackgroundUtils.needs_background_wrapper(hover_styles): final_node = BackgroundUtils.create_panel_container_with_background(styles, hover_styles) var flex_container = AUTO_SIZING_FLEX_CONTAINER.new() flex_container.name = "Flex_" + element.tag_name var vbox = final_node.get_child(0) as VBoxContainer vbox.add_child(flex_container) container_for_children = flex_container + FlexUtils.apply_flex_container_properties(flex_container, styles) else: final_node = AUTO_SIZING_FLEX_CONTAINER.new() final_node.name = "Flex_" + element.tag_name container_for_children = final_node + FlexUtils.apply_flex_container_properties(final_node, styles) else: final_node = AUTO_SIZING_FLEX_CONTAINER.new() final_node.name = "Flex_" + element.tag_name container_for_children = final_node + FlexUtils.apply_flex_container_properties(final_node, styles) # For FLEX ul/ol elements, we need to create the li children directly in the flex container if element.tag_name == "ul" or element.tag_name == "ol": @@ -351,7 +399,8 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) -> # If the element itself has text (like TEXT) elif not element.text_content.is_empty(): var new_node = await create_element_node_internal(element, parser) - container_for_children.add_child(new_node) + if new_node: + container_for_children.add_child(new_node) # For flex divs, we're done - no additional node creation needed elif element.tag_name == "div": pass @@ -369,26 +418,6 @@ func create_element_node(element: HTMLParser.HTMLElement, parser: HTMLParser) -> # Applies background, size, etc. to the FlexContainer (top-level node) final_node = StyleManager.apply_element_styles(final_node, element, parser) - # Apply flex CONTAINER properties if it's a flex container - if is_flex_container: - var flex_container_node = final_node - - if final_node is FlexContainer: - # Direct FlexContainer - flex_container_node = final_node - elif final_node is MarginContainer and final_node.get_child_count() > 0: - var first_child = final_node.get_child(0) - if first_child is FlexContainer: - flex_container_node = first_child - elif final_node is PanelContainer and final_node.get_child_count() > 0: - var vbox = final_node.get_child(0) - if vbox is VBoxContainer and vbox.get_child_count() > 0: - var potential_flex = vbox.get_child(0) - if potential_flex is FlexContainer: - flex_container_node = potential_flex - - if flex_container_node is FlexContainer: - FlexUtils.apply_flex_container_properties(flex_container_node, styles) if is_grid_container: var grid_container_node = final_node @@ -528,7 +557,7 @@ func create_element_node_internal(element: HTMLParser.HTMLElement, parser: HTMLP return null # Create div container - if BackgroundUtils.needs_background_wrapper(styles) or hover_styles.size() > 0: + if BackgroundUtils.needs_background_wrapper(styles) or BackgroundUtils.needs_background_wrapper(hover_styles): node = BackgroundUtils.create_panel_container_with_background(styles, hover_styles) else: node = DIV.instantiate() diff --git a/flumi/addons/gurt-protocol/bin/windows/gurt_godot.dll b/flumi/addons/gurt-protocol/bin/windows/gurt_godot.dll index dad5170..5e1584f 100644 Binary files a/flumi/addons/gurt-protocol/bin/windows/gurt_godot.dll and b/flumi/addons/gurt-protocol/bin/windows/gurt_godot.dll differ diff --git a/flumi/addons/gurt-protocol/bin/windows/~gurt_godot.dll b/flumi/addons/gurt-protocol/bin/windows/~gurt_godot.dll new file mode 100644 index 0000000..5e1584f Binary files /dev/null and b/flumi/addons/gurt-protocol/bin/windows/~gurt_godot.dll differ diff --git a/protocol/cli/src/request_handler.rs b/protocol/cli/src/request_handler.rs index aee5681..abff72b 100644 --- a/protocol/cli/src/request_handler.rs +++ b/protocol/cli/src/request_handler.rs @@ -320,7 +320,13 @@ impl RequestHandler { } pub async fn handle_file_request(&self, request_path: &str) -> std::result::Result { - let mut relative_path = request_path.strip_prefix('/').unwrap_or(request_path).to_string(); + let path_without_query = if let Some(query_start) = request_path.find('?') { + &request_path[..query_start] + } else { + request_path + }; + + let mut relative_path = path_without_query.strip_prefix('/').unwrap_or(path_without_query).to_string(); while relative_path.starts_with('/') || relative_path.starts_with('\\') { relative_path = relative_path[1..].to_string(); diff --git a/protocol/gdextension/src/lib.rs b/protocol/gdextension/src/lib.rs index 742e06a..68f7ff6 100644 --- a/protocol/gdextension/src/lib.rs +++ b/protocol/gdextension/src/lib.rs @@ -131,6 +131,31 @@ impl GurtProtocolClient { true } + #[func] + fn create_client_with_dns(&mut self, timeout_seconds: i32, dns_ip: GString, dns_port: i32) -> bool { + let runtime = match Runtime::new() { + Ok(rt) => rt, + Err(e) => { + godot_print!("Failed to create runtime: {}", e); + return false; + } + }; + + let mut config = GurtClientConfig::default(); + config.request_timeout = tokio::time::Duration::from_secs(timeout_seconds as u64); + config.dns_server_ip = dns_ip.to_string(); + config.dns_server_port = dns_port as u16; + + config.custom_ca_certificates = self.ca_certificates.borrow().clone(); + + let client = GurtClient::with_config(config); + + *self.runtime.borrow_mut() = Some(runtime); + *self.client.borrow_mut() = Some(client); + + true + } + #[func] fn request(&self, url: GString, options: Dictionary) -> Option> { let runtime_binding = self.runtime.borrow(); @@ -162,7 +187,16 @@ impl GurtProtocolClient { }; let port = parsed_url.port().unwrap_or(4878); - let path = if parsed_url.path().is_empty() { "/" } else { parsed_url.path() }; + let path_with_query = if parsed_url.path().is_empty() { + "/" + } else { + parsed_url.path() + }; + + let path = match parsed_url.query() { + Some(query) => format!("{}?{}", path_with_query, query), + None => path_with_query.to_string(), + }; let method_str = options.get("method").unwrap_or("GET".to_variant()).to::(); let method = match method_str.to_uppercase().as_str() { @@ -192,7 +226,6 @@ impl GurtProtocolClient { let headers_dict = options.get("headers").unwrap_or(Dictionary::new().to_variant()).to::(); let mut request = GurtRequest::new(method, path.to_string()) - .with_header("Host", host) .with_header("User-Agent", "GURT-Client/1.0.0"); for key_variant in headers_dict.keys_array().iter_shared() { diff --git a/search-engine/Cargo.lock b/search-engine/Cargo.lock new file mode 100644 index 0000000..88e1eca --- /dev/null +++ b/search-engine/Cargo.lock @@ -0,0 +1,4407 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-lc-rs" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.9.3", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.106", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +dependencies = [ + "serde", +] + +[[package]] +name = "bitpacking" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1d3e2bfd8d06048a179f7b17afc3188effa10385e7b00dc65af6aae732ea92" +dependencies = [ + "crunchy", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "census" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 1.0.15", + "phf 0.11.3", + "smallvec", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.106", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.106", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ego-tree" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12a0bb14ac04a9fcf170d0bbbef949b44cc492f4452bd20c095636956f653642" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastdivide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs4" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e180ac76c23b45e767bd7ae9579bc0bb458618c4bc71835926e098e61d15f8" +dependencies = [ + "rustix 0.38.44", + "windows-sys 0.52.0", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getopts" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gurt" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "chrono", + "rustls 0.23.31", + "rustls-native-certs", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tracing", + "url", +] + +[[package]] +name = "gurted-search-engine" +version = "0.1.0" +dependencies = [ + "anyhow", + "base64 0.22.1", + "chrono", + "clap", + "futures", + "glob", + "gurt", + "lol_html", + "mime", + "regex", + "reqwest", + "scraper", + "serde", + "serde_json", + "sha2", + "sqlx", + "tantivy", + "thiserror", + "tokio", + "toml", + "tracing", + "tracing-subscriber", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "html5ever" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.15", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa 1.0.15", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.3", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "levenshtein_automata" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.3", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +dependencies = [ + "bitflags 2.9.3", + "libc", + "redox_syscall", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lol_html" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4629ff9c2deeb7aad9b2d0f379fc41937a02f3b739f007732c46af40339dee5" +dependencies = [ + "bitflags 2.9.3", + "cfg-if", + "cssparser 0.27.2", + "encoding_rs", + "hashbrown 0.13.2", + "lazy_static", + "lazycell", + "memchr", + "mime", + "selectors 0.22.0", + "thiserror", +] + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "lz4_flex" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen 0.11.3", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "measure_time" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbefd235b0aadd181626f281e1d684e116972988c14c264e42069d5e8a5775cc" +dependencies = [ + "instant", + "log", +] + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memmap2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +dependencies = [ + "libc", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "murmurhash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "oneshot" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce411919553d3f9fa53a0880544cda985a112117a0444d5ff1e870a893d6ea" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags 2.9.3", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "ownedbytes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a059efb063b8f425b948e042e6b9bd85edfe60e913630ed727b23e2dfcc558" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.106", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags 2.9.3", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rust-stemmers" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.3", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.9.3", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.103.4", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.3.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scraper" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90460b31bfe1fc07be8262e42c665ad97118d4585869de9345a84d501a9eaf0" +dependencies = [ + "ahash", + "cssparser 0.31.2", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors 0.25.0", + "tendril", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.3", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +dependencies = [ + "bitflags 2.9.3", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser 0.27.2", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc 0.1.1", + "smallvec", + "thin-slice", +] + +[[package]] +name = "selectors" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" +dependencies = [ + "bitflags 2.9.3", + "cssparser 0.31.2", + "derive_more", + "fxhash", + "log", + "new_debug_unreachable", + "phf 0.10.1", + "phf_codegen 0.10.0", + "precomputed-hash", + "servo_arc 0.3.0", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa 1.0.15", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.15", + "ryu", + "serde", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "servo_arc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" +dependencies = [ + "serde", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" +dependencies = [ + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +dependencies = [ + "dotenvy", + "either", + "heck 0.4.1", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.9.3", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa 1.0.15", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.9.3", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa 1.0.15", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tantivy" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96599ea6fccd844fc833fed21d2eecac2e6a7c1afd9e044057391d78b1feb141" +dependencies = [ + "aho-corasick", + "arc-swap", + "base64 0.22.1", + "bitpacking", + "byteorder", + "census", + "crc32fast", + "crossbeam-channel", + "downcast-rs", + "fastdivide", + "fnv", + "fs4", + "htmlescape", + "itertools", + "levenshtein_automata", + "log", + "lru", + "lz4_flex", + "measure_time", + "memmap2", + "num_cpus", + "once_cell", + "oneshot", + "rayon", + "regex", + "rust-stemmers", + "rustc-hash", + "serde", + "serde_json", + "sketches-ddsketch", + "smallvec", + "tantivy-bitpacker", + "tantivy-columnar", + "tantivy-common", + "tantivy-fst", + "tantivy-query-grammar", + "tantivy-stacker", + "tantivy-tokenizer-api", + "tempfile", + "thiserror", + "time", + "uuid", + "winapi", +] + +[[package]] +name = "tantivy-bitpacker" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284899c2325d6832203ac6ff5891b297fc5239c3dc754c5bc1977855b23c10df" +dependencies = [ + "bitpacking", +] + +[[package]] +name = "tantivy-columnar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" +dependencies = [ + "downcast-rs", + "fastdivide", + "itertools", + "serde", + "tantivy-bitpacker", + "tantivy-common", + "tantivy-sstable", + "tantivy-stacker", +] + +[[package]] +name = "tantivy-common" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8019e3cabcfd20a1380b491e13ff42f57bb38bf97c3d5fa5c07e50816e0621f4" +dependencies = [ + "async-trait", + "byteorder", + "ownedbytes", + "serde", + "time", +] + +[[package]] +name = "tantivy-fst" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" +dependencies = [ + "byteorder", + "regex-syntax 0.8.5", + "utf8-ranges", +] + +[[package]] +name = "tantivy-query-grammar" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847434d4af57b32e309f4ab1b4f1707a6c566656264caa427ff4285c4d9d0b82" +dependencies = [ + "nom", +] + +[[package]] +name = "tantivy-sstable" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c69578242e8e9fc989119f522ba5b49a38ac20f576fc778035b96cc94f41f98e" +dependencies = [ + "tantivy-bitpacker", + "tantivy-common", + "tantivy-fst", + "zstd", +] + +[[package]] +name = "tantivy-stacker" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56d6ff5591fc332739b3ce7035b57995a3ce29a93ffd6012660e0949c956ea8" +dependencies = [ + "murmurhash32", + "rand_distr", + "tantivy-common", +] + +[[package]] +name = "tantivy-tokenizer-api" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0dcade25819a89cfe6f17d932c9cedff11989936bf6dd4f336d50392053b04" +dependencies = [ + "serde", +] + +[[package]] +name = "tempfile" +version = "3.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.8", + "windows-sys 0.60.2", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa 1.0.15", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2 0.6.0", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls 0.23.31", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.3", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/search-engine/Cargo.toml b/search-engine/Cargo.toml new file mode 100644 index 0000000..50fc97f --- /dev/null +++ b/search-engine/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "gurted-search-engine" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.38.0", features = ["full"] } +futures = "0.3.30" +tantivy = "0.22" +sha2 = "0.10" +gurt = { path = "../protocol/library" } +sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "chrono", "uuid"] } +scraper = "0.20" +lol_html = "1.2" +url = "2.5" +toml = "0.8.13" +serde = { version = "1.0.203", features = ["derive"] } +serde_json = "1.0" +chrono = { version = "0.4", features = ["serde"] } +anyhow = "1.0.86" +thiserror = "1.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +uuid = { version = "1.0", features = ["v4"] } +regex = "1.10.4" +mime = "0.3" +base64 = "0.22" +glob = "0.3" +clap = { version = "4.5.4", features = ["derive"] } +urlencoding = "2.1" +reqwest = "0.11" diff --git a/search-engine/README.md b/search-engine/README.md new file mode 100644 index 0000000..80a5952 --- /dev/null +++ b/search-engine/README.md @@ -0,0 +1,5 @@ +The official Gurted search engine, Ringle. + +Copy `config.template.toml` to `config.toml` and edit as needed. + +Run with `cargo run` diff --git a/search-engine/config.template.toml b/search-engine/config.template.toml new file mode 100644 index 0000000..ec65c6c --- /dev/null +++ b/search-engine/config.template.toml @@ -0,0 +1,51 @@ +[database] +url = "postgres://..." +max_connections = 5 + +[server] +address = "127.0.0.1" +port = 4879 +cert_path = "certs/t.crt" +key_path = "certs/t.key" + +[search] +index_path = "./search_indexes" +crawl_interval_hours = 2 +max_pages_per_domain = 1000 +crawler_timeout_seconds = 30 +crawler_user_agent = "GurtedSearchBot/1.0" +max_concurrent_crawls = 5 +content_size_limit_mb = 10 +index_rebuild_interval_hours = 48 +search_results_per_page = 20 +max_search_results = 1000 + +allowed_extensions = [ + "html", "htm", "txt", "md", "json", "xml", "rss", "atom" +] + +blocked_extensions = [ + "exe", "zip", "rar", "tar", "gz", "7z", "iso", "dmg", + "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", + "jpg", "jpeg", "png", "gif", "bmp", "svg", "webp", + "mp3", "mp4", "avi", "mov", "wmv", "flv", "webm", + "css", "js", "woff", "woff2", "ttf", "eot" +] + +[crawler] +clanker_txt = true +crawl_delay_ms = 1000 +max_redirects = 5 +follow_external_links = false +max_depth = 10 + +request_headers = [ + ["Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"], + ["Accept-Language", "en-US,en;q=0.5"], + ["Accept-Encoding", "gzip, deflate"], + ["DNT", "1"], +] + +[logging] +level = "info" +format = "compact" \ No newline at end of file diff --git a/search-engine/frontend/search.html b/search-engine/frontend/search.html new file mode 100644 index 0000000..b3b1994 --- /dev/null +++ b/search-engine/frontend/search.html @@ -0,0 +1,96 @@ + + Gurted Search Engine + + + + + + +