pax_global_header00006660000000000000000000000064151030756350014517gustar00rootroot0000000000000052 comment=fbf4bca9bc6f506c5e70b4f32a7fcb228e81e5c6 Mylas-2.1.14/000077500000000000000000000000001510307563500126715ustar00rootroot00000000000000Mylas-2.1.14/.github/000077500000000000000000000000001510307563500142315ustar00rootroot00000000000000Mylas-2.1.14/.github/CODEOWNERS000066400000000000000000000000241510307563500156200ustar00rootroot00000000000000* @raouldeheerMylas-2.1.14/.github/CODE_OF_CONDUCT.md000066400000000000000000000064231510307563500170350ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at info@domipas.nl. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq Mylas-2.1.14/.github/CONTRIBUTING.md000066400000000000000000000053761510307563500164750ustar00rootroot00000000000000# Contributing A big welcome and thank you for considering contributing to Mylas. Reading and following these guidelines will help us make the contribution process easy and effective for everyone involved. It also communicates that you agree to respect the time of the developers managing and developing the open source project. In return, we will reciprocate that respect by addressing your issue, assessing changes, and helping you finalize your pull requests. ## Quicklinks * [Code of Conduct](#code-of-conduct) * [Getting Started](#getting-started) * [Issues](#issues) * [Pull Requests](#pull-requests) ## Code of Conduct We take the open source community seriously and hold ourselves and other contributors to high standards of communication. By participating and contributing to this project, you agree to uphold our [Code of Conduct](https://github.com/raouldeheer/Mylas/blob/main/.github/CODE_OF_CONDUCT.md). ## Getting Started Contributions are made to this repo via Issues and Pull Requests (PRs). A few general guidelines that cover both: - To report security vulnerabilities, please follow our [security policy](https://github.com/raouldeheer/Mylas/security/policy). - Search for existing Issues and PRs before creating your own. - We work hard to makes sure issues are handled in a timely manner but, depending on the impact, it could take a while to investigate the root cause. A friendly ping in the comment thread to the submitter or a contributor can help draw attention if your issue is blocking. ### Issues Issues should be used to report problems with the software, request a new feature, or to discuss potential changes before a PR is created. When you create a new Issue, a template will be loaded that will guide you through collecting and providing the information we need to investigate. If you find an Issue that addresses the problem you're having, please add your own reproduction information to the existing issue rather than creating a new one. ### Pull Requests PRs to our software is always welcome and can be a quick way to get your fix or improvement slated for the next release. In general, PRs should: - Only fix/add the functionality in question **OR** address wide-spread whitespace/style issues, not both. - Add unit or integration tests for fixed or changed functionality (if a test suite already exists). - Address a single concern in the least number of changed lines as possible. - Include documentation in the repo. - Be accompanied by a complete Pull Request template (loaded automatically when a PR is created). For changes that address core functionality or would require breaking changes (e.g. a major release), it's best to open an Issue to discuss your proposal first. This is not required but can save time creating and reviewing changes. Mylas-2.1.14/.github/EXAMPLES.md000066400000000000000000000030221510307563500157660ustar00rootroot00000000000000## Examples Synchronous functions: ```ts const Mylas = require("mylas"); //Save string to file Mylas.saveS("./text.txt", "Hello world!"); //Load string from file const loadedData = Mylas.loadS("./text.txt"); //Save JSON to file JSON.saveS("./text.json", [{test: "Hello world"}]); //Load JSON from file const loadedJSON = JSON.loadS("./text.json"); //Load JSON from file with comments const loadedJSON = JSON.loadS("./text.json", true); ``` ASync, Promises & Callback: ```ts const Mylas = require("mylas"); //Save string to file async await Mylas.save("./text.txt", "Hello world!", () => {console.log("Saved!")}); //Load string from file async const loadedData = await Mylas.load("./text.txt", (data) => {console.log(`Loaded: ${data}`)}); //Save JSON to file async await JSON.save("./text.json", [{test: "Hello world"}], () => {console.log("Saved!")}); //Load JSON from file async const loadedJSON = await JSON.load("./text.json", (data) => {console.log(`Loaded: ${data}`)}); ``` Multithreaded / Worker: ```ts const Mylas = require("mylas"); //Save string to file with worker await Mylas.saveW("./text.txt", "Hello world!", () => {console.log("Saved!")}); //Load string from file with worker const loadedData = await Mylas.loadW("./text.txt", (data) => {console.log(`Loaded: ${data}`)}); //Save JSON to file with worker await JSON.saveW("./text.json", [{test: "Hello world"}], () => {console.log("Saved!")}); //Load JSON from file with worker const loadedJSON = await JSON.loadW("./text.json", (data) => {console.log(`Loaded: ${data}`)}); ```Mylas-2.1.14/.github/FEATURES.md000066400000000000000000000036121510307563500157730ustar00rootroot00000000000000## Features ### File - Mylas.load: Loads file from fs returns a string promise and calls callback. (async) - Mylas.loadW: Loads file from fs returns a string promise and calls callback. (multithreaded/worker) - Mylas.loadS: Loads file from fs returns a string. (sync) - Mylas.save: Saves file to fs returns void promise and calls callback. (async) - Mylas.saveW: Saves file to fs returns void promise and calls callback. (multithreaded/worker) - Mylas.saveS: Saves file to fs returns void. (sync) Import Mylas: Mylas.file.* functions above. Import { File }: File.* functions above. String.* functions above. ### Json - JSON.load: Loads JSON from fs returns json promise and calls callback. (async) - JSON.loadW: Loads JSON from fs returns json promise and calls callback. (multithreaded/worker) - JSON.loadS: Loads JSON from fs returns json. (sync) - JSON.save: Saves JSON to fs returns void promise and calls callback. (async) - JSON.saveW: Saves JSON to fs returns void promise and calls callback. (multithreaded/worker) - JSON.savesS: Saves JSON to fs returns void. (sync) Import Mylas: Mylas.json.* functions above. Import { Json }: Json.* functions above. ### Dir - Mylas.dir.mk: Makes dir in fs returns void promise and calls callback. (async) - Mylas.dir.mkS: Makes dir in fs returns void. (sync) - Mylas.dir.rm: Removes dir in fs returns void promise and calls callback. (async) - Mylas.dir.rmS: Removes dir in fs returns void. (sync) - Mylas.dir.check: Checks if dir exists in fs returns boolean promise or call callback. (async) - Mylas.dir.checkS: Checks if dir exists in fs returns boolean. (sync) Import { Dir }: Dir.* functions above. ### Buf - Mylas.buf.loadW Loads file from fs returns a buffer promise and calls callback. (multithreaded/worker) - Mylas.buf.saveW Saves buffer to file returns void promise and calls callback. (multithreaded/worker) Import { Buf }: Buf.* functions above. Mylas-2.1.14/.github/FUNDING.yml000066400000000000000000000001051510307563500160420ustar00rootroot00000000000000# These are supported funding model platforms github: [raouldeheer] Mylas-2.1.14/.github/ISSUE_TEMPLATE/000077500000000000000000000000001510307563500164145ustar00rootroot00000000000000Mylas-2.1.14/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000012321510307563500211040ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. Mylas-2.1.14/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000011341510307563500221400ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: enhancement assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. Mylas-2.1.14/.github/SECURITY.md000066400000000000000000000012071510307563500160220ustar00rootroot00000000000000# Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 2.1.14 | :white_check_mark: | | 2.1.13 | :white_check_mark: | | <2.1.12 | :x: | ## Supported Node Versions | Version | Supported | | ------- | ------------------ | | 24 | :white_check_mark: | | 22 | :white_check_mark: | | 20 | :white_check_mark: | | 18 | :white_check_mark: | | 16 | :white_check_mark: | | 14 | :white_check_mark: | | 12 | :white_check_mark: | | < 10 | :x: | ## Reporting a Vulnerability To report a Vulnerability open a issue on Github. Mylas-2.1.14/.github/dependabot.yml000066400000000000000000000005561510307563500170670ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "daily" commit-message: prefix: "🔼" reviewers: - "raouldeheer" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" commit-message: prefix: "🔼" reviewers: - "raouldeheer" Mylas-2.1.14/.github/labeler.yml000066400000000000000000000001301510307563500163540ustar00rootroot00000000000000repo: - ./* source: - ts/**/* testing: - tests/**/* github: - .github/*Mylas-2.1.14/.github/logo.png000066400000000000000000002146701510307563500157110ustar00rootroot00000000000000PNG  IHDR8CtEXtSoftwareAdobe ImageReadyqe<#iTXtXML:com.adobe.xmp j+IDATxtaG^MKf LNБ֔AMnImIGzHRNGz}C Iۤm! ^x`B-Y, _9ϑWIRM 0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@!B  0@ `@5D<%>&&&&rGׯݱpǑOMMeSxhr2^WT|*-siSg&~<'9RoSoh/D))Q<&S)djJXYEgs2>oCM}ŧ.((3 ,)SSSV H#ice# 迎 tllӆG/ ~]+V\g @8`fݻÅCG87lhp$>MLN&sKxy\b 8i-yӆJ f_`9Tm{{{o"m۲eo?{~^~v5`ޡwuw=tŧy#o̱qw#Gn5`N]]?}aç'v_ृ#sGǢ;񨻫 q7:2600\u|}WMޯu\xOZKxm co(ۻ8tg@`{@H`޴#\{`>@CGjF.!8jùY9|^vw}:pJ#c:*ڿơX(=:mOÇz/ Ӗ S;ٳ`KkK{m뮃?c`Ylpp$45W?7tf(`IF:olq6>Ի`xhOFtݰ}kze ,e ,0@~ro}eǾ5t/@`>o5ۻf  zw׾_lqsccFYHr[[oټi|p0ˉ3̞֎%[ۖMۻ'>c Iz^q/mUвswF `zm[ںyϦjQ_HfFGӶom^F zDwW_tnXc}C $kݱdӆmݲgGo pOzׯmx`hxh4}ܰvGڎmn*"}C[^_ewu\Ǎs0q ߰nǶ:l?0q=PҦϽ|'" C]}%{Ʋt[8`cH@EaQnhǡL' &徰5m~"$/nlI]֗=\k`:x -u+=LM>`i=̓/nߺcրcxx4=++cL  -;|/ں H\8b%_** 0] Vؼw_5Bih*-ms?XuV򊢭V7~?"05/yʗwG{rW˚?M֗_8?yUJLwLpR Ly]ycEX7 s/ߟu -Q^~v.O_yn*F}}N)+ޞ֎%O>-NN ¬qUR%FG|[ö-m7_jh=gnjt'$ϮpsKJU64U~}^cյUefY8V``iݱ_޼{㞁_he^^vt͝|pZ֥9ާ8?Xue9*xS``7 VT`+פh+'xzzZTQU R[_ _l֓7ewVffxm]ٕ-;G{jL\ݫ{5_<)ܲsYJ0S0M7))\ibb28ؓ^Zf{_UV~çaOkǒ``?;{rYyQ_;B>{ &ɧnXzd~Sdm*VϫD;sS0~펖t/vURx&')w|cwvlwtddEE^=*z~;kהz`vs0uku/tuZ8M+t ޶CК[GEOϫت + NK+,#A֭GcGumgRSSx|zui]})ku;Q5K?|Edy |fv~G|kqh9o,՟2S~9QEey74U~#V]^M;`]vն0pn+)-{Z[/N\s_WW_qqXGSsUfp}kWkϿpddWV]9WoKʦSu >6Kf윌~F peg͙MN^Xʃ+*(Io J\_)%7/k+3 {]\}ޏY8Y*JfdF}CA}\G;>3+=*++QSWvkQq^W?_ekMޭp2,-+X7tqXnWgD֗_\w^SeaaQ+iis|6#ZYvն։ Nڲ_omi o뎃=9k;¢Ʀkʯ,/ ``jmiV}nwsg=55t$/mڵ4'73*(Z=_oJFfڸ8y``ZZNhP+/Ȏzgרu֖ɧUTk5USuM=7N<Vz{x]gHi0=_V^<5 kx<*J\+x1*(:VSze؆yKO_00miXJ3oc5W<0`ۻ^KOl}cU;33 ǁ L qW{DKfڲƔi\rQ}m7nvcVvF.7c_ܚ_c)86`Kⱍ+ 3FMmYZ5<4_Ta%Y0pLNSMONO**Ɋ=xv~y_bKTT{]}COWtWzn0FN}_GJr-Ɖ|npG{ONQQqTMm Uil-J&+s[ *v@y߹;_ 49CU߲15E]})/rw?;zח=/?ɟ۱mY &ej3g}7gPGO5`Ey +ْqϝOXbzLJ ϫ89yy tv~Y[_檭յeVT=Lw0۹={5Z(33=ΈrvTTwKM|8jϫ%z.F&'ѡĵjۣ*Vczgv:x]Mm]sL;0$%9ޝo Nhis^ 9/.Ҳ}_eYG~ /^;KOLN^ ވXEeZ[[޽G׍nLO֗)U_*Y_c)xö{\qSwWj 9YⒼ{KJowmyqyY<ѝ}㪶U[xMZv"q3L* sj˶2gnON xC^XM~̓#JMM ՕUVTuWUiYm9YYc_wY 'SU]ett' n[zk5T\\@üK+ =7JU[s_3\FfZ\+/U>XXB~ٟY馴¢*kNt$7mhҥ5e=s+7X Mgd,ёqcpL$YRZS^YxCMm=U%WV^0gkw}J99Cu f m[nE8`u{R~pĤ1xSwԕxM۷JyE?3UMmYiV_7TTd Nx]X!QK\\S[WvIh]CE^EƐ:Ι`TƊߝ zu/҂Dܼ*V淯پ+UWPiBVZVĵmkn^]~KQq^58`zdڔ?>O_)ysm]_6RSs]eO%߿:w2+e TJ~mk^gk޷_&#MyunJ[S[ti7]Xc=wuj]5}3ҹ7_ڷ=9d N^x++;#}_=޹mwǒXsE_HH]91ftE_#Ǭ"?#t}|kU3j(YpZGkJ|_]C}Ҳ̓# 1{uKJ~ci9QCc5 j=}aYɸ-ϗ<=۬:wλbv0-s;&cz5RsyumSVׯ|=8tsFS,t"zb\O0,_-8̳kh]Crr2)ѩ*>3+#5F7(L70xb;DU=XuĻ2ƕ[\F) W^(iGYnճ[r~pm;$FSslY6~ҒU y9=\edeeDW^uIENӑ 5m*.I>Wi& }m8?X`&!p>|f-Gz贅,z¦ w%޵*0}Uז=qhjݩ-}RTa f*-O>_tGδq˧^wܴ9^YkJ?c;k~3 ڼeD<7F**] NIeRX֘),m2Tzf<Ժ޵#=L)޶ 3PQqnGUuۻ[chiM}ե2} 0Ƞ1fgϻ:püdh\u'mg~w[~Zc*(YkgW^^k@K>c373 LK_޼/13efGo䴬K/[XUZV B@+ URS"kLX߽dH 0/Er3SSsl;8oé׍D{vVV@׃֘f~>@Ii~[_$7{$mMҴIӤ - Ȣ *qudߏ':O Ѕ4l&Kzͽ,7ɽ羞<"gs/`@^:1G:TKd P(j>L"|U:~}gd2)56` ɓ3X"ҨˮTohͺ g3H"3M}k4(Y= Q[W-]rnN8l6xKo =z#= d3S88lIdI'|[PL?}DܣR+S7߯% 'EyΝl` >5`r6$,PU]|[=_ uwV! ` LMwE#"ad8Z%ݔmG]CŧHinBwz4m(Y$k~vǽ&l[T_y.j W Å%7>8*<N?Cl .ٺn4o{?Bv8'~x$MDd/|߿ȇSCz94I(ǏiO$2Ca=z->~4n,.Ϳ$׉c?%f@F dᡉK{H,bi&XS]t[/޽`95>|'I"{%)᱇S{H0D1ݯ?/Fk]`9<6xJX6y~spk">Te:9tII/\=l۾OVFN;I҉?pDX  T<苞Y] N]on>ie* ģG'k>i`QVILN$zpw߽?H@&q:߰ڌG.#nG&H+0^:1CO{u[Z}4dIg$!/vubzo( #?tX,N+L{嵻n SidYvC/\ Va6gu$4p; 7NLVQYx)ȏtH+ pOoڎ+Lz/WV@Q9 % V``< Jܔ aߥ[;7KLR ol)4Ȋ^W:' y?yH8% ` N8X3v9I,n81N䨼yBr776@:Q$81?R)Xf·R [EymvAȜtcǺgff@P]ёX^kNꝏJS*p^(,$o|̓g$t g*Pq`Hf7 W^N% rժeX\V!KQrj_KH @p{djү&i˯꼾a +QVVmυ-ˮQ^^ӞzI@X ݳ$v_ТZ$ W;YmB!_Ys4;7u`w60D/8uJCgӖ칰b _͡R!\xqwv&k޾5QPq?|A]]$,klz N'IbW8/{:Qrޠ*Wj?a.oOM&}WzS{HKAXy 21ueWv~32FrQybrentzi7ť?j5t2 ҽE7I`)(4>i?zOCZ򢷵)kʿJrUaqތ٢_i+U}ع~_cs/2:voldxrI`x,ҁ]ffLڶ5`S$䲂~r \}wl?ʦM5wG0:IX, "Hk;eRVIuN,+wc~(\sÞݲ3Қ]=<AX "zs7hK6i4bLµ9[Ҵ mm]QA@a纏0@%}@QP)W;ʤiөaK qGw4o^]u8t;8>i' ,``{!] k%xr3E%y+.xEW[_]\EX[[0~PT! ,`ѿ/鋑D囅ˮVNrU{JJ ׿+* OZwv~l1IӮ-$ ,㝞!4SZKQڽJbIǚ7 ܶʪfRoX( <̄_OI"6m^s Iٕ-VӢ4M컸$rlߎݍB݆{NHEGqOIWÚ蒭$of3//I`( ǴvO"4p ]ohEK ޱ?orocY㙋.٪WLCOurHֵM& d^@+pJo6^~M{iVjTAz+F'+NԐ0Y{vV}$Li"ڭQ~v()k4{v7=l2+^e4nA?X\Ex+j"έw}cwDJ}[E iiS7ԮT*™MJ2290rfb yo>m۽aSgMQAz,kP\8D(pfeyq=6y*CP33a?C(-+i״ZpwOWUS{֘N`0"=5Dx31ÖҨpǎ M~)`zO>[Vx$^Q=pN*+:u{.lv3sysK{c`IPbn$CV  A'Fn_M X?,{cypicVz~瞦=-> MQNǎM O〳EcG~D鳭sCiOD֚*JIH?HRXlLzvUoߵ1;[7ssh pLK8 Y ~h͈4)pؒn2DnM$ Ϯ!?+oƽQ?-ۼm^>t3 P{E1Ni}FC9NAX͊B 5Kol`m~fiݫ oP^gj_5")>@hԄE4GI!J0IS#\c[HGxS]g<~KZ)칠qI& X,()`j`3$f]>Rq>oP(.?Lx=cU'^T,acSMM-5?" HJ np{ ,D)fVhnYq<6x/i,}_|VQ'f-zԱriV{G}ʛ Ot= +wg`5\p_MKg2{7n'GcK~a6$ [SK~CEIȃJL]B=B$#%lFꏐ&DU2jRհg]YLJ"}^ gƉc"5thm3W$Gfm$/:vl,S!kk˾m])I,]"1;w-5rkٕ701~, j3S54i`m;Hj?P*yQ7IB~:vnXOwM$rkӈg(ݕMdx|]rExUOHђmS& ކ2 oYh[kIBϴmӐBBwיnDDqڔLQlYIdz|һ0N 4;ڤK%mvd' ^oms[a& ڹa»DdJ8u?b+ r ѻ+# ]dz|EёCHbi Aعb7X5'Ho&jݺ~Iț=޹IMKwfhs27^/*rl/5`@xe*ʙ0A,QŚ-Fd0Ď.W0D۶zCZk/p2{"}rG$7bAm =zcwH+ yX\u~z$x2Q*m mf!Hx+-j֕>Lx-)s4cD{gC/,݉cp(' V$.˵mk3YEK{|ĦerE9oh3$4eƖjrļh4T箍RqŸ{nPXH"w4o1;Ibi\㞼/(+ɤl/ل5^>=7˹}QOޑNovR( cMfy1o Q-15&b;6V+$=# Q4.~DxGeDQ5<=yLO+ i~_{zt$bMawsI`!6F㏶l]u8m${6m^*tW$1f{~ᐑN^rA1]CO+#rqjo%œFlIkM(i`*& 囅-[kבDn2Ά ^rMA/ł\hgkcz50rZoYX5nb:qێw1 ֫]M-՚BF/A2Nf9,K5Eod-֙hDK##g^֭uͬhT('ܹ$r0wTi!bNaD-=>={rQQd6(D9̠KSLEyэy$0t ~Ym1@㦚";K ,T 3 4ݘ+mOr1`S/ ?/'?{!/& ,UӦX'H"8-[ד$M[Ibɤt=>5]aQQTKO$L9t䈇CI~_7Egϔ)&F.FM[j 윏?vԕ&X~S~q1֖+mMR^Fn˥ZzQFN:34IKeka& ˆƪHY}*H/o$ tmV!NC.F帨(T= DBzo\js,.<Ysj3X(IH'ܶcC-sGk{$8I6;'"R5 c^_(29%|Fx'JD9'mh-p>NH-[kU'HB-֎:ٔW:k$R +H(fɜ{g|+Gȵ6G5R@32,BkIQkvRxEDm"rC7H*F'/$S(acS5L&}xێbiDvٴe$0I 66W}O}Vh\4Ÿ )QkNRxE ;<̄ F~F oI+H63;I"{H;In}Y}^5E | % 1')u=X竢q `ȞklA[ʪw' dmV$Zk"kRUMX8?$/"'ل5$5r3)cyBWwXA*2IE%y!|QhVBHkWvfIa?E:Rs=HѸ<㙸$^wbVR '<=פpR=I 즩,6mYkc/CͺO" M4kHBޢq|7"!kFI&<xqc'r?Ԥ5{Xu+"lnxI"sY,FayMe$_`]_Nk&ܾ˧=$!o1Lg3>qRFC~zܰ&2Y YsͰ/ĠTu2j lV_@NSXd" ,kԇkf&' yRx^dfv7帉@N(AF>$yqCU52UKڂ2$Id,5Ӛ., ¤R)a?E"ǢÞ\Π5r{›7b `GIajJ-n@S[;H"4o1& ,'{]USH 762o,oQQ$9?1~{7L @V(C:1'XSxQ:L8QAX1RU;HbaD1!4nIS4.2-Fʵ6Dzozǎ(9 rS)rXBj֕v'fo7J.Vצl%eŊYWp?ׇ/M$IN"bA [&kvzܢq1 `R(5]HbaPQY$MZHbXm&akg}I`W:-V<.Ԅ[PN2RxkGKuI[*0d6-$0E%y:"ן~$VϦ-kegH+Yh$G$0sH[K om`r\ig6o-"xlP,y&aXꚒku:,I L{-A+l6muÊUժ}HbaB05$ u≄5׮D"/ Q_%IXJ)@6/}nАk\SZ^|$ZzOZͬ J kvPDIa~z\#ɽѸ<㙸ޞSB 0d~),Laq5@̔٣$r}WcI`5U8U\?L 3}'-0?. HH/6ǮH&|dL<}$rMaɬgld'?IͭFbU :pI,̄W`IK8B 3>qyoEzR !;ӞE@I̟BjJfH28KB$6B2BUMZRA (=~fLXڿH(?|a Ν+'e"*jHaq|`dC[z\#ӣy,PNg bJJ 2a8lÛ[k$>-5ؐ F8wM{7I_2|ޙ_d\5E+3LM4 L\R Ss(1Z=lz:ܱ>`Ds+*i2?7hDAoвefXx"auXW\Lg|䒏5s:L`Ȇ( @&xA~oԌ8h Ţ;bc65j^YW\O.QWebI/8Qz }U]TP*hh,fˠbij{+pX_`:OsND"bޠuFv"Fnp4.*x&R !~oh{.!s:j3zIbf"a?:|DX"^H*NP ŪFoZ(%ܺ9?WT|>JD\jGB-#ӓBvyi7ey,珱l1E[LY BWD1Xn ),- w3 wHvxyޔP˜aܷ&̐7-}u i5U8Z)3EIiSÎ2OX\CsR t=#oYlnzo颢8E 7!S39%yRUH3=}?tOP.(ͭxi[++RPi7z_z{lxHyh8k6&%cT*i#۶y2wxC3轴K@(C6!Λl$-h;GOYL$,Z׷l&Xy¤;H";~r7jEy_3[ )&E.piEK=ٴͽ{@(C6fKHa͇CI>X'?5vYf-sZj֮.IdOٞ$Wk7 G,d҇I⍤i>O<揄ZHD>Xb b;vnXGi6F?Oh`Iƽ`_KDV߻B {&Ŭ,(&fz-Md & Q,C5wߴ)'>G? ȋio^^anHS?S./:#X%Id(VB$Ieklwci?1@!8d!5G"g&w|/b9Hun`_H#C7eDR?jΟHDBhId#q~8ӷQ图J91.ZH@`Y{CHktXt=i[aQ^WZxsM-5U+3?}i{j3=7pW,* ӞߐD5^̮ɀ/׃qNOud; /d2Id6qxvs=]g& mlt:n;I]w1MuRn$WDyH!z\#dF珞xbJ|Y0d!X_:t5m"9K50Ժ΢'$!_."Ѥޞ_t?CX4.BOgsP,ZJ/-ĈzY0d n$s8wi2=;,\a4=]$!g<\ۧժs׺Oμc6TDv b /x"aumy?=<""GY/Hb 6WgF񕣊KӑğlڲnmeUkG_R:m^/)1אDs?ʑ2m_g<w;#"Ӥ QFŸ!4$GPV\{#rm-6;%&^h^$r˱3b$׳\]_U]^[ل@wˌZݬ(Z!p8Vme¢h$z72e{N|^Yc*.'Dhc%XDbe*&TJSR*V9SknȤO}~=EU$3;O:F11~1?3VZjBӨTnF;;VtK;m1JPF [X h% j=Gmu?-grl0o) i6gm]çԮ|>%7xB:'I#D/B.^蝙RyC3e=H FS_'h:8S ŢETJh'lFc69ob;Ph 2/\3w_ DºHsx=V2 zim7LCyfK^ވ0fl&|cpXž?*p<ܲtS'r5Uk7>m;&ZgLwop0BYhI +{&k+ =-=#_GWbv@ Bшvdzj^%,ό¨_|D;d {^OZ xs[? Z76U7U`/7}swk Ke2@^#J ;6I"DE+] g<wG}sX*.3|j̥]Zy}IK+f/=q6Q,ًκda1u=~k6, N14YHEAQؕtz@Ͷ~,wfK,!g~o_ Mo MFߑ[/w˫~Z3w'V츒V_Q"U8c1MP$Nq5cANm/6L5w=3S3}D㛙M& L:1wK+m)/qgAea3٫f+N ;Vi>/iB[W}OLz9R]p&L V{_rW0"njϥ6ol)!?nN6ʥ=5OaT6R>xVHĜr+eq%*2a;֬/}'ڣR"֬ zfhCуR4['<4p;8܋'\^?tNfdPF֋F0z`kz*&>։^A "L&ͩ,P~bȍA+m7|Y Gt@.myҵƷ'|Ͷ{aQl%!M)=,[X*cF7VTb0)߮ѡBH_L|`ڴ^N,L14wSO?vѩ,:γFzar~4VQ뙤R)T ~ģN4-:{ )bѸFV'N鴽93TR*'Y*d^0mRɅ>| \#ٴ·[֖ĘhCc2ym? Eju87>tlBchdܿWc;~ V{֏*yZ:%0wOO$4j鯲HD5q >?5z'qϬjG%_aU|k.gLJVNѨաʚ/rA&2}>˥vKKVHя6Yf˼ܵL4}Ku_-.(#bƷ ZNȥ6Kߌx&]k8_ϹIN[YbcGeFiD]ר'3y;+ =s_97) 7M6ܵD2\ڳat3t.A)֢QE%s1p;_i-K#)Iχʤr/DŽnd{Ocy_-9\_ɩ?%˫^@ߪ})l ӡF\%1${h#F" n Fa:d MM=|r{lv'M5:>z$lBY-bDc0~Qf+L:Mk?o፰mGCEk:a*ޡRǙ0'eeE3pf<8DQePE>`@QO .aaf<=gS.é'tOߗ|v~WB׫ުu_j=){co "vҳiJ6gъr#IIFd7 K*szm]}.{.-XǍ?<3i&=ɼԶKRʔOBOS7¡3v^gYCS283JHHqױ;;lE"K||ӑ9'>9Կp= |LoHH` &*2fg_2RPg?Ģyz_y{KjShi䫮qj_Tmb+rUf()h )<&L)`fuJI.?K3#ʟ~a=1~OorrFyܾob˵1uJwu{T3NWYVd O߄4-*O<1:v]ʃܿ8ʱHcmg$A0Md2 rd{1wE!kDF*n{)LԐ 4_e n%2@xhD76iI]RNadTNy'?nz=QtOd(Q*&KTj,\[_S&D/ /v)T5 +aoɯ>Qƨ\3þS;(S>?yhxBauy# :h()7+!76d |m~j0mWj3Iiey6$A(6\~fʟf+J~HR{'>(wƣI۷xUQcy- tX'Go!yZ*k I$S@Yi,ĭ8. #U|NS& $B0_08`Й\m19Ω^՘J]51 XulUY96"|-Q^U΁p~TJ'#H,}mLO% QL7=z_$)e}O џ5%ɮr)묮kBKDz(;YSJIY5>I-im]Gp6BR~+ǧg@KԡWq3 ~IFp7 &o3nX-|}N'7VT}KkOY__QXy6TYm=xI~Iϊa諍F\Byq GBҌ:+^4 i31i\?@R(ne4_lQgRkٚ}ջJ-#Z:OJ&Z>fJYRRՆ=8Cgg:꘲-XqQ=}xo_(:u ud׽H"0Ha@ !(7SEY뗘xKui歭k:~E5tU|G:a|;W C)AAn.]B diԲ4K0<36gR2IԚŝ=WMyT}Z.LJo1Z:L 223Nvn${btf$A;70H` ڳOQF5EY)ʒALʫVd.m{h_'zK0W{Oz17$X>ՓpmE^6os=ARu<&/kL^Kԍ!q43K%5PY[KǴc%4r>ۦ*Rgu  T:Mh,'ʞ`r#IBjH-fO5NIl<}:2\ \G ad޿D12:,X!-z&>0i\^UZ2oʴ/:z\SGt腁ѿ@:t$Q!0,  2:]4e k ,V%m0MS.mg(ژ&h(B3Yh-)#N;"Kg 7Jgb zc7v.n3` zYe"FدkMi>y.- \CSs#_ tђFfcz, /8u/ʲn-뱵t:AcM*!2%͜u soiedPnEĒ QLv<}.{.-w?Jrߡ)^Zo g_'emӱMH `H00@T k犢 Ca h%W|{U{%j.cK[ͻ;o1$k+%!9 n7HSKϐVw&INH(Wi8N IJ+ MO\m)Xc:< GzFktf1nDѿ%aJ(E Kg /^]rkEmmĈ(ʈ)qm9$\~bّp{%N}c4wvcO]QZ6~289P Z` Z*6#Pa ),j,[sk0=_0 3HVZbs̹;u&&Ihxڿ~Fi3fEh`5sĊÃ=Ddɐݧ6hVo3y!_^:Dv_GKQ"87>$Q Z` Z:6!P1Zo2*2w˶Um:h4!Ҹ"/Ioa9|?MZz^O?@Z]smba۩@~tԵVsd`'/FR{rtctJSȯ_ȟophV$pfcd2 ?-B0-J[B; "SoZUVF64V3kz)&pH $vZvhi }Vᙩ(;㛥LZr[~h%q^S[G3*J ./h%ʚX e 8鉫Ba`/h:lX2ݨǔMlKԲ0MS[[+kc5/#R /İ\ْ(Tt:m|!=1z-i09->Cљu f>W81:vQ&끎~0Ruy T$,=ckDa/hd4ȕ^O#UV{_tYZno[ Z#R΄Rt_?E%~=۪ggg$m::g`eFj[+k:56t|>ogLpp׷M<1: Fdcøy1wL}IEWg=[gCd?{9_2X-Vq LRwU>lKR-%ErYZS,nj~d523ݨB&h `t&͡GyA 1&n0g&^S[^]x֎FaQˎ`/h:umsNgIcs]kW Ɩ4TߎpvLƈ@KY\~uߐv/%־яʨKӣ$W^>[Ot <9V]S[ δ/s߶H" I|"Nʵ%ּkg1}ohp޶2 y A!d7`AB d OleY0>yρX$W- Q$)0} yI{ίVg7Q áɫIbFc핗D nj(i\"5]LGsk![eڧp|9:R8h 8,J?Cљ=ox{\j_oF9w0:D:yѼ4VPTy8d2mC 1 q~,5\~f&;S3^M_JMDCQ@0h4gFJJ@m>=-QrѪE3HܒrJLjDVHAH,M (iqQUe?};8En2 {{Kf+msjlhD0r2i92[W}b񫴐2k|XoNd޻]b_GҶN8= rXR0ISDH\#rZ8R +S@ьF RMRN@5TR|GcK͍MU7!mKg29I䆢HAI"^/-faEsi{5*ꠌ^f/IO6׷^tpg&7}@Y2 &+:ZGt\|Ņt޶qenܽ-Msc$7[ @} D(Rȍ,'/=ȿ[/\g{[[[0 78l@1R RP?))[I-;KKZǷ1iur[{f2z 3 𒨩)6+Jk;Rt&c88} ]M붗.w ;1n<,q>4uk߾iʂ)qL}-oPFIRyc:hF0r*%7\/-7*ml)&e) I䆢HAݔ)H.?G1'v\{(qpeԵ2zL6+R֎#_6ig`*x}(:({2[hgWȧqͷ1嘺lUq|%PfG޴]j&eic:!mE I%ӥ P8 M77U.:Kg31~tc!ޫ;8riB+z:<JSԿ|öDU6co@+$e07G71@=Dij )Fd2iB;>e^V\mx5m X`s_hC9#TNJtR_9edfe2zQ4e~2]UZ >LJB^5N.{igVȧZ[;^MQ=wQKZXMao_辇1+$B0aIIJڲ_[ij^'n+onl ,W!I I|mE b5hgᶗ.hkaF 4 m[UvV꣌ݖhUgp| <E7jnkjoQXQҶu&dOr3W/_sFG[LG#KX/ezI*ssꢖmhr,}?CN>ygz&ƶɤ[p D3!GTZR;(k+4]Ss&e}IiߺMKs43x֐_(k2MQ;Vs⸧#'. kO̅}ӑg\Wq ¡ZSs')#_۷!tZ&JMz?_>}|'1lV(u"ݛ7&eߢ(! bY:zaq9RQwmV1`$Qf 7/(M%״hfz9^Gz -"n˸݉~^{|67^(ˆ<&:M*,roi>ʔ[:>Gr:jW]މ֩~&MYXn\kJS[R2i=:|p,b n"=kBwX.ʲU+1 KW(lo33MVO,Jg=I Q~:! $D1d+dūKfaװ C.fi ,KJcpn gbI I>̲=wy\[Wpk6o`R7~fĈf_ͽq|kj玚6tzkcJWq5gCW}^}^P >>2<#t8X8i:Ką!$2*o~}~aSjXXOfEN(ʨA&Ȓ[8\e3tZ x|(G3A%qV\7WWi!T:m:4exf`*x5y_SS #soJ]lk]]}Z>实NTu)^ǐN?y3` 2'1!7ha*iksԫS~^=xh)^S45$+!D_)hX˵Jeim1lvB+ ^9ؗ:#_QF&G[Uݿs q9B-Zwjqeu25Zz){JgtchܠFT(XoA + U9~SK' iRȍ P#HBY$rfWz^BX>ʨjetr&K3D{Z,ZK&aR^C%C5gPtluP"|Y pJqzNiq8T=֪nǑŸ3{yáVpvѴq,t*H[R4VMX!,K\ʟe0u^:q XIJxA܁$r CO" _b)h{_İ)oi:O>FUs2T4I4yw+k@k>3WCkګ`(3 AALGZjgګ7A:u54;rQ1á[<+ϏZ$| 91,dZ@xd9)2V2̽k"-Dٜ8W,4Fꕐ$mu{bVFU/igA墹Zρ-wO Fzi;jqK41r~Uْ,s~VZ*k?I84}vH Di:r8M<&\"IeTWOgJu{I,K^>!D'}ey$6-KU$İxZ,2ڔZb\9RU[+ "&7/N 9ݤ׿&p=nPHD"-ԣb^nhZYK1$qnt31y'1Z ;tXL+H"7F3FIZNQRT^.Eg\_C Y|hflPZLmaS}>Bsd[[;PPQ!B=nɹe4A:5N^뮭m IFzpz֟y^ @B0hcH"7$+7" >vtj^`06ni~a4RXDB@U7hX  OߏBFE]?Jr>,S{(XcMRWxo?V~zkDzla͈K Qh(6xMig::w7;G%vdz7nPhqQXMz*J6,s>~[:ޠiCtߋ3SH :x6RM*ͅc$Vgbs۽U5koǭ)3 iK`Ysf[FFrY8=,^GQs4$9Ajzfkj?l=6~n,<ǢI:8\Hbu(-lZ쥡-HbrTu#! 4b` fN!cBP |߽Sw:?[+|e O^#(3[> IU$v{w,2zZEό/m6k߳rm=6^|_Ȓ!m/=\LۭlI0C VWI,phJ:48=ю4@ 3[X)sG/@ Qx',PߐB P7AH.aefRfoX@;RT:m:<}}:2眘 zk G6X RRfHAO͖DmRI`2mUZz8keUIoO>ԗh:x&2"̈́濕S1M#@)Jgp" %јdtާsU e 1z#|pBAZ{e/ݥN`6:Gn$~ʶqO+r .'ʙO㶳̘2 oh߰h^7?ygZH@(KMN6׷\(kPho`HIFzl&3Ÿ8Z09[lGzLݽtӑ< :xâ8W` Eވ$@&>"G,G'fI/K%D1+xJG]FMv}PN}~S+987G_VL:!aʋqD &^zC&^9Ptށ4@K 3e"H"7 BsHlv6d2 rqL AKrg}-fyht }sRY;VN&z) O ^+9DcHz8_H㖣Y_(?ijN e}-A0aFSE9^g#$ZKH!w˃ CHBI\~+{<™ƕx/fDS1gVUJ}B땿Or};ldh,m)< J2=u[KHcidҺ~L ` 1v )MN^r(GTI/$Brl:v9* 6ZAOʒLGmʺZdz(묯7}G5d3tѥ.ϝHci>vTi PF DE'1Фx\0G7"ܽcydSQ }SGKw.6PTfm]?k>Q>QJI>uˬ6,+2!N㶓SYoy}6շ`H#%S'I `6sa!rA\$ېD^yS\\B^c|Z͹* hIAZ+kRڏVE6\~edF̊ANŸ-XVW{˺-nri,zOav :A z|>? IEo\䈦)]Yv$n,% &ക+0J:ƈ%KQu(I,m(`()BbG1n(C ֞ eV_վi,Ξ/" :AL&$DZ$t:{ Ieq rfI KD=jbBF<^K%] ͔JR6׷~jVoL,E?='ZqEMN[6nlK㪷1C"  +7`qq3 h$ɆDJ-4P/A Ln,M=,+W-o]އW} r%q#Zϟ9HcEʠF~Mm CuS)Kxo,m7RqZZY;/V`H#ܝ-*~`sInzjX7# >!I䮤rј3[I"JEk(#6+,>RZ_[o6HVUabZ v G7׷MmH$7tpxHH` ݼ )n~.-Hd6,MXD%HAxIt^Upke?TFG{f}уmʦk ICQN$*=.HTdMŴ&g7,\jopp>Do`*x5Fi tDz䐫XM߈$@K3O ,Ar;j "F_fi:]pZџ`n>JЂ֚-,7$ guu EgQxIz&[iM^[m%fӇ߼nu79;eI_@@tf9)#Q*MNaД!\ѴQYHBHt'=0+ ?0ҵΊWY'=CeL!NPc$@,,w:LϾO墹o>z;Znqs8&ر7ns{* :g;1~R>! s, 11)VHlqCtNi$nD͜Zx|(ʍBV2WQ+&%~;dEK[}N[sH":j9Tf2H2oxfjk1lYOB$XeV{֎k}uu7`sHցz$@0hFI%$r7==s~.DsLH"wCVI/ $#+]hI:JJ=BK:M-W!RnķUaVPe-ԣor("Z-mm]}7oh.wXk)kpz#`9:bG:Bӑ ЂsQ\.@ Cad ":f+]{O#e2zA8TҙU:=w"YSۀѿzfKr.,&Cs.w}-r}tۑZFAs 3MH|X%^q(7ܛ}ջ]:)Z-rچu%oZ{Au!:J&> :AS\0!7Rҥiw|]H"wzNWVn %4ݫrԹ*z{t79 s,Bke!差4EefI-ԥor}qgdRz| hʬۚ?Xrq뚭A1?87h@t8lߠ(#X k |IeHBYr\~͎~+EtLOea%/qӚچ^WrJhtt?,2’)7C|mu kΡ|<EA,L(IFȝeJK" u^HrX^Gegi3G3D@KbG5 W!HHⴕ/>S0ukV~.i]UY^k$DyP[)%֐Y9$T*2# 2.wɕV)$ԍR1̜Zwy+6z=y X#Sn67),z5HH㴕)g{{N~U u9<R(Ƿ]\R^ՠקT(C0h"]0N` \9X+>xY'RP?AIG1Zⲗ&sQJTۨgfFHSJ&^bjSe8?/A@d-q|KK956tcf0j=2{7Z'@]ohPtL+u B,:A{޲V=&`XPuHH459wLhޅ$r^,uxIцäTbjC^U$=Ә38:fs}ˍshX O! ڧ:u|OpvL9 GԎݟE9cc=e4Z_L.h:AsܞĢndx7HH\u(b,Nt| I I$)>\,GLé6&~% N)϶zQ$p宝$3ZS:6<P'InXcՈȜpߝO;5>B̔.{ih[ks,W%ڡ4Qnu>$fh` )1:f/d" KH"h G{2@15vh&Jz$:qtzӵZSHM_F @2,-ǵV/e)_X8'3G~7% eo?\JMtw>⩣, 첗"}$SIC0hf= ;djrudhj'X_XN! dis4sB x|_-pV[XHϕJrga9yuf$;r=$tNX/9`wwpR5wblۯ薓I\!LJw&?^SFP2 j`$OEOLOq#ӸD# @Jg7R / I.?K3j,WUێ2ʹlIMi^&{qtZuuvIdI<>.9L'#'z~EKQ r򉺧 N{5 p]@e_b2n7Q$l S 0]IAZteL#-5rfU6KYjiޏί{Xo,be^r=CV5g4Z 1[(\FU?:?y(h :e9 '8̨ZLp~MmG}(.wDg;j?$@k qzRLu٣wӟSFn.'Ã=lߋG>w|84uB:<=cۦ#s;ʈ_ePXmbbLP%"u+gR?u[ۃm$:9e,z1{1j`%b:Q$Uq#7(Z‚Ϗ:!Hb uf\x Oߤ\O+\EYxwTF&!?kT:ʐhQ[1İC.{ibg3vE8k(Fk.[̽{b.-*hUCJ}_ &o O[ke!WNrݧhv,e1Xqza(z,1^yrn2 h9Phٙgt::hTq3=9#86i$MM}i/In̜WܷO&eTJXD=$g,+lM4j=56t#5_DU>GxuXtg{z^23lh0 5+Ng,MGK(8{\k=)$tG>UUf(b &&5ΣuiK,?V;Yٸn"pyYeh5PhЎ|`q3tPT Ir>_hY[H)6EfM^9UE/cQO.ɤ`Ͻ?޻{@קyI4Nvڶhv*+{7!_|OB]&ˋ~79;mfXUޘ夾{Vn 2@zl̔432YhfyI(6mI>o# к=V4$rķd||->y䞉/_ai:V`дo"559Jz=l&1}Z&} e*2 >c7YvYNVcaj\H$\~PZVF"V1 k TҴWqϡ&qpBGM=QfeTx!+N?sw#?Ã=cLtW|X ۦl}-H`д0Rh 5jbh+gh&k|dZ2Yڃ%fˌZs >h q+g$A^D9%NϏfHR  I`6?P7jch P,}ջl& 879?Jw$_ud'4߽xh_1̑}_ MG4sfF+PuYVf4ɡK6omy:8sj2em|NG^Gj7ZCOpj(:~/eY5 IԉG"!eܥ?D%)@r99EJY=cDH`(:f&m,a܃#C'dž~4UNjj(6c" ;2{[B+]_|p43e7[71L?c+ 36Itey*! "9hu펟  p=E 37 _!R됽8m%#so{ɩe_ߩ_ĄڪXQp.;`8}}!™z* _>:2b/1" rArCpv R&iEK ,DQjyloC]2ufZeCυ! 5Oަ'+}쥝h@̍ f /o:ucğ̼e<9:xG{dfQJ&hIs@ק_8uX:e vEPc&~Ʊ@ƍ%4%u a xT^h$z.A:X.{iuƫX]иꟐsL6*s!кS_fYZ'2XLFn0TzAl;N&g]ᶗ~p,_1 md2 LEfyc\ ] 5"wHE0[8]Mٿ>4ȡ0BrM ScC75;b&̓Q>QGjNH"ZF͟M^JMPR2 [^3e̕HBE @ tUx.-0 U5.bo+@ה/dB <1?{cKg4fi#u)]FgD3Ie%,Ĥ^2XX[ZW mlt+wteE xPqk9$K4OYޥܻr>~ZD+ʭĔAq.5-̝GJ7u5uIuh&HZ߷H+2jYLZM [Nre(*.uEe5]zn7 6{|j;Nކ$)I EA"Ejo?Tx?LŌ- pve'<%ej,![\դU! !,MϐVf~DR./б=Erd2 /Xe5w)j~Ǐ[95a'}#N2_|)I E)}>$.69#آg<$TQ';[iqܞ].W$A$֓^FH,wQxEbMKG巹]Zۆ@'|"$jwqUwwiF]{-W\)$YlBŸl`$6$N IlދdZuTf4M=3)O ŖUyAy=sܙ=vKhfQPFP 14w劽?S+U, "5R%CҳTczibSc.^#YZ)0ںN,,tMS)VK: sX= |TqI z()qRPFHMZxblV@xsz^̍OOǗixxR!KI$q52&\ѡMb8ִZ>?jMS+v,Zff>L4%GIhs.g6I[%|Po>` k_H & tU߸^q`N? 2e_VA/MLXD'95Nד,תբ^-5ZFY75cZ/Ie|UV]D))%*g!f |%y 'I`oix$M.{sxO Qڑ{+ILLS[O5uawW@&Kz$?! _c]O[{ 詉IK+2L!]$ת5-b>hہ{|YʁbX <񸙱3jxJJ %)DJ=hkD7i@W=0IB2b_&.`׀)L;\ڒScM ؅ Ӳ[xP1:k>qQ NN,Ԫmb>VK|i1qsD b/D[orzܱRjSZtNg&Top_8PT:IRߓC6Vk+OϹ$ VTSbVLX5Q'[lRhˬfѫU`%iY_|[KϪ Ąd Iу$!NQIǯhҢy400%*C1Sk|BeEwd{HM W]DZz* i@UM · p~`ehE$2ڼ96.]V%$*= .rwYJW#|ǎoq8X# $ q]jAV~_rTvB!GɁYxzvň5y*[t{}eM|*DлًlZWZDxZ~eO`!#$-?1#HbFAEzSc/'{g뻇G$# +Qz@0)LL^n|{B>GĥfXV[Y诵tjM?! u"6fHORb_-ȓAִ N;QkbvScwפ&F{01zz%k/(X4>_`ve bb*HC ^m x4^Ҕ;V:$0Vvnj 憎r _ œY煛B>FΉKe&77΁N \H|RЌjMwVt86 .;Qkb77>>RogcDt\1gQRzLӤG_.,.yY~iQ)b[/*Ri@(#h%&EJ748";r#E~%9Fg`B( dvy~izHl~M= b™y$r.'NǯU%w"ǘúfzPf!Oz@mpz<Zgox0TOԦ&7>=z^z|qn7W0,ӞK%gOvDe+)5IRGA+$0LSю%mZ_zʼnQf 0o$~Y3-}Gsp^egsy=b>~Z ~I"!BCmpzݽ2CMu+HdJ3')2 SK!5@ۋxeyUsǕdܡQ$2quZ3"DXA-3;;*e^x!yd.XګSk|iÁG;/ϳ97qLͳ])V[#0.,wN[sthA'k^#Kό[[)6h՚RԘ+Zs&~v`Fg)uz߰xf1rA[L{Rj`ȌE3ovzC_j_j+ |@<=ΈPr/M|"?!S7hoL2g&r,%끛DH0Zbr}KZzIc~n%9T /di~6=^6809=N';:|Z)΄\&*1Bթԕ:ѨՍMŒ!-FSQ"E߿ =rnn?'F9PAHrSP+=ӳC 9:69q2rMZRng죺<1[פreiY&S4J5^6h]U~6y$B-`FA-$`IHika 9TW]ѥs6pSm!q.WF}cѱW=GVl*ҥV*:ƮUk܁7zRn={n${mԑ5scjK})r^O,#יkI==a ث'p7}T]}kҾ0cȎR)Uwu˘;*JgJTK)? 5:`dq>GԎ͞m# ,$_e" l}G2\tY{[H;NG^{Ѵc:\. l(LjM%S^V&}cS֦ԬoҳEm+ rwMG˽u&1]\dBxTb-ǝ{NAۗ)9jy==&hf@ zIHK.n4&oX~`oMŗ% ۷A[)JQkɎKc{GhƘ7c➌ M2>g<z {WHM?%DDqY-R+?Dol&_PYqM{=q;b~eMuf}rBLb/7mVWu]/RT%aQ{b>4h>||7*7pĹ 7nE1a|(BOݝ^.}Ef 784గHMM ̾w pkqk_N[ޱ1P-PM~;%*aΖg+o-m@j%Ն 32V\X䮸עa].Ř ef'd[L0΁.۷de_ZH/wF.2Iˈ# P5tK(_@3' o&v خ:=_341شV*Z*"ߍ1! J=#vSszV=drנm^&*i1vBOBތ c?_`b պ,>|v;IA+;. 1)zi>KSCM< .0тNի7 ;GRԦKg-8H^}(f.w p ΋ngN`sf[-FSo)C$6ఛF6y.\ەz54*ݠV4FWQ0GCYo I ` 8GܲV3m訙$y֨0){iuԊɑ1? @Qv_F.mr{=xGGcm en\JեUktjM1l6Y a1GEJTl)x;.?ByQ;w ]TާVWfNV%q`P*-=nKdi3ƹ/P(%(PD{Te$&OxaVHzuG#>!2=#~QEK㽞QڔAһ a{s#Hbr+zIm{1I=WMǭ<~)IT9XP>E~a &ჵm-;PM#$ kkYJ!:ѱ1ڔNw On}1-=.GCn4 ^4[6vbdNX$Bp955z/Uiw &P2+.dmt{?@5y$1I y&S $5 1;jP>Cn~ˉ15$1y>zw$ 8.>(-#' 9m_R颤] `3f,**"c>|D36cn5HܨwLuР0&I`eYٷh4*VΑ%9Sqrm,Ĉ09rc"̣$1yiSy!G.8ڸ$&O5–ȌjáM=%U,5ѻ# 爈 m+L !6x6{ i4 mx菣c1R"c/Ips5RjSIrY` \a4bu}0WD}鐲f$j6J2@hz"[z(6 ƊLk6zbEe%.!u`oMIX׶+HIG' n}Djm*MɼQ9Wh4*DWˇGL04KxIbj'FH 4O5<%(r_ij&= 9 0[Lu$15WwgǐK`l~뵝wjLYY!f";VJmʈMx.ToC1(NΎw}بON 1906%>TRa$ xGG-ҚT(%)ӻ" :v~R`QIbj j6@P*ۚz%=Av\Vw Es0kN%.>$Lw?3~3c8LĨ9zQhk)IT:~D@( 0Cg9O#{=_% ]mᄍ;wanɤ! T4;:* R~h]H`$&Ԑ:m3aKn4 o.4NJZޢtIdVloWJmҨ_ӻ2 92͕3 xJTܺ ,0TJSxA:fة_$=AAb]M- iIPXNN$k{}&{G)0JNݛ_j"Av95mwHM:f89}- LQZJT|7\S0iԪ>X` :kml cu_HMnqR-,*`Ht/IL-%{}:IF`}cÎ;Fn˜bw?@!q:nRZ]G^B.``(UK 55aLA͛}r0cvgPESKS-)4@h7?>>RJR2ng,((;7ҴY$1k/}nWI09.w4Ե"W\I>sRjSx2˚@ L M&=ALCklz$`rl|=$1L!z5C`ɑ֦Ҕ @P L7ʳOO>>ݹBCpnvl;ٱ8NĤM$A[Lk_ϽRjS1dGZL~z00-)xHb|8(i;pTLkᒂH͡_HMeYߢgl(S "ܺhiaʼns-mwT>LpvjZ~O~t2w: --  tzO 6EZ6%EFWѻ6)2kN,%ͺ$4w_IpfN5u];GKju{ٜLnᦺ֦ԬY# %ˋwk4*˜&}C]Vob4 \,^^\k& (-]=C&%b]\XD+ `DB%iw"ړ~?1o8?VE'pMPXMᦺ'֦Y+ [l'i9o~bvHH膗tiL@$BQns '6%FD?jw(SbεiVSrk|r24OZ[v#iL@$Bs~T0= `FQ kRbjHbz?⛯rz4 9Gܚ7\^qq iL蚹 X 8K<))5pS `Fֵ J%t;|v[LzG Xy<^v9TiLk%3u#/J= Wy?= `G5 &y)ʘOo^ݕv{ ظ]^wf_4_qY_@hN5_pԦ#7] QJ?ك0à=;OQ3 gT頻&x-R{ $9,@V1%+rJ3b'o+"0`(ΔN6 /Y^ oiqJMYħL:(nܤ5$13vx]@N ;(ΠħH 4QIRUJ89.iթWUZ˜!WƮX@r߷^ݙow7he:Klm3Dy?kc.?ļyJ9{wlyyn~ #?}As3' и<ɶ懤&Je/HL ``,]QKN$s`ouņ-۝ vC/oM1s,Ր@4;6fR Ҫ>z; 1t#^2wNg3)P(Yn@֟Wm|4fV]tizI?Bq]ꎖ;&F3X``e$<4oaϰǛ =;HĦ봭緼VSr+i̬LٹI@|KMEiߢgEaKVE̪ig7o+' bz{g7oljG3+>1szѰsDWvd:S_wEafo,=Z_xfIT>ڍﴷZIcfij3[L#u%PIr-,(tEjy]um @oA߰4f܅y1lj74g%nwOG+Jti$1W^vWI^_ه!ɩ1/eg`io||\RKNd^O0 }s>`)hap8\_d`c>fqW{TorzDwCiwx0ToԦ0cȎ.~S@:Kf2jp,_U\}<IjV;=.ڤhfP ,N[tMU+{ ':^v7#u$`:/{՝߫n4#=3~򕥁kicˠzV K@k=/%Drx#?qWSCM`V=wQ(7h)@pX]+oldSTXK{%eOUo! !]ڍ*7! Q՗{6"J2D<*PfKX.$ cq͖v'a g+.Wb3 n% at^{品7s8\pFBׯۚk( Xn~#Vr Q,@|h4il'۹g6{"M 7=ԇjX*T!\1VͦDᗞ0,,$[yQ`I\/:}RC0^#&0U8 Op R͞KD&~ԣ3WV]S&'*~>PKW SXDEf"4` -i!|zVhIeEzQz@1mkώ^a8"Jf"XRkϻ'l$ pe?8{qO_G"@ig6u"a2eW\!+f"oIdHdKV+,*Piuj/t5;Vxwn;s8\" \vU --ZѢ ;l訛$% _8xrjHKc}-?8F t4 r\R>ZPzI{qu$2>P5_>o$ v$o(>?WhIa%E"8nٱjsdˮڊK4  9rm}% O\􇥳3# @Yuѷ;;HC*[.$ H`@"Pe%2,]QOF"tڶwkm2HRBwT憝{wl qd{b%`fc޷opA "7<{U_^|@U0 AN[ҳY}?k|m%eR 4Mc;CID37}UWBvP$g0ŵ$) YnAҽ+2N"n{pꓧ~q$~E1a) HX[KϪnwHAҠke%2-MHD"ԍ{w:rDֿU_NI}4 U>KmsMj6f.X\A"IeN-M2 @ط+ DF= +Е 5 01C#aG QԐ(U _Z\G: @ضwF[Z( 1I83aᆑ{Z3] k%'  @y=xIB\&KL3/{vqYhԱ~-Fn# {4wp9$]-+2]q"I XP3xO쭮 iKN,;(Uf 3#+i8qI}`OMe$"m%e\sҷt: 7? hP2y͕ǚ֐xL8g^Nf~QJ%E*V̓UWGr|?bt @1{v˳u5mWFpEz#"C[I?s`]u}}a$2t+CFi PTo`Knz;4GxDx eɬ9qIRu,6.?^w*  7޼rEtLXi QXi[g7olo뵒Fp1[Y7TQHRP~T82`c`k +qErK_zv]:>:Flvܤ=3ΈínȆ5NPPDw㿭:)% @0 @Xy˺6?lPe Qy)E%isIBXM[O|LdVf솯`V[+/m/0[L臘YaV0pZ~QyQU7,'(^wò_'E`W^€LRʬ߽r쩉5cZ+z QB,l]{ò_'S0Ryiun۝N%]SX\XxH` 8"[KNV6q/hɮݤ`7#~ѐd1Cւ'b`hLm-=ThiC}{]g{}U/}aq7Ig|cMOߢϢѨeQĸĻ":08k.GwS]MOTue\ ~ɓũ(L"~aw>VƅWfdef'kXc2)38ܺ.)i<;V9,eoX_sPAm3/8:Rn-JK{pDd`twM [Ow/a__PAk/(B'Z[ 8gEVC\ IQeNIͳE'=ytLC]Gǩ#PK08+fQvW*7?.>`gdm00aFNo_jZ {<,E2148=p}kK }k 7`koX?9yI(8c u_׽=*hT(-~]BRԖĨ;/-^Vwַg YDw KȊ43CYiiu?w?40b1b¯KH@dGd_}/76pɸdCݰI)op(8km _y VT  qDF+.>ѱaXûBB 'M!z"#p&쿻8/tuO YዩyM˯E١ `Br7%T*dF^f 3DXrWW8;ٸl10u}* ,<0`=<8rMiwzRlKMEZu7,5*RG٣ `_`;H3ARtzl1v_gDdfz2:&?jc$wϨ>F_c6AwtM3&'?i͵_Y{G9t~UǏ6e/C!#q?%x F0hԲW.ZRȬ_`d:oYѸ)T;@uqL\SYL˯ZӢt$c0)P~xtg(iaua]K `t'njG̸M_vqIL=79X4 x\r N-^`S*>xgfN. \dyv9)FٵR;ƜN7a@0/2Q4 e_]LdC m1Wv(Ӌ]G{o[~}MդғeW-]50iӋ0av{kO C K\V>?7}NM`3f;&W?g8]jbђBY`l'`f0A`_08X_O,=d/0 @:;~mխ7GN~Қˮ\t54G`8.Ǜ{vnzLV/+V._Y09vѻo14  KI|4a @N5u]{lXB .bR @x(ᡑЏ7۽>:ʒ0K>/8@|U*$`'@({kR6oHN0""; V^2<{'iF(.|Uh4`$?yY# |sĭ];>pL!Q'[Hq޲B^  " oM7ĤFx-~qa0QpDn1IR+es$hl1 >Cm]6#iZÇV]< @( 9cŠ\.U5k关#u$`q`oMʖkz5_,29se7 HJWpƃa7l| R!+*M_ubI $gl'?v\5#hgEWeR\Cd n`Fc JYqiꋊ/ QH^G?x֖4Z*{,008ܱо='#7 zV6wAvPK"QToh[HYfv«_0`FvIӭ9nt GwMG"$2Y dvy`ԺH.Oܷj%R+er//6EE[HNm9PW~#c"]eMVODF\.:ŮO*Ow1 s-\\`U%@ccJx;8zslI6.,jUZ@PZZ P(T^ **h+QT[*]Ҋ^VtA[bI8WlO| ]#/ޛ~{WyzчY7ebkjۻZM>Y:9SOfT6J%vwy~ V=sꮇ|j{^[znرCT$Y ?B9>S_;urtڞwؼeו<`8y჋>t86ZȘp15އZ33]l7dMx>`hb|j]k[~ώKp!t暛oۼ/ "M]rar@1ص۶wu>f"!D#C{ȡ=~xqzh $vt]m{ow&0r?'&g lb ܶuMp![+gSWW[^:D IHFG 7>gz."[}Fpgw˾fG 9kKk[ݛv; E%\"3O=q|xw8/,`+'-MNT\lw{KL+\N0drb?ywO>cl(pNtt6vغ{OM-LRWCw;rsYC,WIl[76Տ pp#Ó{:Z}_>tfp|;¥{餫} p[/Ϝ>뇞9O?yrzt3xavް}Çoxo}}]T |C>LJQ.&z֯mmֶAS"s?s轅YCᚷ\uퟺ~K{7u\ڶIj-&&w?çuLO ׌DO/om{_L&]6 *2tf֓G?8+c*&fJή7ıᷭ]t:b2@F Mzh#CΜolаթ%n_~䉑tv|ŕH Q838GǏ ᡣ#Ó떖 +*Қ_׽nh_ְ?J:i0B95prw7o]F'1uXYq].[;ioڷ~c+z7t{uИ- \Mjll`ۚϵL V3Žӛ 6&g?:un3RY' UD*JkMrml|KkCCk[rg2ui\>0WRz~~09ss7||-Sf_}[|q1lXĠ*֮^{1%Ʀk4e[_پ7J&=#pU)3k狋ۦ~nՎ{[&'f>1;3R3r¡V͛L$T6kjYK[|>И}}sk)< 3ESzPNJbqqt'ggk?33=?75537;+rXڸXNRi)tUdu"J~9ɤ벵kkSe5456\\MV3T9mBX)-suBy}\^8_X\x8xOyc?HU|oaʲZj4^xee%q~|e}>z,ŪJTUۮJ$5tm|mm\m&u"SV&~.S;J'd"4rU^?\t:uv!J{k aa*jKRWvii\Z+s/UK˥;^{ԯcU+W+5cj]TkKUՉ*+55˕u57~*LVTuttmh2U3J%hmml2,V*+B0 j#ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB`*IENDB`Mylas-2.1.14/.github/workflows/000077500000000000000000000000001510307563500162665ustar00rootroot00000000000000Mylas-2.1.14/.github/workflows/codeql-analysis.yml000066400000000000000000000045151510307563500221060ustar00rootroot00000000000000# For most projects, this workflow file will not need changing; you simply need # to commit it to your repository. # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. # # ******** NOTE ******** # We have attempted to detect the languages in your repository. Please check # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # name: "CodeQL" on: push: branches: [ main, gh-pages ] pull_request: # The branches below must be a subset of the branches above branches: [ main, gh-pages ] schedule: - cron: '41 12 * * 2' jobs: analyze: name: Analyze runs-on: ubuntu-latest strategy: fail-fast: false matrix: language: [ 'javascript' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - name: Checkout repository uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. # By default, queries listed here will override any specified in a config file. # Prefix the list here with "+" to use these queries and those in the config file. # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # and modify them (or add more) to build your code if your project # uses a compiled language #- run: | # make bootstrap # make release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 Mylas-2.1.14/.github/workflows/label.yml000066400000000000000000000007231510307563500200720ustar00rootroot00000000000000# This workflow will triage pull requests and apply a label based on the # paths that are modified in the pull request. # # To use this workflow, you will need to set up a .github/labeler.yml # file with configuration. For more information, see: # https://github.com/actions/labeler name: Labeler on: [pull_request] jobs: label: runs-on: ubuntu-latest steps: - uses: actions/labeler@v4 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" Mylas-2.1.14/.github/workflows/node.js.yml000066400000000000000000000023521510307563500203530ustar00rootroot00000000000000# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: Node.js CI on: push: branches: [main, dev, gh-pages] pull_request: branches: [main, dev, gh-pages] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x, 22.x, 24.x] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4.1.0 with: node-version: ${{ matrix.node-version }} - name: Cache node modules uses: actions/cache@v4 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - run: npm install - run: npm run build --if-present - run: npm test Mylas-2.1.14/.github/workflows/npm-publish.yml000066400000000000000000000027221510307563500212520ustar00rootroot00000000000000# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages name: Node.js Package on: release: types: [created] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x, 22.x, 24.x] steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4.1.0 with: node-version: ${{ matrix.node-version }} - name: Cache node modules uses: actions/cache@v4 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS path: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - run: npm install - run: npm run build --if-present - run: npm test publish-npm: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v4.1.0 with: node-version: 22 registry-url: https://registry.npmjs.org/ - run: npm install - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} Mylas-2.1.14/.github/workflows/ossar-analysis.yml000066400000000000000000000034231510307563500217630ustar00rootroot00000000000000# This workflow integrates a collection of open source static analysis tools # with GitHub code scanning. For documentation, or to provide feedback, visit # https://github.com/github/ossar-action name: OSSAR on: pull_request: jobs: OSSAR-Scan: # OSSAR runs on windows-latest. # ubuntu-latest and macos-latest support coming soon runs-on: windows-latest steps: # Checkout your code repository to scan - name: Checkout repository uses: actions/checkout@v3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Ensure a compatible version of dotnet is installed. # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. # GitHub hosted runners already have a compatible version of dotnet installed and this step may be skipped. # For self-hosted runners, ensure dotnet version 3.1.201 or later is installed by including this action: # - name: Install .NET # uses: actions/setup-dotnet@v1 # with: # dotnet-version: '3.1.x' # Run open source static analysis tools - name: Run OSSAR uses: github/ossar-action@v1 id: ossar # Upload results to the Security tab - name: Upload OSSAR results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: ${{ steps.ossar.outputs.sarifFile }} Mylas-2.1.14/.github/workflows/stale.yml000066400000000000000000000012011510307563500201130ustar00rootroot00000000000000name: Mark stale issues and pull requests on: schedule: - cron: "30 1 * * *" jobs: stale: runs-on: ubuntu-latest steps: - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity.''It will be closed if no further activity occurs. Thank you for your contributions.' stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity.''It will be closed if no further activity occurs. Thank you for your contributions.' Mylas-2.1.14/.gitignore000066400000000000000000000031261510307563500146630ustar00rootroot00000000000000# Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage *.lcov # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # TypeScript v1 declaration files typings/ # TypeScript cache *.tsbuildinfo # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Microbundle cache .rpt2_cache/ .rts2_cache_cjs/ .rts2_cache_es/ .rts2_cache_umd/ # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .env.test # parcel-bundler cache (https://parceljs.org/) .cache # Next.js build output .next # Nuxt.js build / generate output .nuxt dist # Gatsby files .cache/ # Comment in the public line in if your project uses Gatsby and *not* Next.js # https://nextjs.org/blog/next-9-1#public-directory-support # public # vuepress build output .vuepress/dist # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # TernJS port file .tern-port tmp/ build/Mylas-2.1.14/.npmignore000066400000000000000000000000621510307563500146660ustar00rootroot00000000000000_config.yml .eslintignore .gitignore .npmrc CNAME Mylas-2.1.14/.npmrc000066400000000000000000000000221510307563500140030ustar00rootroot00000000000000package-lock=falseMylas-2.1.14/CNAME000066400000000000000000000000141510307563500134320ustar00rootroot00000000000000mylas.js.orgMylas-2.1.14/LICENSE000066400000000000000000000020561510307563500137010ustar00rootroot00000000000000MIT License Copyright (c) 2020 Raoul de Heer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Mylas-2.1.14/README.md000066400000000000000000000034011510307563500141460ustar00rootroot00000000000000# Mylas ![npm](https://img.shields.io/npm/dt/mylas) ![install size](https://badgen.net/packagephobia/install/mylas) ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/min/mylas) ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/mylas) ![dependencie count](https://img.shields.io/badge/dependencies-0-brightgreen) ![GitHub](https://img.shields.io/github/license/raouldeheer/Mylas) ![npm (scoped)](https://img.shields.io/npm/v/mylas) ![node-current (scoped)](https://img.shields.io/node/v/mylas) Mylas is a npm package that makes the loading and storing of data from fs easy and reliable. And it supports multithreading, json with comments and loading buffers with multithreading. It can also find [node_modules](https://github.com/raouldeheer/Mylas/wiki/Dir#nodemodules) folders. ## Installation Install Mylas from NPM ```ts npm i mylas // Or yarn add mylas ``` ## Getting started To get started have a look at our [wiki](https://github.com/raouldeheer/Mylas/wiki) ## Examples - [Json examples](https://github.com/raouldeheer/Mylas/wiki/Json) - [File examples](https://github.com/raouldeheer/Mylas/wiki/File) - [Buf examples](https://github.com/raouldeheer/Mylas/wiki/Buf) - [Dir examples](https://github.com/raouldeheer/Mylas/wiki/Dir) ## Documentation All features are listed at the [wiki](https://github.com/raouldeheer/Mylas/wiki) ## Contributing We would love more contributors! To start contributing read our [Contributing page](https://github.com/raouldeheer/Mylas/blob/main/.github/CONTRIBUTING.md). ## Supported Versions Check for supported versions at the [security policy](https://github.com/raouldeheer/Mylas/security/policy). Mylas-2.1.14/_config.yml000066400000000000000000000000321510307563500150130ustar00rootroot00000000000000theme: jekyll-theme-caymanMylas-2.1.14/config/000077500000000000000000000000001510307563500141365ustar00rootroot00000000000000Mylas-2.1.14/config/build.sh000066400000000000000000000002011510307563500155620ustar00rootroot00000000000000#!/usr/bin/env bash rm -rf ./build tsc --build ./config/tsconfig.json tsup --config config/tsup.config.ts cp ./ts/dts/* ./build Mylas-2.1.14/config/tsconfig.json000066400000000000000000000142121510307563500166450ustar00rootroot00000000000000{ "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Basic Options */ "incremental": false, /* Enable incremental compilation */ "target": "ES2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": false, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ // "outDir": "./", /* Redirect output structure to the directory. */ "rootDir": "../ts/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": false, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ "noEmit": true, /* Do not emit outputs. */ // "importHelpers": false, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ "noUnusedLocals": true, /* Report errors on unused locals. */ "noUnusedParameters": true, /* Report errors on unused parameters. */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ /* Source Map Options */ // "sourceRoot": "../ts", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "../ts", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }, "exclude": [ "../node_modules", "../tests", "../build" ], "include": [ "../ts/**/*" ] } Mylas-2.1.14/config/tsup.config.ts000066400000000000000000000003531510307563500167460ustar00rootroot00000000000000import { defineConfig } from "tsup" export default defineConfig({ target: "node14", entry: ["ts/index.ts", "ts/register.ts", "ts/worker.ts"], outDir: "build", format: "cjs", minify: true, splitting: true, clean: true, })Mylas-2.1.14/package.json000066400000000000000000000025621510307563500151640ustar00rootroot00000000000000{ "name": "mylas", "version": "2.1.14", "description": "Mylas is a npm package to make the loading and storing of data from fs easy and reliable.", "main": "build/index.js", "typings": "build/index", "files": [ "build/" ], "exports": { ".": { "types": "./build/index.d.ts", "require": "./build/index.js", "default": "./build/index.js" }, "./register": { "types": "./build/register.d.ts", "require": "./build/register.js", "default": "./build/register.js" } }, "scripts": { "prepack": "npm run build", "test": "jest --config ./tests/jest.config.js", "build": "bash ./config/build.sh" }, "repository": { "type": "git", "url": "git+https://github.com/raouldeheer/Mylas.git" }, "keywords": [ "fs", "data", "json", "loader", "multithreaded", "json-comments", "node-modules" ], "author": "Raoul de Heer", "license": "MIT", "bugs": { "url": "https://github.com/raouldeheer/Mylas/issues" }, "homepage": "https://mylas.js.org/", "devDependencies": { "@types/jest": "^30.0.0", "@types/node": "^24.10.0", "jest": "^30.2.0", "ts-jest": "^29.4.5", "tsup": "^8.5.0", "typescript": "^5.9.3" }, "engines": { "node": ">=16.0.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/raouldeheer" } } Mylas-2.1.14/tests/000077500000000000000000000000001510307563500140335ustar00rootroot00000000000000Mylas-2.1.14/tests/buffer.test.ts000066400000000000000000000031061510307563500166320ustar00rootroot00000000000000import mylas from "../build/index.js"; import fs from "fs"; const testData = Buffer.from("Test data"); const testDataPath = "./tests/buffertestdata.txt"; const testDataPathAsync = "./tests/buffertestfileasync.txt"; beforeAll(() => { fs.writeFileSync(testDataPath, testData, "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem async", async () => { await mylas.buf.saveW(testDataPathAsync, testData); /** data should now be saved */ const data = await mylas.buf.loadW(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { mylas.buf.saveW(testDataPathAsync, testData, () => { /** data should now be saved */ mylas.buf.loadW(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem async", async () => { const data = await mylas.buf.loadW(testDataPath); expect(data).toStrictEqual(testData); }); test("Should load the data from the filesystem async with callback", done => { mylas.buf.loadW(testDataPath, data => { expect(data).toStrictEqual(testData); done(); }); }); }); Mylas-2.1.14/tests/dir.test.ts000066400000000000000000000064501510307563500161440ustar00rootroot00000000000000import mylas, { Dir } from "../build/index.js"; import fs from "fs"; const testDataPathDir = "./tests/testdir/"; const testDataPathDirAsync = "./tests/testdirasync/"; const testDataPathDirSync = "./tests/testdirsync/"; const testDataPathDir2 = "./tests/testdir2/"; const testDataPathDirAsync2 = "./tests/testdirasync2/"; const testDataPathDirSync2 = "./tests/testdirsync2/"; describe("Make and remove dir on fs", () => { test("Should create and remove dir", done => { mylas.dir.mk(testDataPathDir, () => { expect(fs.existsSync(testDataPathDir)).toBeTruthy(); mylas.dir.check(testDataPathDir, (result) => { expect(result).toBeTruthy(); mylas.dir.rm(testDataPathDir, () => { expect(fs.existsSync(testDataPathDir)).toBeFalsy(); mylas.dir.check(testDataPathDir, (result2) => { expect(result2).toBeFalsy(); done(); }); }); }); }); }); it("Should create and remove dir", async () => { await mylas.dir.mk(testDataPathDirAsync); expect(fs.existsSync(testDataPathDirAsync)).toBeTruthy(); expect(await mylas.dir.check(testDataPathDirAsync)).toBeTruthy(); await mylas.dir.rm(testDataPathDirAsync); expect(fs.existsSync(testDataPathDirAsync)).toBeFalsy(); expect(await mylas.dir.check(testDataPathDirAsync)).toBeFalsy(); }); it("Should create and remove dir", () => { mylas.dir.mkS(testDataPathDirSync); expect(fs.existsSync(testDataPathDirSync)).toBeTruthy(); expect(mylas.dir.checkS(testDataPathDirSync)).toBeTruthy(); mylas.dir.rmS(testDataPathDirSync); expect(fs.existsSync(testDataPathDirSync)).toBeFalsy(); expect(mylas.dir.checkS(testDataPathDirSync)).toBeFalsy(); }); }); describe("Make and remove dir on fs", () => { test("Should create and remove dir", done => { Dir.mk(testDataPathDir2, () => { expect(fs.existsSync(testDataPathDir2)).toBeTruthy(); Dir.check(testDataPathDir2, (result) => { expect(result).toBeTruthy(); Dir.rm(testDataPathDir2, () => { expect(fs.existsSync(testDataPathDir2)).toBeFalsy(); Dir.check(testDataPathDir2, (result2) => { expect(result2).toBeFalsy(); done(); }); }); }); }); }); it("Should create and remove dir", async () => { await Dir.mk(testDataPathDirAsync2); expect(fs.existsSync(testDataPathDirAsync2)).toBeTruthy(); expect(await Dir.check(testDataPathDirAsync2)).toBeTruthy(); await Dir.rm(testDataPathDirAsync2); expect(fs.existsSync(testDataPathDirAsync2)).toBeFalsy(); expect(await Dir.check(testDataPathDirAsync2)).toBeFalsy(); }); it("Should create and remove dir", () => { Dir.mkS(testDataPathDirSync2); expect(fs.existsSync(testDataPathDirSync2)).toBeTruthy(); expect(Dir.checkS(testDataPathDirSync2)).toBeTruthy(); Dir.rmS(testDataPathDirSync2); expect(fs.existsSync(testDataPathDirSync2)).toBeFalsy(); expect(Dir.checkS(testDataPathDirSync2)).toBeFalsy(); }); }); Mylas-2.1.14/tests/file.test.ts000066400000000000000000000040201510307563500162740ustar00rootroot00000000000000import { File } from "../build/index.js"; import fs from "fs"; const testData = "Test data"; const testDataPath = "./tests/filetestdata.txt"; const testDataPathSync = "./tests/filetestfilesync.txt"; const testDataPathAsync = "./tests/filetestfileasync.txt"; beforeAll(() => { fs.writeFileSync(testDataPath, testData, "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem", () => { File.saveS(testDataPathSync, testData); /** data should now be saved */ const data = File.loadS(testDataPathSync); fs.unlinkSync(testDataPathSync); expect(data).toStrictEqual(testData); }); it("Should save the data to the filesystem async", async () => { await File.save(testDataPathAsync, testData); /** data should now be saved */ const data = await File.load(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { File.save(testDataPathAsync, testData, () => { /** data should now be saved */ File.load(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem", () => { const data = File.loadS(testDataPath); expect(data).toStrictEqual(testData); }); it("Should load the data from the filesystem async", async () => { const data = await File.load(testDataPath); expect(data).toStrictEqual(testData); }); test("Should load the data from the filesystem async with callback", done => { File.load(testDataPath, data => { expect(data).toStrictEqual(testData); done(); }); }); }); Mylas-2.1.14/tests/file.workers.test.ts000066400000000000000000000031071510307563500177740ustar00rootroot00000000000000import mylas from "../build/index.js"; import fs from "fs"; const testData = "Test data"; const testDataPath = "./tests/fileworkertestdata.txt"; const testDataPathAsync = "./tests/fileworkertestfileasync.txt"; beforeAll(() => { fs.writeFileSync(testDataPath, testData, "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem async", async () => { await mylas.file.saveW(testDataPathAsync, testData); /** data should now be saved */ const data = await mylas.file.loadW(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { mylas.file.saveW(testDataPathAsync, testData, () => { /** data should now be saved */ mylas.file.loadW(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem async", async () => { const data = await mylas.file.loadW(testDataPath); expect(data).toStrictEqual(testData); }); test("Should load the data from the filesystem async with callback", done => { mylas.file.loadW(testDataPath, data => { expect(data).toStrictEqual(testData); done(); }); }); }); Mylas-2.1.14/tests/findDepTest/000077500000000000000000000000001510307563500162445ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/findDeps.test.ts000066400000000000000000000034771510307563500213410ustar00rootroot00000000000000import { Dir } from "../../build/index.js"; const testFunc = (testCases: any[]) => { testCases.forEach((v) => { it(`Should find ${v[0]} or more folders`, () => { expect(Dir.nodeModules(v[1]).length).toBeGreaterThanOrEqual(v[0]); }); }); }; describe("Find node modules, string input", () => { testFunc([ [1, null], [1, process.cwd() + "/tests/findDepTest"], [2, process.cwd() + "/tests/findDepTest/test_dir"], [3, process.cwd() + "/tests/findDepTest/test_dir/test_dir2"], ]); }); describe("Find node modules, options absolute input", () => { testFunc([ [1, { cwd: process.cwd(), relative: false }], [1, { cwd: process.cwd() + "/tests/findDepTest", relative: false }], [2, { cwd: process.cwd() + "/tests/findDepTest/test_dir", relative: false }], [3, { cwd: process.cwd() + "/tests/findDepTest/test_dir/test_dir2", relative: false }], ]); }); describe("Find node modules, options relative input", () => { testFunc([ [1, { cwd: process.cwd(), relative: true }], [1, { cwd: process.cwd() + "/tests/findDepTest", relative: true }], [2, { cwd: process.cwd() + "/tests/findDepTest/test_dir", relative: true }], [3, { cwd: process.cwd() + "/tests/findDepTest/test_dir/test_dir2", relative: true }], ]); }); describe("Find node modules, options only cwd input", () => { testFunc([ [1, { cwd: process.cwd() }], [1, { cwd: process.cwd() + "/tests/findDepTest" }], [2, { cwd: process.cwd() + "/tests/findDepTest/test_dir" }], [3, { cwd: process.cwd() + "/tests/findDepTest/test_dir/test_dir2" }], ]); }); describe("Find node modules, options only relative input", () => { testFunc([ [1, { relative: true }], [1, { relative: false }], ]); });Mylas-2.1.14/tests/findDepTest/node_modules/000077500000000000000000000000001510307563500207215ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/node_modules/.keep000066400000000000000000000000001510307563500216340ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/test_dir/000077500000000000000000000000001510307563500200615ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/test_dir/node_modules/000077500000000000000000000000001510307563500225365ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/test_dir/node_modules/.keep000066400000000000000000000000001510307563500234510ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/test_dir/test_dir2/000077500000000000000000000000001510307563500217605ustar00rootroot00000000000000Mylas-2.1.14/tests/findDepTest/test_dir/test_dir2/.keep000066400000000000000000000000001510307563500226730ustar00rootroot00000000000000Mylas-2.1.14/tests/jest.config.js000066400000000000000000000001561510307563500166040ustar00rootroot00000000000000module.exports = { preset: 'ts-jest', testEnvironment: 'node', globals: { 'ts-jest': { } } }; Mylas-2.1.14/tests/json.test.ts000066400000000000000000000110661510307563500163360ustar00rootroot00000000000000import mylas, { Json } from "../build/index"; import fs from "fs"; import "../build/register"; const testJson = [{ "Test": "Data" }]; const testJsonPath = "./tests/testdata.json"; const testJsonPathSync = "./tests/testfilesync.json"; const testJsonPathSync2 = "./tests/testfilesync.json"; const testJsonPathAsync = "./tests/testfileasync.json"; beforeAll(() => { fs.writeFileSync(testJsonPath, JSON.stringify(testJson), "utf8"); }); afterAll(() => { fs.unlinkSync(testJsonPath); }); /** Json tests */ describe("Save jsonfile to test folder", () => { it("Should save the jsondata to the filesystem", () => { mylas.json.saveS(testJsonPathSync, testJson); /** data should now be saved */ const data = mylas.json.loadS(testJsonPathSync); fs.unlinkSync(testJsonPathSync); expect(data).toStrictEqual(testJson); }); it("Should save the jsondata to the filesystem", () => { JSON.saveS(testJsonPathSync2, testJson); /** data should now be saved */ const data = JSON.loadS(testJsonPathSync2); fs.unlinkSync(testJsonPathSync2); expect(data).toStrictEqual(testJson); }); it("Should save the jsondata to the filesystem async", async () => { await mylas.json.save(testJsonPathAsync, testJson); /** data should now be saved */ const data = await mylas.json.load(testJsonPathAsync); fs.unlinkSync(testJsonPathAsync); expect(data).toStrictEqual(testJson); }); test("Should save the jsondata to the filesystem async with callback", done => { mylas.json.save(testJsonPathAsync, testJson, () => { /** data should now be saved */ mylas.json.load(testJsonPathAsync, data => { fs.unlinkSync(testJsonPathAsync); expect(data).toStrictEqual(testJson); done(); }); }); }); }); describe("Load jsonfile from test folder", () => { it("Should load the jsondata from the filesystem", () => { const data = mylas.json.loadS(testJsonPath); expect(data).toStrictEqual(testJson); }); it("Should load the jsondata from the filesystem and remove comments", () => { const data = mylas.json.loadS("./config/tsconfig.json", true); expect(data).toBeDefined(); }); it("Should load the jsondata from the filesystem and remove comments", async () => { const data = await mylas.json.load("./config/tsconfig.json", undefined, true); expect(data).toBeDefined(); }); it("Should load the data from the filesystem async", async () => { const data = await mylas.json.load(testJsonPath); expect(data).toStrictEqual(testJson); }); test("Should load the data from the filesystem async with callback", done => { mylas.json.load(testJsonPath, data => { expect(data).toStrictEqual(testJson); done(); }); }); }); describe("Save jsonfile to test folder using Json", () => { it("Should save the jsondata to the filesystem", () => { Json.saveS(testJsonPathSync, testJson); /** data should now be saved */ const data = Json.loadS(testJsonPathSync); fs.unlinkSync(testJsonPathSync); expect(data).toStrictEqual(testJson); }); it("Should save the jsondata to the filesystem async", async () => { await Json.save(testJsonPathAsync, testJson); /** data should now be saved */ const data = await Json.load(testJsonPathAsync); fs.unlinkSync(testJsonPathAsync); expect(data).toStrictEqual(testJson); }); test("Should save the jsondata to the filesystem async with callback", done => { Json.save(testJsonPathAsync, testJson, () => { /** data should now be saved */ Json.load(testJsonPathAsync, data => { fs.unlinkSync(testJsonPathAsync); expect(data).toStrictEqual(testJson); done(); }); }); }); }); describe("Load jsonfile from test folder using Json", () => { it("Should load the jsondata from the filesystem", () => { const data = Json.loadS(testJsonPath); expect(data).toStrictEqual(testJson); }); it("Should load the data from the filesystem async", async () => { const data = await Json.load(testJsonPath); expect(data).toStrictEqual(testJson); }); test("Should load the data from the filesystem async with callback", done => { Json.load(testJsonPath, data => { expect(data).toStrictEqual(testJson); done(); }); }); }); Mylas-2.1.14/tests/json.workers.test.ts000066400000000000000000000033761510307563500200360ustar00rootroot00000000000000import { Json } from "../build/index.js"; import fs from "fs"; const testData = [{ Test: "Data" }]; const testDataPath = "./tests/jsonworkertestdata.json"; const testDataPathAsync = "./tests/jsonworkertestfileasync.json"; beforeAll(() => { fs.writeFileSync(testDataPath, JSON.stringify(testData), "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem async", async () => { await Json.saveW(testDataPathAsync, testData); /** data should now be saved */ const data = await Json.loadW(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { Json.saveW(testDataPathAsync, testData, () => { /** data should now be saved */ Json.loadW(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem async", async () => { const data = await Json.loadW(testDataPath); expect(data).toEqual(testData); }); it("Should load the jsondata from the filesystem and remove comments", async () => { const data = await Json.loadW("./config/tsconfig.json", undefined, true); expect(data).toBeDefined(); }); test("Should load the data from the filesystem async with callback", done => { Json.loadW(testDataPath, data => { expect(data).toEqual(testData); done(); }); }); }); Mylas-2.1.14/tests/main.test.ts000066400000000000000000000040121510307563500163020ustar00rootroot00000000000000import mylas from "../build/index.js"; import fs from "fs"; const testData = "Test data"; const testDataPath = "./tests/testdata.txt"; const testDataPathSync = "./tests/testfilesync.txt"; const testDataPathAsync = "./tests/testfileasync.txt"; beforeAll(() => { fs.writeFileSync(testDataPath, testData, "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem", () => { mylas.saveS(testDataPathSync, testData); /** data should now be saved */ const data = mylas.loadS(testDataPathSync); fs.unlinkSync(testDataPathSync); expect(data).toStrictEqual(testData); }); it("Should save the data to the filesystem async", async () => { await mylas.save(testDataPathAsync, testData); /** data should now be saved */ const data = await mylas.load(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { mylas.save(testDataPathAsync, testData, () => { /** data should now be saved */ mylas.load(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem", () => { const data = mylas.loadS(testDataPath); expect(data).toStrictEqual(testData); }); it("Should load the data from the filesystem async", async () => { const data = await mylas.load(testDataPath); expect(data).toStrictEqual(testData); }); test("Should load the data from the filesystem async with callback", done => { mylas.load(testDataPath, data => { expect(data).toStrictEqual(testData); done(); }); }); }); Mylas-2.1.14/tests/tsconfig.json000066400000000000000000000007341510307563500165460ustar00rootroot00000000000000{ "compilerOptions": { "incremental": false, "target": "ES2017", "module": "commonjs", "rootDir": "../ts/", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true } }Mylas-2.1.14/tests/workers.test.ts000066400000000000000000000030411510307563500170530ustar00rootroot00000000000000import mylas from "../build/index.js"; import fs from "fs"; const testData = "Test data"; const testDataPath = "./tests/workertestdata.txt"; const testDataPathAsync = "./tests/workertestfileasync.txt"; beforeAll(() => { fs.writeFileSync(testDataPath, testData, "utf8"); }); afterAll(() => { fs.unlinkSync(testDataPath); }); /** file tests */ describe("Save file to test folder", () => { it("Should save the data to the filesystem async", async () => { await mylas.saveW(testDataPathAsync, testData); /** data should now be saved */ const data = await mylas.loadW(testDataPathAsync); fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); }); test("Should save the data to the filesystem async with callback", done => { mylas.saveW(testDataPathAsync, testData, () => { /** data should now be saved */ mylas.loadW(testDataPathAsync, data => { fs.unlinkSync(testDataPathAsync); expect(data).toStrictEqual(testData); done(); }); }); }); }); describe("Load file from test folder", () => { it("Should load the data from the filesystem async", async () => { const data = await mylas.loadW(testDataPath); expect(data).toStrictEqual(testData); }); test("Should load the data from the filesystem async with callback", done => { mylas.loadW(testDataPath, data => { expect(data).toStrictEqual(testData); done(); }); }); }); Mylas-2.1.14/ts/000077500000000000000000000000001510307563500133175ustar00rootroot00000000000000Mylas-2.1.14/ts/buf.ts000066400000000000000000000045431510307563500144510ustar00rootroot00000000000000import fs from "fs"; import { objectCallback, voidCallback, Method, } from "./types"; import { checkPath, } from "./checks"; import action from "./workerActions"; const buf = { /** * loads string data from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @return {Promise} */ load: async ( path: string, callback?: objectCallback ): Promise => { if (await checkPath(path)) { const data = await fs.promises.readFile(path); callback?.(data); return data; } else { throw new Error(`Can't read from ${path}`); } }, /** * saves string to file. * @param {string} path path to save to. * @param {Buffer} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: async ( path: string, data: Buffer, callback?: voidCallback ): Promise => { if (await checkPath(path)) { await fs.promises.writeFile(path, data); callback?.(); } else { throw new Error(`Can't write to ${path}`); } }, /** * loads string data from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. */ loadW: async ( path: string, callback?: objectCallback ): Promise => { const array = await action({ method: Method.loadBuffer, path: path, }); callback?.(Buffer.from(array)); return Buffer.from(array); }, /** * saves string to file. * @param {string} path path to save to. * @param {Buffer} data data to save. * @param {voidCallback} callback callback to call. */ saveW: async ( path: string, data: Buffer, callback?: voidCallback, ): Promise => { const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(data.byteLength)); sharedUint8Array.set(data); await action({ method: Method.saveBuffer, path: path, data: sharedUint8Array, callback: callback }); }, }; export default buf; Mylas-2.1.14/ts/checks.ts000066400000000000000000000021161510307563500151270ustar00rootroot00000000000000import { existsSync, mkdirSync } from "fs"; import { parse } from "path"; /** * checks if dirPath exists. * @param {string} path path to check. * @return {boolean} */ export const checkPathSync = ( path: string, ): boolean => { /** check if dir exists */ if (!checkDir(path)) return false; return true;// all checks good return true }; /** * checks if dirPath exists. * @param {string} path path to check. * @return {Promise} */ export const checkPath = async ( path: string, ): Promise => { /** check if dir exists */ if (!checkDir(path)) return false; return true; // all checks good return true }; /** * checks if the path.dir exist. if false make dir. * @param {string} path path for dir to check. * @return {boolean} */ const checkDir = ( path: string ): boolean => { /** check if dir exists */ const dir = parse(path).dir; //check if path doesn't have dir or if path exists if (!(dir == '' || existsSync(dir))) mkdirSync(dir, { recursive: true }); return existsSync(dir); // check if path doesn't exists }; Mylas-2.1.14/ts/dir.ts000066400000000000000000000054351510307563500144540ustar00rootroot00000000000000import fs from "fs"; import findDeps from "./find-dependencies"; import { booleanCallback, voidCallback, } from "./types"; import { checkPathSync, checkPath, } from "./checks"; const dir = { /** * makes fs dir sync * @param {string} path path to dir * @return {void} */ mkS: (path: string): void => { if (checkPathSync(path)) fs.mkdirSync(path, { recursive: true }); }, /** * removes fs dir sync * @param {string} path path to dir * @return {void} */ rmS: (path: string): void => { if (checkPathSync(path)) { // node version 12 compatibility if (process.versions.node.startsWith("12")) { fs.rmdirSync(path, { recursive: true }); } else { fs.rmSync(path, { recursive:true, force: true }); } } }, /** * checks if dir exists sync. * @param {string} path path to dir. * @return {boolean} */ checkS: (path: string): boolean => fs.existsSync(path), /** * makes fs dir * @param {string} path path to dir * @param {voidCallback} callback callback to call. * @return {Promise} */ mk: async ( path: string, callback?: voidCallback ): Promise => { if (await checkPath(path)) await fs.promises.mkdir(path, { recursive: true }); callback?.(); } , /** * removes fs dir * @param {string} path path to dir * @param {voidCallback} callback callback to call. * @return {Promise} */ rm: async ( path: string, callback?: voidCallback ): Promise => { if (await checkPath(path)) { // node version 12 compatibility if (process.versions.node.startsWith("12")) { await fs.promises.rmdir(path, { recursive: true }); } else { await fs.promises.rm(path, { recursive:true, force: true }); } } callback?.(); }, /** * checks if dir exists. * @param {string} path path to dir. * @param {booleanCallback} callback callback to call. * @return {Promise} */ check: async ( path: string, callback?: booleanCallback ): Promise => { const response = fs.existsSync(path); callback?.(response); return response; }, /** * NodeModules finds where the node_modules directories are. * @param {{ cwd?: string; relative?: boolean; } | string} input optional cwd input. * @returns an array of locations where node_modules is found. */ nodeModules: (input?: { cwd?: string; relative?: boolean; } | string): string[] => findDeps(input), }; export default dir; Mylas-2.1.14/ts/dts/000077500000000000000000000000001510307563500141115ustar00rootroot00000000000000Mylas-2.1.14/ts/dts/index.d.ts000066400000000000000000000005641510307563500160170ustar00rootroot00000000000000import { BufT, DirT, FileT, JsonT, } from "./interfaces"; declare interface MylasT extends FileT { json: JsonT; file: FileT; dir: DirT; buf: BufT; } declare const Mylas: MylasT; declare const Json: JsonT; declare const File: FileT; declare const Dir: DirT; declare const Buf: BufT; export default Mylas; export { Json, Dir, File, Buf }; Mylas-2.1.14/ts/dts/interfaces.d.ts000066400000000000000000000160051510307563500170300ustar00rootroot00000000000000declare type voidCallback = () => void; declare type stringCallback = (arg0: string) => void; declare type objectCallback = (arg0: T) => void; declare type booleanCallback = (arg0: boolean) => void; declare interface JsonT { /** * loads JSON from file sync. * @param {string} path path to load from. * @param {boolean} hasComments file to load has comments in json. * @return {T} */ loadS: (path: string, hasComments?: boolean) => T; /** * saves JSON data to file sync. * @param {string} path path to save to. * @param {T} data data to save. * @return {void} */ saveS: (path: string, data: T) => void; /** * loads JSON from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @param {boolean} hasComments file to load has comments in json. * @return {Promise} */ load: (path: string, callback?: objectCallback | undefined, hasComments?: boolean) => Promise; /** * saves JSON data to file. * @param {string} path path to save to. * @param {T} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: (path: string, data: T, callback?: voidCallback | undefined) => Promise; /** * loads JSON from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @param {boolean} hasComments file to load has comments in json. */ loadW: (path: string, callback?: objectCallback | undefined, hasComments?: boolean) => Promise; /** * saves JSON data to file. * @param {string} path path to save to. * @param {T} data data to save. * @param {voidCallback} callback callback to call. */ saveW: (path: string, data: T, callback?: voidCallback | undefined) => Promise; } declare interface StringSave { /** * saves string to file sync. * @param {string} path path to save to. * @return {void} */ saveS: (path: string) => void; /** * saves string to file async. * @param {string} path path to save to. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: (path: string, callback?: voidCallback | undefined) => Promise; /** * saves string to file with worker. * @param {string} path path to save to. * @param {voidCallback} callback callback to call. */ saveW: (path: string, callback?: voidCallback | undefined) => Promise; } declare interface FileT { /** * loads string data from file sync. * @param {string} path path to load from. * @return {string} */ loadS: (path: string) => string; /** * loads string data from file async. * @param {string} path path to load from. * @param {stringCallback} callback callback to call. * @return {Promise} */ load: (path: string, callback?: stringCallback | undefined) => Promise; /** * loads string data from file with worker. * @param {string} path path to load from. * @param {stringCallback} callback callback to call. */ loadW: (path: string, callback?: stringCallback | undefined) => Promise; /** * saves string to file sync. * @param {string} path path to save to. * @param {string} data data to save. * @return {void} */ saveS: (path: string, data: string) => void; /** * saves string to file async. * @param {string} path path to save to. * @param {string} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: (path: string, data: string, callback?: voidCallback | undefined) => Promise; /** * saves string to file with worker. * @param {string} path path to save to. * @param {string} data data to save. * @param {voidCallback} callback callback to call. */ saveW: (path: string, data: string, callback?: voidCallback | undefined) => Promise; } declare interface DirT { /** * Creates directory on filesystem synchronous. * @param {string} path path to dir * @return {void} */ mkS: (path: string) => void; /** * Removes directory on filesystem synchronous. * @param {string} path path to dir * @return {void} */ rmS: (path: string) => void; /** * Checks if directory exists on filesystem synchronous. * @param {string} path path to dir. * @return {boolean} */ checkS: (path: string) => boolean; /** * Creates directory on filesystem asynchronous. * @param {string} path path to dir * @param {voidCallback} callback callback to call. * @return {Promise} */ mk: (path: string, callback?: voidCallback | undefined) => Promise; /** * Removes directory on filesystem asynchronous. * @param {string} path path to dir * @param {voidCallback} callback callback to call. * @return {Promise} */ rm: (path: string, callback?: voidCallback | undefined) => Promise; /** * Checks if directory exists on filesystem asynchronous. * @param {string} path path to dir. * @param {booleanCallback} callback callback to call. * @return {Promise} */ check: (path: string, callback?: booleanCallback | undefined) => Promise; /** * NodeModules finds where the node_modules directories are. * @param {{ cwd?: string; relative?: boolean; } | string} input optional cwd input. * @returns an array of locations where node_modules is found. */ nodeModules: (input?: { cwd?: string; relative?: boolean; } | string) => string[]; } declare interface BufT { /** * loads buffer data from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @return {Promise} */ load: (path: string, callback?: objectCallback | undefined) => Promise; /** * saves buffer to file. * @param {string} path path to save to. * @param {Buffer} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: (path: string, data: Buffer, callback?: voidCallback | undefined) => Promise; /** * loads buffer data from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. */ loadW: (path: string, callback?: objectCallback | undefined) => Promise; /** * saves buffer to file. * @param {string} path path to save to. * @param {Buffer} data data to save. * @param {voidCallback} callback callback to call. */ saveW: (path: string, data: Buffer, callback?: voidCallback | undefined) => Promise; } export { FileT, JsonT, StringSave, BufT, DirT, }; Mylas-2.1.14/ts/dts/register.d.ts000066400000000000000000000003351510307563500165300ustar00rootroot00000000000000import { FileT, JsonT, StringSave } from "./interfaces"; declare global { interface JSON extends JsonT { } interface StringConstructor extends FileT { } interface String extends StringSave { } } export { }; Mylas-2.1.14/ts/file.ts000066400000000000000000000054541510307563500146160ustar00rootroot00000000000000import fs from "fs"; import { stringCallback, voidCallback, Method, } from "./types"; import { checkPathSync, checkPath, } from "./checks"; import action from "./workerActions"; const file = { /** * loads string data from file. * @param {string} path path to load from. * @return {string} */ loadS: ( path: string, ): string => { if (checkPathSync(path)) { return fs.readFileSync(path, "utf8"); } else { throw new Error(`Can't read from ${path}`); } }, /** * saves string to file. * @param {string} path path to save to. * @param {string} data data to save. * @return {void} */ saveS: ( path: string, data: string, ): void => { if (checkPathSync(path)) { fs.writeFileSync(path, data, "utf8"); } else { throw new Error(`Can't write to ${path}`); } }, /** * loads string data from file. * @param {string} path path to load from. * @param {stringCallback} callback callback to call. * @return {Promise} */ load: async ( path: string, callback?: stringCallback, ): Promise => { if (await checkPath(path)) { const data = await fs.promises.readFile(path, "utf8"); callback?.(data); return data; } else { throw new Error(`Can't read from ${path}`); } }, /** * saves string to file. * @param {string} path path to save to. * @param {string} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: async ( path: string, data: string, callback?: voidCallback, ): Promise => { if (await checkPath(path)) { await fs.promises.writeFile(path, data, "utf8"); callback?.(); } else { throw new Error(`Can't write to ${path}`); } }, /** * loads string data from file. * @param {string} path path to load from. * @param {stringCallback} callback callback to call. */ loadW: ( path: string, callback?: stringCallback, ): Promise => action({ method: Method.loadFile, path: path, callback: callback, }), /** * saves string to file. * @param {string} path path to save to. * @param {string} data data to save. * @param {voidCallback} callback callback to call. */ saveW: ( path: string, data: string, callback?: voidCallback, ): Promise => action({ method: Method.saveFile, path: path, data: data, callback: callback, }), }; export default file; Mylas-2.1.14/ts/find-dependencies.ts000066400000000000000000000165331510307563500172430ustar00rootroot00000000000000import fs from "fs"; import path from "path"; import os from "os"; export default function (input?: { cwd?: string; relative?: boolean; } | string): string[] { const opts = { cwd: process.cwd(), relative: true, ...(typeof input === "string" ? { cwd: input } : input), }; const results: string[] = []; let schDr = opts.cwd; let modDr: string | null; let df = false; do { if (schDr.charAt(0) === "~") schDr = tilde(schDr); if (schDr.charAt(0) === "@") schDr = path.join(gm || (gm = isWin ? path.resolve(prefix || (prefix = getPrefix()), "node_modules") : path.resolve(prefix || (prefix = getPrefix()), "lib/node_modules")), schDr.slice(1)); modDr = lookup(schDr); if (modDr) { const fmd = opts.relative ? path.relative(opts.cwd, modDr) : modDr; df = results.indexOf(fmd) > -1; if (!df) { results.push(fmd); schDr = path.join(modDr, "../../"); } } } while (modDr && !df); return results; } function lookup(cwd: string): string | null { const fp = path.resolve(cwd, "node_modules"); const res = fs.existsSync(fp) ? path.resolve(fp) : null; if (res) return res; const dir = path.dirname(cwd); return dir === cwd ? null : lookup(dir); } let gm: string; let prefix: string; function getPrefix(): string { if (process.env.PREFIX) { prefix = process.env.PREFIX; } else { prefix = confPath(path.resolve(os.homedir(), ".npmrc")); if (!prefix) { try { prefix = confPath(path.resolve(file(), "..", "..", "npmrc")); if (prefix) prefix = confPath(path.resolve(prefix, "etc", "npmrc")) || prefix; } catch (_) { /* Do nothing */ } if (!prefix) { if (isWin) { prefix = process.env.APPDATA ? path.join(process.env.APPDATA, "npm") : path.dirname(process.execPath); } else { prefix = path.dirname(path.dirname(process.execPath)); if (process.env.DESTDIR) prefix = path.join(process.env.DESTDIR, prefix); } } } } return prefix ? tilde(prefix) : ""; } function confPath(configPath: string) { try { return inip(fs.readFileSync(configPath, "utf-8"))?.prefix; } catch (err) { return null; } } function inip(str: string) { const out = Object.create(null); let p = out; let section: any = null; for (const line of str.split(/[\r\n]+/g)) { if (!line || line.match(/^\s*[;#]/)) continue; const match = line.match(/^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i); if (!match) continue; if (match[1] !== undefined) { section = decode(match[1]); if (section === "__proto__") { p = Object.create(null); continue; } p = out[section] = out[section] || Object.create(null); continue; } const keyRaw = decode(match[2] || ""); const isArray = keyRaw.length > 2 && keyRaw.slice(-2) === "[]"; const key = isArray ? keyRaw.slice(0, -2) : keyRaw; if (key === "__proto__") continue; const valueRaw = match[3] ? decode(match[4] || "") : true; const value = valueRaw === "true" || valueRaw === "false" || valueRaw === "null" ? JSON.parse(valueRaw) : valueRaw; if (isArray) { if (!Object.hasOwnProperty.call(p, key)) p[key] = []; else if (!Array.isArray(p[key])) p[key] = [p[key]]; } if (Array.isArray(p[key])) p[key].push(value); else p[key] = value; } const remove: string[] = []; for (const j of Object.keys(out)) { if (!Object.hasOwnProperty.call(out, j) || typeof out[j] !== "object" || Array.isArray(out[j])) continue; // @ts-ignore const parts = j.replace(/\1/g, "\u0002LITERAL\\1LITERAL\u0002").replace(/\\\./g, "\u0001").split(/\./) // @ts-ignore .map(part => part.replace(/\1/g, "\\.").replace(/\2LITERAL\\1LITERAL\2/g, "\u0001")); let p = out; const l = parts.pop() || ""; const nl = l.replace(/\\\./g, "."); for (const part of parts) { if (part === "__proto__") continue; if (!Object.hasOwnProperty.call(p, part) || typeof p[part] !== "object") p[part] = Object.create(null); p = p[part]; } if (p === out && nl === l) continue; p[nl] = out[j]; remove.push(j); } remove.forEach(d => delete out[d]); return out; } function decode(str: string) { str = str.trim(); const c1 = str.charAt(0), c2 = str.charAt(str.length - 1); if ((c1 === "\"" && c2 === "\"") || (c1 === "'" && c2 === "'")) { str = c1 === "'" ? str.substr(1, str.length - 2) : str; try { return JSON.parse(str); } catch (_) { /* Do nothing */ } } else { let esc = false, unesc = ""; for (let i = 0; i < str.length; i++) { const c = str.charAt(i); if (esc) { if ("\\;#".indexOf(c) !== -1) unesc += c; else unesc += "\\" + c; esc = false; } else if (";#".indexOf(c) !== -1) break; else if (c === "\\") esc = true; else unesc += c; } if (esc) unesc += "\\"; return unesc.trim(); } return str; } const tilde = (fp: string) => fp.charAt(0) === "~" ? fp.charAt(1) === "+" ? path.join(process.cwd(), fp.slice(2)) : path.join(os.homedir(), fp.slice(1)) : fp; const isWin = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys"; function file(): string { const env = (process.env.PATH || "").split(isWin ? ";" : ":"); let ext = [""]; if (isWin) { env.unshift(process.cwd()); ext = (process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";"); } for (const envi of env) { const part = path.join( (envi.charAt(0) === "\"" && envi.slice(-1) === "\"") ? envi.slice(1, -1) : envi, "npm"); for (const exti of ext) if (isexesync(part + exti)) return fs.realpathSync(part + exti); } throw new Error("Can't find npm file"); } function isexesync(path: string) { try { return (isWin ? (path: string) => { const stat = fs.statSync(path); if (!stat.isSymbolicLink() && !stat.isFile()) return false; if (!process.env.PATHEXT) return true; const pathext = process.env.PATHEXT.split(";"); if (pathext.indexOf("") !== -1) return true; for (const pathexti of pathext) { const p = pathexti.toLowerCase(); if (p && path.substr(-p.length).toLowerCase() === p) return true; } return false; } : (path: string) => { const { mode, gid, uid, isFile } = fs.statSync(path); return (isFile() && ( (mode & 1) || (mode & 2) && gid === process.getgid!() || (mode & 4) && uid === process.getuid!() || (mode & 6) && process.getuid!() === 0 )); })(path); } catch (_) { return false; } } Mylas-2.1.14/ts/index.ts000066400000000000000000000006131510307563500147760ustar00rootroot00000000000000/** Import all sub-modules */ import Buf from "./buf"; import File from "./file"; import Json from "./json"; import Dir from "./dir"; /** Make module */ const Mylas = { json: Json, file: File, dir: Dir, buf: Buf, ...File, }; /** Export modules */ export default Mylas; export { Json, Dir, File, Buf }; import { Method, Request } from "./types"; export { Method, Request };Mylas-2.1.14/ts/json.ts000066400000000000000000000112031510307563500146350ustar00rootroot00000000000000import { objectCallback, voidCallback, Method, } from "./types"; import file from "./file"; import action from "./workerActions"; const json = { /** * loads JSON from file sync. * @param {string} path path to load from. * @param {boolean} hasComments file to load has comments in json. * @return {T} */ loadS: ( path: string, hasComments = false, ): T => JSON.parse(hasComments ? removeComments(file.loadS(path)) : file.loadS(path)), /** * saves JSON data to file sync. * @param {string} path path to save to. * @param {T} data data to save. * @return {void} */ saveS: ( path: string, data: T, ): void => file.saveS(path, JSON.stringify(data)), /** * loads JSON from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @param {boolean} hasComments file to load has comments in json. * @return {Promise} */ load: async ( path: string, callback?: objectCallback, hasComments = false, ): Promise => { const data: T = JSON.parse(hasComments ? removeComments(await file.load(path)) : await file.load(path)); callback?.(data); return data; }, /** * saves JSON data to file. * @param {string} path path to save to. * @param {T} data data to save. * @param {voidCallback} callback callback to call. * @return {Promise} */ save: async ( path: string, data: T, callback?: voidCallback, ): Promise => { await file.save(path, JSON.stringify(data)); callback?.(); }, /** * loads JSON from file. * @param {string} path path to load from. * @param {objectCallback} callback callback to call. * @param {boolean} hasComments file to load has comments in json. */ loadW: ( path: string, callback?: objectCallback, hasComments = false, ): Promise => action({ method: hasComments ? Method.loadJsonComments : Method.loadJson, path: path, callback: callback, }), /** * saves JSON data to file. * @param {string} path path to save to. * @param {T} data data to save. * @param {voidCallback} callback callback to call. */ saveW: ( path: string, data: T, callback?: voidCallback, ): Promise => action({ method: Method.saveJson, path: path, data: data, callback: callback, }), }; export default json; function removeComments(jsonString: string): string { const isNotEscaped = (string: string, quotePosition: number) => { let backslashCount = 0; while (string[quotePosition] === '\\') { quotePosition--; backslashCount++; } return !(backslashCount % 2); }; let isInsideString = false; let isInsideSComment = false; let isInsideMComment = false; let offset = 0; let result = ""; for (let i = 0; i < jsonString.length; i++) { const currentCharacter = jsonString[i] || ""; const nextCharacter = jsonString[i + 1] || ""; const isOutsideComment = !(isInsideMComment || isInsideSComment); if (isOutsideComment && currentCharacter === "\"" && isNotEscaped(jsonString, i-1)) isInsideString = !isInsideString; if (isInsideString) continue; const currNextCharacter = currentCharacter + nextCharacter; if (isOutsideComment && currNextCharacter === "//") { result += jsonString.slice(offset, i); offset = i; isInsideSComment = true; i++; } else if (isInsideSComment && currNextCharacter === "\r\n") { i++; isInsideSComment = false; offset = i; continue; } else if (isInsideSComment && currentCharacter === "\n") { isInsideSComment = false; offset = i; } else if (isOutsideComment && currNextCharacter === "/*") { result += jsonString.slice(offset, i); offset = i; isInsideMComment = true; i++; continue; } else if (isInsideMComment && currNextCharacter === "*/") { i++; isInsideMComment = false; offset = i + 1; continue; } } return (result + ((isInsideMComment || isInsideSComment) ? "" : jsonString.slice(offset))).replace(/,(?!\s*?[{["'\w])/g, ""); } Mylas-2.1.14/ts/register.ts000066400000000000000000000037661510307563500155270ustar00rootroot00000000000000import file from "./file"; import json from "./json"; import { voidCallback, stringCallback, objectCallback } from "./types"; // These types are here for tsc to compile. // These types are in index.d.ts for release version. declare global { interface JSON { loadS: (path: string) => T; saveS: (path: string, data: T) => void; load: (path: string, callback?: objectCallback) => Promise; save: (path: string, data: T, callback?: voidCallback) => Promise; loadW: (path: string, callback?: objectCallback) => Promise; saveW: (path: string, data: T, callback?: voidCallback) => Promise; } interface StringConstructor { loadS: (path: string) => string; saveS: (path: string, data: string) => void; load: (path: string, callback?: stringCallback) => Promise; save: (path: string, data: string, callback?: voidCallback) => Promise; loadW: (path: string, callback?: stringCallback) => Promise; saveW: (path: string, data: string, callback?: voidCallback) => Promise; } interface String { saveS: (path: string) => void; save: (path: string, callback?: voidCallback) => Promise; saveW: (path: string, callback?: voidCallback) => Promise; } } String.load = file.load; String.save = file.save; String.loadS = file.loadS; String.saveS = file.saveS; String.loadW = file.loadW; String.saveW = file.saveW; String.prototype.save = async function (path: string, callback?: voidCallback) { await file.save(path, String(this), callback); }; String.prototype.saveS = function (path: string) { file.saveS(path, String(this)); }; String.prototype.saveW = async function (path: string, callback?: voidCallback) { await file.saveW(path, String(this), callback); }; JSON.load = json.load; JSON.save = json.save; JSON.loadS = json.loadS; JSON.saveS = json.saveS; JSON.loadW = json.loadW; JSON.saveW = json.saveW; export { }; Mylas-2.1.14/ts/types.ts000066400000000000000000000010631510307563500150330ustar00rootroot00000000000000 export declare type voidCallback = () => void; export declare type stringCallback = (arg0: string) => void; export declare type objectCallback = (arg0: T) => void; export declare type booleanCallback = (arg0: boolean) => void; export const enum Method { loadFile, saveFile, loadJson, loadJsonComments, saveJson, loadBuffer, saveBuffer, } export interface Request { method: Method, path: string, data?: any, // eslint-disable-line @typescript-eslint/no-explicit-any callback?: objectCallback, } Mylas-2.1.14/ts/worker.ts000066400000000000000000000020521510307563500151770ustar00rootroot00000000000000import { parentPort as PP, } from "worker_threads"; import { Json, Buf, File, Method, Request } from "./index"; /* eslint-disable */ PP!.once("message", async ({ method, path, data }: Request) => { try { if (method === Method.loadFile) PP!.postMessage(await File.load(path)); if (method === Method.saveFile) await File.save(path, data); if (method === Method.loadJson) PP!.postMessage(await Json.load(path)); if (method === Method.loadJsonComments) PP!.postMessage(await Json.load(path, undefined, true)); if (method === Method.saveJson) await Json.save(path, data); if (method === Method.saveBuffer) await Buf.save(path, Buffer.from(data)); if (method === Method.loadBuffer) { const data = await Buf.load(path); const sharedUint8Array = new Uint8Array( new SharedArrayBuffer(data.byteLength)); sharedUint8Array.set(data); PP!.postMessage(sharedUint8Array); } process.exit(0); } catch (error) { process.exit(1); } }); Mylas-2.1.14/ts/workerActions.ts000066400000000000000000000010501510307563500165150ustar00rootroot00000000000000import { Worker } from "worker_threads"; import { Request } from "./types"; import { resolve } from "path"; const action = ( { callback, ...req }: Request ): Promise => new Promise((res, rej) => { let d: T; new Worker(resolve(__dirname, "./worker.js")) .once("message", m => d = m).once("exit", c => c == 0 ? res(d) : rej(c)) .once("error", e => rej(e)).once("messageerror", e => rej(e)) .postMessage(req); }).then(v => { callback?.(v); return v; }, e => { throw new Error(e); }); export default action;