{"id":15556911,"url":"https://github.com/icholy/uzi","last_synced_at":"2026-02-01T23:03:59.565Z","repository":{"id":57389598,"uuid":"66224222","full_name":"icholy/uzi","owner":"icholy","description":"WIP: API and syntax in heavy flux.","archived":false,"fork":false,"pushed_at":"2017-05-23T20:57:23.000Z","size":376,"stargazers_count":0,"open_issues_count":9,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-09T01:37:30.241Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icholy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-21T22:47:46.000Z","updated_at":"2016-11-02T20:03:05.000Z","dependencies_parsed_at":"2022-09-09T22:03:42.326Z","dependency_job_id":null,"html_url":"https://github.com/icholy/uzi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/icholy/uzi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fuzi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fuzi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fuzi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fuzi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icholy","download_url":"https://codeload.github.com/icholy/uzi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icholy%2Fuzi/sbom","scorecard":{"id":480329,"data":{"date":"2025-08-11","repo":{"name":"github.com/icholy/uzi","commit":"63ecfc07c510ac9f67268e73b4e07dff33485df2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-19T16:26:29.276Z","repository_id":57389598,"created_at":"2025-08-19T16:26:29.276Z","updated_at":"2025-08-19T16:26:29.276Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28993784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T22:01:47.507Z","status":"ssl_error","status_checked_at":"2026-02-01T21:58:37.335Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T15:15:16.435Z","updated_at":"2026-02-01T23:03:59.547Z","avatar_url":"https://github.com/icholy.png","language":"TypeScript","readme":"![](uzi.png)\n\n\u003e An Element positioning system inspired by SICP's \"Propagation of Constraints\".\n\n# Quick Start\n\n``` sh\nnpm install\npython -mSimpleHTTPServer\n```\n\nBrowse the `/examples` directory.\n\n# Feature Overview\n\n``` html\n\u003cdiv uz-rect id=\"A\"\u003e\u003c/div\u003e\n\u003cdiv uz-rect id=\"B\"\u003e\u003c/div\u003e\n```\n\n### Constrain properties of an element.\n\n``` sass\n#B {\n\n  //  Anchor elements to eachother\n  left: A.right;\n\n  // Center in another element.\n  center-in: A;\n\n  // Basic expressions can be used.\n  right: A.right + B.width / 2;\n}\n\n// Classes are supported\n.class-name {\n  height: B.width / A.height;\n}\n```\n\n### Interface with JavaScript.\n\n``` js\n\n// assign variables\nengine.assign(\"x\", 100);\n\n// add user defined functions\nengine.func(\"fooBar\", () =\u003e 200);\nengine.funcs(Math, \"Math\");\n```\n\n``` sass\n#B {\n\n  // using variable\n  height: x * A.height;\n\n  // using user defined functions\n  width: C.height - Math.min(A.height, fooBar());\n  left:  B.right + Math.sin(x) * 100px;\n}\n```\n\n### Declare rules inline.\n\n``` html\n\u003cdiv uz-rect id=\"A\"\u003e\u003c/div\u003e\n\u003cdiv uz-style=\"width: A.height * 3\"\u003e\u003c/div\u003e\n```\n\n# Rule Attributes\n\n* `left`\n* `right`\n* `top`\n* `bottom`\n* `width`\n* `height`\n* `center-x`\n* `center-y`\n* `center-in`\n* `relative-to`\n* `align-x`\n* `align-y`\n* `size`\n* `watch`\n\n# Element Attributes\n\n* `uz-rect`\n* `uz-style`\n\n# Special Rects\n\n* `viewport`\n* `body`\n* `document`\n\nThese can be used like any other rect in the system.\n\n``` sass\n#item {\n  center-x: viewport.center-x;\n  top: 10px;\n}\n```\n\nNote: user's can create custom rects by extending the `Rect` `class`.\n\n# Setup\n\nThe `Engine` `class` is how the user interacts with the system.\n\n``` ts\nlet engine = new uzi.Engine();\n\n// assign variables and attach functions\n\nengine.initialize(/* options */);\n```\n\nBy default, the engine will walk the entire DOM and mount Elements which have an \n`uz-rect` or `uz-style` attribute.  This behaviour is configured via an options object passed \ninto the `Engine#initialize` method.\n\n``` ts\ninterface EngineOptions {\n\n  // Find and parse script tags where type=\"text/uzi\"\n  findStyleSheets?: boolean;\n\n  // Walk the dom and find elements with `uz-rect` or `uz-style` attributes.\n  findElements?: boolean;\n\n  // Use the selectors in the stylesheets to lookup elements in the dom.\n  lookupSelectors?: boolean;\n\n  // Provide pre-compiled rules to the env.\n  envData?: EnvData;\n}\n```\n\nDefault Engine Options:\n\n``` ts\n{\n  findStyleSheets: true,\n  findElements:    true\n}\n```\n\n## Manually managing Element life-cycle\n\nElement life-cycles can be manually managed using the `Engine#mount` and `Engine#unmount` methods.\n\n``` ts\n// start managing the element.\nengine.mount(element);\n\n// stop managing the element.\nengine.unmount(element);\n```\n\n## Pre-Compiling\n\n\u003e This is still a work in progress.\n\nA cache of all source to compiled rules is kept during runtime. If you export this\ndata, and initialize uzi with it, the parser doesn't need to be sent\nto the client.\n\n**Export:**\n``` ts\nlet envData = engine.getEnv().getExportData();\n```\n\n**Import:**\n``` ts\nlet engine = new uzi.Engine({ envData });\n```\n\n\n# Angular Integration\n\nAngular integration lets you use functions and variables from the `$scope` in your rules.\n\n``` html\n\u003cdiv uz-rect\n     uz-style=\"width: 100px * $index\"\n     ng-repeat=\"foo in foos\"\u003e\n\u003c/div\u003e\n```\n\n# Debugging:\n\nThe simplest way to debug is to use the `System` `class`.\n\n``` ts\nwindow.system = engine.getSystem();\n```\n\nThe `System#toString()` method will show all relationships. `toString` takes an\noptional string parameters which is used to filter the resulting lines.\n\n\nThere is also a `System#$` property which uses a `Proxy` to provide access to\nthe underlying variables with support for tab completion.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficholy%2Fuzi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficholy%2Fuzi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficholy%2Fuzi/lists"}