Files
ewwii/docs/book/modules/stdlib.html
2025-08-25 17:56:01 +05:30

492 lines
25 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE HTML>
<html lang="en" class="latte sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Std Library - Ewwii documentation</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href=".././theme/catppuccin.css">
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../";
const default_light_theme = "latte";
const default_dark_theme = "macchiato";
window.path_to_searchindex_js = "../searchindex.js";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('latte')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
sidebar_toggle.checked = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="latte">Latte</button></li>
<li role="none"><button role="menuitem" class="theme" id="frappe">Frappé</button></li>
<li role="none"><button role="menuitem" class="theme" id="macchiato">Macchiato</button></li>
<li role="none"><button role="menuitem" class="theme" id="mocha">Mocha</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Ewwii documentation</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/Ewwii-sh/ewwii" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="standard-library"><a class="header" href="#standard-library">Standard Library</a></h1>
<h2 id="stdenv"><a class="header" href="#stdenv"><code>std::env</code></a></h2>
<p>The <code>std::env</code> module provides access to common system-level environment queries. It is supported on Unix-based systems (Linux, macOS).</p>
<h3 id="usage"><a class="header" href="#usage">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::env" as env;
// Get an environment variable, or fallback to a default
let shell = env::get_env("SHELL") ?? "unknown";
// Set an environment variable (current process only)
env::set_env("DEBUG_MODE", "true");
// Get the user's home directory
let home = env::get_home_dir() ?? "/home/user";
// Get the current working directory
let cwd = env::get_current_dir() ?? "/";
// Get the current username
let user = env::get_username() ?? "nobody";</code></pre>
<h3 id="functions"><a class="header" href="#functions">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>get_env</code></td><td>Gets an environment variable's value</td></tr>
<tr><td><code>set_env</code></td><td>Sets an environment variable (current process only)</td></tr>
<tr><td><code>get_home_dir</code></td><td>Returns the current user's home directory path if found</td></tr>
<tr><td><code>get_current_dir</code></td><td>Returns the current working directory</td></tr>
<tr><td><code>get_username</code></td><td>Gets the current user's username from <code>$USER</code></td></tr>
</tbody></table>
</div>
<h2 id="stdtext"><a class="header" href="#stdtext"><code>std::text</code></a></h2>
<p>The <code>std::text</code> module provides access to more string manipulation that Rhai lacks.</p>
<h3 id="usage-1"><a class="header" href="#usage-1">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::text" as text;
// Convert a string to a URL-friendly slug
let slug = text::to_slug("Ewwii is cool!"); // output: "ewwii-is-cool"
// Convert a string to camelCase
let camel = text::to_camel_case("my cool project"); // output: "myCoolProject"
// Truncate a string to N characters (without splitting in the middle of a character)
let short = text::truncate_chars("hello world", 5); // output: "hello"
// Convert a string to uppercase
let upper = text::to_upper("hello"); // output: "HELLO"
// Convert a string to lowercase
let lower = text::to_lower("HELLO"); // output: "hello"</code></pre>
<h3 id="functions-1"><a class="header" href="#functions-1">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>to_slug</code></td><td>Converts a string into a lowercase, hyphen-separated slug</td></tr>
<tr><td><code>to_camel_case</code></td><td>Converts a string into camelCase, removing non-alphanumeric characters</td></tr>
<tr><td><code>truncate_chars</code></td><td>Truncates a string to a maximum number of characters (UTF-8 safe)</td></tr>
<tr><td><code>to_upper</code></td><td>Converts a string to uppercase</td></tr>
<tr><td><code>to_lower</code></td><td>Converts a string to lowercase</td></tr>
</tbody></table>
</div>
<h2 id="stdmonitor"><a class="header" href="#stdmonitor"><code>std::monitor</code></a></h2>
<p>The <code>std::monitor</code> module provides utilities for querying information about connected monitors, including their resolution, dimensions, and DPI.</p>
<h3 id="usage-2"><a class="header" href="#usage-2">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::monitor" as monitor;
// Get number of monitors
let count = monitor::count(); // e.g., 2
// Get resolution of the primary monitor
let (w, h) = monitor::primary_resolution();
let res_str = monitor::primary_resolution_str(); // e.g., "1920x1080"
// Get resolutions of all monitors
let all_res = monitor::all_resolutions();
let all_res_str = monitor::all_resolutions_str(); // e.g., "1920x1080, 1280x1024"
// Get dimensions of a specific monitor
let (x, y, w, h) = monitor::dimensions(0);
let dim_str = monitor::dimensions_str(0); // e.g., "1920x1080"
// Get DPI of a monitor
let dpi = monitor::dpi(0);
let dpi_str = monitor::dpi_str(0); // e.g., "96.0"</code></pre>
<h3 id="functions-2"><a class="header" href="#functions-2">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>count()</code></td><td>Returns the number of connected monitors.</td></tr>
<tr><td><code>primary_resolution()</code></td><td>Returns the width and height of the primary monitor as a tuple <code>(width, height)</code>.</td></tr>
<tr><td><code>primary_resolution_str()</code></td><td>Returns the primary monitor resolution as a string in the format <code>"WIDTHxHEIGHT"</code>.</td></tr>
<tr><td><code>all_resolutions()</code></td><td>Returns a vector of <code>(width, height)</code> tuples for all connected monitors.</td></tr>
<tr><td><code>all_resolutions_str()</code></td><td>Returns a comma-separated string of all monitor resolutions in <code>"WIDTHxHEIGHT"</code> format.</td></tr>
<tr><td><code>dimensions(index)</code></td><td>Returns <code>(x, y, width, height)</code> for the monitor at the given index.</td></tr>
<tr><td><code>dimensions_str(index)</code></td><td>Returns the dimensions of the monitor at the given index as a formatted string <code>"x,y - WxH"</code>.</td></tr>
<tr><td><code>dpi(index)</code></td><td>Returns the DPI (dots per inch) of the monitor at the given index, accounting for scaling.</td></tr>
<tr><td><code>dpi_str(index)</code></td><td>Returns the DPI as a formatted string with one decimal place, e.g., <code>"96.0"</code>.</td></tr>
</tbody></table>
</div>
<h3 id="notes"><a class="header" href="#notes">Notes</a></h3>
<ul>
<li>Monitor indices are zero-based: the primary monitor is index 0.</li>
<li>DPI calculation assumes a base of 96 DPI multiplied by the monitors scale factor.</li>
<li>The module automatically initializes GTK if it hasnt been initialized on the main thread.</li>
</ul>
<h2 id="stdjson"><a class="header" href="#stdjson"><code>std::json</code></a></h2>
<p>The <code>std::json</code> module provides utilities for working with JSON data within Rhai scripts. It allows parsing, serializing, and manipulating JSON objects dynamically.</p>
<h3 id="usage-3"><a class="header" href="#usage-3">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::json" as json;
// Parse a JSON string
let json_val = json::parse_json(r#"{"name":"Alice","age":30}"#);
// Convert JSON back to string
let json_str = json::to_string(json_val);
// Get a value from a JSON object
let name = json::get(json_val, "name"); // "Alice"
// Set a value in a JSON object
json::set(json_val, "age", 31);</code></pre>
<h3 id="functions-3"><a class="header" href="#functions-3">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>parse_json()</code></td><td>Parses a JSON string into a Rhai <code>Dynamic</code> representing a <code>serde_json::Value</code>. Returns an error if parsing fails.</td></tr>
<tr><td><code>to_string()</code></td><td>Serializes a <code>Dynamic</code> JSON value back into a JSON string.</td></tr>
<tr><td><code>get()</code></td><td>Retrieves a value by key from a JSON object. Returns <code>()</code> if the key does not exist.</td></tr>
<tr><td><code>set()</code></td><td>Sets a key-value pair in a JSON object. Returns an error if the value is not a JSON object.</td></tr>
</tbody></table>
</div>
<h3 id="notes-1"><a class="header" href="#notes-1">Notes</a></h3>
<ul>
<li>All JSON values are represented as Rhai <code>Dynamic</code> objects internally.</li>
<li>Keys that do not exist in a JSON object return a <code>UNIT</code> value.</li>
<li><code>set()</code> only works on JSON objects; trying to set a key on a non-object JSON value will produce an error.</li>
<li>Parsing and serialization errors are returned as Rhai <code>EvalAltResult</code> errors.</li>
</ul>
<h2 id="stdmath"><a class="header" href="#stdmath"><code>std::math</code></a></h2>
<p>The <code>std::math</code> module provides a collection of mathematical constants and functions.
It includes basic arithmetic, trigonometry, exponentiation, logarithms, and utility functions.</p>
<h3 id="usage-4"><a class="header" href="#usage-4">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::math" as math;
// Constants
print(math::PI); // 3.14159...
print(math::E); // 2.71828...
print(math::TAU); // 6.28318...
// Basic math
let x = math::abs(-42.0); // 42
let y = math::sqrt(9.0); // 3
let z = math::pow(2.0, 10.0); // 1024
// Trigonometry
let s = math::sin(math::PI / 2); // ~1
let c = math::cos(0.0); // 1
let t = math::tan(math::PI / 4); // ~1
// Exponentials &amp; logs
let e = math::exp(1.0); // ~2.718
let l = math::ln(math::E); // 1
let l10 = math::log10(100.0); // 2
let l2 = math::log(2.0, 8.0); // 3
// Inverse trig
let a = math::asin(1.0); // PI/2
let b = math::acos(0.0); // PI/2
let c = math::atan(1.0); // PI/4
let d = math::atan2(1.0, 1.0); // PI/4
// Hyperbolic
let sh = math::sinh(1.0);
let ch = math::cosh(1.0);
let th = math::tanh(1.0);
// Utilities
let f = math::floor(3.7); // 3
let r = math::round(3.5); // 4
let m = math::min(10.0, 20.0); // 10
let M = math::max(10.0, 20.0); // 20
let cl = math::clamp(15.0, 0.0, 10.0); // 10
// Other Utilities
let tof = math::to_float(42); // 42 -&gt; 42.0
let toi = math::to_int(3.14); // truncates toward zero -&gt; 3
// NOTE: to_int does NOT round!
// If you want nearest integer, use: to_int(math::round(3.14))</code></pre>
<h3 id="constants"><a class="header" href="#constants">Constants</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Constant</th><th>Value</th><th>Description</th></tr></thead><tbody>
<tr><td><code>PI</code></td><td>3.14159…</td><td>Circle ratio π</td></tr>
<tr><td><code>E</code></td><td>2.71828…</td><td>Eulers number</td></tr>
<tr><td><code>TAU</code></td><td>6.28318…</td><td>Full circle (2π)</td></tr>
</tbody></table>
</div>
<h3 id="functions-4"><a class="header" href="#functions-4">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>abs(x)</code></td><td>Absolute value of <code>x</code></td></tr>
<tr><td><code>sqrt(x)</code></td><td>Square root of <code>x</code></td></tr>
<tr><td><code>pow(base, exp)</code></td><td>Base raised to power of exponent</td></tr>
<tr><td><code>sin(x)</code></td><td>Sine of <code>x</code> (radians)</td></tr>
<tr><td><code>cos(x)</code></td><td>Cosine of <code>x</code> (radians)</td></tr>
<tr><td><code>tan(x)</code></td><td>Tangent of <code>x</code> (radians)</td></tr>
<tr><td><code>exp(x)</code></td><td>e raised to the power <code>x</code></td></tr>
<tr><td><code>ln(x)</code></td><td>Natural log of <code>x</code></td></tr>
<tr><td><code>log10(x)</code></td><td>Base-10 log of <code>x</code></td></tr>
<tr><td><code>log(base, x)</code></td><td>Log of <code>x</code> in <code>base</code></td></tr>
<tr><td><code>asin(x)</code></td><td>Inverse sine</td></tr>
<tr><td><code>acos(x)</code></td><td>Inverse cosine</td></tr>
<tr><td><code>atan(x)</code></td><td>Inverse tangent</td></tr>
<tr><td><code>atan2(y, x)</code></td><td>Arctangent of <code>y/x</code> considering quadrant</td></tr>
<tr><td><code>sinh(x)</code></td><td>Hyperbolic sine</td></tr>
<tr><td><code>cosh(x)</code></td><td>Hyperbolic cosine</td></tr>
<tr><td><code>tanh(x)</code></td><td>Hyperbolic tangent</td></tr>
<tr><td><code>floor(x)</code></td><td>Round down</td></tr>
<tr><td><code>ceil(x)</code></td><td>Round up</td></tr>
<tr><td><code>round(x)</code></td><td>Round to nearest</td></tr>
<tr><td><code>trunc(x)</code></td><td>Round toward zero</td></tr>
<tr><td><code>fract(x)</code></td><td>Fractional part</td></tr>
<tr><td><code>min(a, b)</code></td><td>Smaller of two values</td></tr>
<tr><td><code>max(a, b)</code></td><td>Larger of two values</td></tr>
<tr><td><code>clamp(x, min, max)</code></td><td>Clamp <code>x</code> into <code>[min, max]</code></td></tr>
<tr><td><code>to_float</code></td><td>Convert an integer or float into a floating-point</td></tr>
<tr><td><code>to_int</code></td><td>Convert an integer or float into an integer</td></tr>
</tbody></table>
</div>
<h3 id="note"><a class="header" href="#note">Note</a></h3>
<p>All functions in this module work with floating-point numbers (f64).</p>
<p>If you pass an integer (e.g. <code>0</code>), Rhai will report an error because there is no math::cos(i64). Use a floating-point literal instead (e.g. <code>0.0</code>).</p>
<p>All math functions return <code>f64</code>. If you need an integer result, use <code>to_int</code> to convert.</p>
<h2 id="stdcommand"><a class="header" href="#stdcommand"><code>std::command</code></a></h2>
<p>The <code>std::command</code> module provides functions which you can use to run shell commands on your system.</p>
<h3 id="usage-5"><a class="header" href="#usage-5">Usage</a></h3>
<pre><code class="language-rust ignore">import "std::command" as command;
// run a command
command::run("notify-send Hello!");
// run a command and read output from stdout
let output = command::run_and_read("pwd"); // example output: /home/foo/.config/ewwii/</code></pre>
<h3 id="functions-5"><a class="header" href="#functions-5">Functions</a></h3>
<div class="table-wrapper"><table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody>
<tr><td><code>run(x)</code></td><td>Run the shell command in <code>x</code></td></tr>
<tr><td><code>run_and_read(x)</code></td><td>Run the shell command in <code>x</code> and return the stdout</td></tr>
</tbody></table>
</div>
<h3 id="note-1"><a class="header" href="#note-1">Note</a></h3>
<p>The functions in <code>std::command</code> execute arbitrary shell commands. Only run scripts you trust, as misuse can compromise your system.</p>
<p>This, along with features like <code>poll</code>, <code>listen</code>, <code>onclick</code>, <code>onhover</code>, etc., which also run shell commands, can be abused by bad actors. Always verify and trust a package before installing it via <a href="https://github.com/Ewwii-sh/eiipm">eiipm</a>. Even if a package is registered in <a href="https://github.com/Ewwii-sh/eii-manifests">eii-manifests</a>, bad actors could change the code of their package without the awareness of maintainers.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../modules/user_defined.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../modules/apilib.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../modules/user_defined.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../modules/apilib.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<!-- Livereload script (if served using the cli tool) -->
<script>
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
</script>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
<script src="../js/home_button.js"></script>
</div>
</body>
</html>