commit 9dbae07029ff81861c8fdece79cddbbfb8e8dca2 Author: Mike Nolan Date: Sun Jun 30 19:50:11 2024 -0500 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e57f18 --- /dev/null +++ b/.gitignore @@ -0,0 +1,484 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from `dotnet new gitignore` + +# dotenv files +.env + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Vim temporary swap files +*.swp diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..46ff6af --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,675 @@ +# GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +## Preamble + +The GNU General Public License is a free, copyleft license for +software and other kinds of works. + +The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom +to share and change all versions of a program--to make sure it remains +free software for all its users. We, the Free Software Foundation, use +the GNU General Public License for most of our software; it applies +also to any other work released this way by its authors. You can apply +it to your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you +have certain responsibilities if you distribute copies of the +software, or if you modify it: responsibilities to respect the freedom +of others. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + +Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + +Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the +manufacturer can do so. This is fundamentally incompatible with the +aim of protecting users' freedom to change the software. The +systematic pattern of such abuse occurs in the area of products for +individuals to use, which is precisely where it is most unacceptable. +Therefore, we have designed this version of the GPL to prohibit the +practice for those products. If such problems arise substantially in +other domains, we stand ready to extend this provision to those +domains in future versions of the GPL, as needed to protect the +freedom of users. + +Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish +to avoid the special danger that patents applied to a free program +could make it effectively proprietary. To prevent this, the GPL +assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and +modification follow. + +## TERMS AND CONDITIONS + +### 0. Definitions. + +"This License" refers to version 3 of the GNU General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds +of works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of +an exact copy. The resulting work is called a "modified version" of +the earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based +on the Program. + +To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user +through a computer network, with no transfer of a copy, is not +conveying. + +An interactive user interface displays "Appropriate Legal Notices" to +the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +### 1. Source Code. + +The "source code" for a work means the preferred form of the work for +making modifications to it. "Object code" means any non-source form of +a work. + +A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can +regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same +work. + +### 2. Basic Permissions. + +All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, +without conditions so long as your license otherwise remains in force. +You may convey covered works to others for the sole purpose of having +them make modifications exclusively for you, or provide you with +facilities for running those works, provided that you comply with the +terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works for +you must do so exclusively on your behalf, under your direction and +control, on terms that prohibit them from making any copies of your +copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the +conditions stated below. Sublicensing is not allowed; section 10 makes +it unnecessary. + +### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + +When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such +circumvention is effected by exercising rights under this License with +respect to the covered work, and you disclaim any intention to limit +operation or modification of the work as a means of enforcing, against +the work's users, your or third parties' legal rights to forbid +circumvention of technological measures. + +### 4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +### 5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these +conditions: + +- a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. +- b) The work must carry prominent notices stating that it is + released under this License and any conditions added under + section 7. This requirement modifies the requirement in section 4 + to "keep intact all notices". +- c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. +- d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + +A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +### 6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of +sections 4 and 5, provided that you also convey the machine-readable +Corresponding Source under the terms of this License, in one of these +ways: + +- a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. +- b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the Corresponding + Source from a network server at no charge. +- c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. +- d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. +- e) Convey the object code using peer-to-peer transmission, + provided you inform other peers where the object code and + Corresponding Source of the work are being offered to the general + public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, +family, or household purposes, or (2) anything designed or sold for +incorporation into a dwelling. In determining whether a product is a +consumer product, doubtful cases shall be resolved in favor of +coverage. For a particular product received by a particular user, +"normally used" refers to a typical or common use of that class of +product, regardless of the status of the particular user or of the way +in which the particular user actually uses, or expects or is expected +to use, the product. A product is a consumer product regardless of +whether the product has substantial commercial, industrial or +non-consumer uses, unless such uses represent the only significant +mode of use of the product. + +"Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to +install and execute modified versions of a covered work in that User +Product from a modified version of its Corresponding Source. The +information must suffice to ensure that the continued functioning of +the modified object code is in no case prevented or interfered with +solely because modification has been made. + +If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or +updates for a work that has been modified or installed by the +recipient, or for the User Product in which it has been modified or +installed. Access to a network may be denied when the modification +itself materially and adversely affects the operation of the network +or violates the rules and protocols for communication across the +network. + +Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +### 7. Additional Terms. + +"Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders +of that material) supplement the terms of this License with terms: + +- a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or +- b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or +- c) Prohibiting misrepresentation of the origin of that material, + or requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or +- d) Limiting the use for publicity purposes of names of licensors + or authors of the material; or +- e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or +- f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions + of it) with contractual assumptions of liability to the recipient, + for any liability that these contractual assumptions directly + impose on those licensors and authors. + +All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; the +above requirements apply either way. + +### 8. Termination. + +You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +### 9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or run +a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +### 10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +### 11. Patents. + +A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims owned +or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + +If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + +A patent license is "discriminatory" if it does not include within the +scope of its coverage, prohibits the exercise of, or is conditioned on +the non-exercise of one or more of the rights that are specifically +granted under this License. You may not convey a covered work if you +are a party to an arrangement with a third party that is in the +business of distributing software, under which you make payment to the +third party based on the extent of your activity of conveying the +work, and under which the third party grants, to any of the parties +who would receive the covered work from you, a discriminatory patent +license (a) in connection with copies of the covered work conveyed by +you (or copies made from those copies), or (b) primarily for and in +connection with specific products or compilations that contain the +covered work, unless you entered into that arrangement, or that patent +license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +### 12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under +this License and any other pertinent obligations, then as a +consequence you may not convey it at all. For example, if you agree to +terms that obligate you to collect a royalty for further conveying +from those to whom you convey the Program, the only way you could +satisfy both those terms and this License would be to refrain entirely +from conveying the Program. + +### 13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +### 14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions +of the GNU General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies that a certain numbered version of the GNU General Public +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that numbered version or +of any later version published by the Free Software Foundation. If the +Program does not specify a version number of the GNU General Public +License, you may choose any version ever published by the Free +Software Foundation. + +If the Program specifies that a proxy can decide which future versions +of the GNU General Public License can be used, that proxy's public +statement of acceptance of a version permanently authorizes you to +choose that version for the Program. + +Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +### 15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + +### 16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR +CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT +NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR +LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM +TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +### 17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +## How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively state +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper +mail. + +If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands \`show w' and \`show c' should show the +appropriate parts of the General Public License. Of course, your +program's commands might be different; for a GUI interface, you would +use an "about box". + +You should also get your employer (if you work as a programmer) or +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. For more information on this, and how to apply and follow +the GNU GPL, see . + +The GNU General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Lesser General Public License instead of this License. But first, +please read . \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1572924 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: publish/linux-x64 publish/linux-arm publish/linux-arm64 publish/win-x86 publish/win-x64 publish/win-arm64 publish/osx-x64 publish/osx-arm64 publish/mono + +publish/mono: + mkdir -p publish/mono || true && cd "TYTDLite.ServerNetFwMono" && dotnet publish -c Release -o ../publish/mono && cd ../publish/mono && tar cvzf ../mono.tar.gz . && zip -r ../mono.zip . && rm -r * && mv ../mono.tar.gz . && mv ../mono.zip . +publish/%: + mkdir -p $@ || true && cd "TYTDLite.ServerCli" && dotnet publish -c Release -o ../$@ --self-contained -p:PublishReadyToRun=true -p:PublishSingleFile=true -r $(notdir $@) + diff --git a/README.md b/README.md new file mode 100644 index 0000000..05617d2 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +TYTDLite +======== + +A YouTube Downloader website that archives videos when people download videos using it. + +Running from source (.NET 8) +================================ +```bash +cd TYTDLite.ServerCli +dotnet run -- --help +``` + +Download binaries (.NET 8) +========================== +- [TYTDLite](https://downloads.tesses.net/apps/tytdlite/) +- ```bash ./TYTDLite.ServerCli --help``` + +Download binaries (Mono) +======================== +- [TYTDLite](https://downloads.tesses.net/apps/tytdlite/mono) +- [Wii-Linux-NGX-Mono (only Wii or other PowerPC)](https://tesses.net/apps/tytd/2022/wii.php) +- ```bash mono TYTDLite.ServerNetFwMono.exe --help``` \ No newline at end of file diff --git a/TYTDLite.ServerCli/Program.cs b/TYTDLite.ServerCli/Program.cs new file mode 100644 index 0000000..94d7bb3 --- /dev/null +++ b/TYTDLite.ServerCli/Program.cs @@ -0,0 +1,19 @@ +/* + TYTD Lite: A YouTube Downloader website that archives videos when people download videos using it. + Copyright (C) 2024 Mike Nolan + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +using TYTDLite; +TYTDLiteServer.MainFunc(args); \ No newline at end of file diff --git a/TYTDLite.ServerCli/TYTDLite.ServerCli.csproj b/TYTDLite.ServerCli/TYTDLite.ServerCli.csproj new file mode 100644 index 0000000..d30a3e0 --- /dev/null +++ b/TYTDLite.ServerCli/TYTDLite.ServerCli.csproj @@ -0,0 +1,18 @@ + + + + + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/TYTDLite.ServerNetFwMono/Program.cs b/TYTDLite.ServerNetFwMono/Program.cs new file mode 100644 index 0000000..dfc144e --- /dev/null +++ b/TYTDLite.ServerNetFwMono/Program.cs @@ -0,0 +1,30 @@ +/* + TYTD Lite: A YouTube Downloader website that archives videos when people download videos using it. + Copyright (C) 2024 Mike Nolan + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +using TYTDLite; +namespace TYTDLite.ServerNetFwMono +{ + +class Program +{ + + static void Main(string[] args) + { + TYTDLiteServer.MainFunc(args); + } +} + +} \ No newline at end of file diff --git a/TYTDLite.ServerNetFwMono/TYTDLite.ServerNetFwMono.csproj b/TYTDLite.ServerNetFwMono/TYTDLite.ServerNetFwMono.csproj new file mode 100644 index 0000000..33c4a7b --- /dev/null +++ b/TYTDLite.ServerNetFwMono/TYTDLite.ServerNetFwMono.csproj @@ -0,0 +1,12 @@ + + + + + + + + Exe + net48 + + + diff --git a/TYTDLite.sln b/TYTDLite.sln new file mode 100644 index 0000000..38df432 --- /dev/null +++ b/TYTDLite.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TYTDLite.ServerCli", "TYTDLite.ServerCli\TYTDLite.ServerCli.csproj", "{2AFC0D08-267E-4DAA-B955-67F13EF31FEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TYTDLite.ServerNetFwMono", "TYTDLite.ServerNetFwMono\TYTDLite.ServerNetFwMono.csproj", "{49DE2AD1-DDDB-42CC-8F82-999D002F6F3B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TYTDLite", "TYTDLite\TYTDLite.csproj", "{2108EAB4-4B0F-49EF-B054-641341B96268}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2AFC0D08-267E-4DAA-B955-67F13EF31FEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2AFC0D08-267E-4DAA-B955-67F13EF31FEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2AFC0D08-267E-4DAA-B955-67F13EF31FEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2AFC0D08-267E-4DAA-B955-67F13EF31FEB}.Release|Any CPU.Build.0 = Release|Any CPU + {49DE2AD1-DDDB-42CC-8F82-999D002F6F3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {49DE2AD1-DDDB-42CC-8F82-999D002F6F3B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {49DE2AD1-DDDB-42CC-8F82-999D002F6F3B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {49DE2AD1-DDDB-42CC-8F82-999D002F6F3B}.Release|Any CPU.Build.0 = Release|Any CPU + {2108EAB4-4B0F-49EF-B054-641341B96268}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2108EAB4-4B0F-49EF-B054-641341B96268}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2108EAB4-4B0F-49EF-B054-641341B96268}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2108EAB4-4B0F-49EF-B054-641341B96268}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/TYTDLite/AssetProvier.cs b/TYTDLite/AssetProvier.cs new file mode 100644 index 0000000..0922c94 --- /dev/null +++ b/TYTDLite/AssetProvier.cs @@ -0,0 +1,104 @@ +/* + TYTD Lite: A YouTube Downloader website that archives videos when people download videos using it. + Copyright (C) 2024 Mike Nolan + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +using System; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using Tesses.WebServer; + +namespace TYTDLite +{ + //thanks to https://www.meziantou.net/getting-the-date-of-build-of-a-dotnet-assembly-at-runtime.htm + [AttributeUsage(AttributeTargets.Assembly)] + internal class BuildDateAttribute : Attribute +{ + public BuildDateAttribute(string value) + { + DateTime = DateTime.ParseExact(value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None); + } + + public DateTime DateTime { get; } +} + public class AssetProvider : Server + { + internal static DateTime GetBuildDate() + { + var attribute = asm.GetCustomAttribute(); + return attribute != null ? attribute.DateTime : default(DateTime); + } + static Assembly asm=typeof(AssetProvider).Assembly; + public AssetProvider() + { + + } + + + public static Stream OpenRead(string path) + { + return asm.GetManifestResourceStream($"TYTDLite.Assets{path.Replace("/",".")}"); + } + public override async Task GetAsync(ServerContext ctx) + { + try{ + + var build = GetBuildDate(); + string nice = $"S_{Convert.ToBase64String(Encoding.UTF8.GetBytes($"{build.ToString()}-{ctx.UrlPath}"))}"; + + + ctx.WithDate(build).WithLastModified(build); + ctx.ResponseHeaders.Add("ETag",nice); + + + await ctx.SendBytesAsync(await ReadAllBytesAsync(ctx.UrlPath),HeyRed.Mime.MimeTypesMap.GetMimeType(ctx.UrlPath)); + }catch(ArgumentNullException ex) + { + _=ex; + await NotFoundServer.ServerNull.GetAsync(ctx); + } + } + public static async Task ReadAllBytesAsync(string path) + { + using(var s = OpenRead(path)) + { + var ms = new MemoryStream(); + await s.CopyToAsync(ms); + return ms.ToArray(); + } + } + public static async Task ReadAllTextAsync(string path) + { + using(var s = OpenRead(path)) + using(var ms = new StreamReader(s)) + { + return await ms.ReadToEndAsync(); + } + } + + public static string ReadAllText(string path) + { + using(var s = OpenRead(path)) + using(var ms = new StreamReader(s)) + return ms.ReadToEnd(); + } + + + } +} diff --git a/TYTDLite/Assets/android-chrome-192x192.png b/TYTDLite/Assets/android-chrome-192x192.png new file mode 100644 index 0000000..548a71b Binary files /dev/null and b/TYTDLite/Assets/android-chrome-192x192.png differ diff --git a/TYTDLite/Assets/android-chrome-512x512.png b/TYTDLite/Assets/android-chrome-512x512.png new file mode 100644 index 0000000..58d6121 Binary files /dev/null and b/TYTDLite/Assets/android-chrome-512x512.png differ diff --git a/TYTDLite/Assets/beer.min.css b/TYTDLite/Assets/beer.min.css new file mode 100644 index 0000000..5c17f7d --- /dev/null +++ b/TYTDLite/Assets/beer.min.css @@ -0,0 +1 @@ +:root{--size: 16px;--font: Inter, Roboto, "Helvetica Neue", "Arial Nova", "Nimbus Sans", Arial, sans-serif;--font-icon: "Material Symbols Outlined";--speed1: .1s;--speed2: .2s;--speed3: .3s;--speed4: .4s}:root,body.light{--primary: #6750a4;--on-primary: #ffffff;--primary-container: #e9ddff;--on-primary-container: #22005d;--secondary: #625b71;--on-secondary: #ffffff;--secondary-container: #e8def8;--on-secondary-container: #1e192b;--tertiary: #7e5260;--on-tertiary: #ffffff;--tertiary-container: #ffd9e3;--on-tertiary-container: #31101d;--error: #ba1a1a;--on-error: #ffffff;--error-container: #ffdad6;--on-error-container: #410002;--background: #fffbff;--on-background: #1c1b1e;--surface: #fdf8fd;--on-surface: #1c1b1e;--surface-variant: #e7e0eb;--on-surface-variant: #49454e;--outline: #7a757f;--outline-variant: #cac4cf;--shadow: #000000;--scrim: #000000;--inverse-surface: #313033;--inverse-on-surface: #f4eff4;--inverse-primary: #cfbcff;--surface-dim: #ddd8dd;--surface-bright: #fdf8fd;--surface-container-lowest: #ffffff;--surface-container-low: #f7f2f7;--surface-container: #f2ecf1;--surface-container-high: #ece7eb;--surface-container-highest: #e6e1e6;--overlay: rgb(0 0 0 / .5);--active: rgb(0 0 0 / .1);--elevate1: 0 .125rem .125rem 0 rgb(0 0 0 / .32);--elevate2: 0 .25rem .5rem 0 rgb(0 0 0 / .4);--elevate3: 0 .375rem .75rem 0 rgb(0 0 0 / .48)}body.dark{--primary: #cfbcff;--on-primary: #381e72;--primary-container: #4f378a;--on-primary-container: #e9ddff;--secondary: #cbc2db;--on-secondary: #332d41;--secondary-container: #4a4458;--on-secondary-container: #e8def8;--tertiary: #efb8c8;--on-tertiary: #4a2532;--tertiary-container: #633b48;--on-tertiary-container: #ffd9e3;--error: #ffb4ab;--on-error: #690005;--error-container: #93000a;--on-error-container: #ffb4ab;--background: #1c1b1e;--on-background: #e6e1e6;--surface: #141316;--on-surface: #e6e1e6;--surface-variant: #49454e;--on-surface-variant: #cac4cf;--outline: #948f99;--outline-variant: #49454e;--shadow: #000000;--scrim: #000000;--inverse-surface: #e6e1e6;--inverse-on-surface: #313033;--inverse-primary: #6750a4;--surface-dim: #141316;--surface-bright: #3a383c;--surface-container-lowest: #0f0e11;--surface-container-low: #1c1b1e;--surface-container: #201f22;--surface-container-high: #2b292d;--surface-container-highest: #363438;--overlay: rgb(0 0 0 / .5);--active: rgb(255 255 255 / .2);--elevate1: 0 .125rem .125rem 0 rgb(0 0 0 / .32);--elevate2: 0 .25rem .5rem 0 rgb(0 0 0 / .4);--elevate3: 0 .375rem .75rem 0 rgb(0 0 0 / .48)}@font-face{font-family:Material Symbols Outlined;font-style:normal;font-weight:400;font-display:swap;src:url(material-symbols-outlined.woff2) format("woff2"),url(./material-symbols-outlined.woff2) format("woff2")}@font-face{font-family:Material Symbols Rounded;font-style:normal;font-weight:400;font-display:swap;src:url(material-symbols-rounded.woff2) format("woff2"),url(./material-symbols-rounded.woff2) format("woff2")}@font-face{font-family:Material Symbols Sharp;font-style:normal;font-weight:400;font-display:swap;src:url(material-symbols-sharp.woff2) format("woff2"),url(./material-symbols-sharp.woff2) format("woff2")}*{-webkit-tap-highlight-color:transparent;position:relative;vertical-align:middle;color:inherit;margin:0;padding:0;border-radius:inherit;box-sizing:border-box}body{color:var(--on-surface);background-color:var(--surface);overflow-x:hidden}label{font-size:.75rem;vertical-align:baseline}a,b,i,span,strong{vertical-align:bottom}a,button,.button{cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;border:none;font-family:inherit;outline:inherit;justify-content:center}a,button,.button,i,label{user-select:none}body ::-webkit-scrollbar,body ::-webkit-scrollbar-thumb,body ::-webkit-scrollbar-button{background:none;inline-size:.4rem;block-size:.4rem}body :is(:hover,:focus)::-webkit-scrollbar-thumb{background:var(--outline);border-radius:1rem}pre,code{direction:ltr}.primary{background-color:var(--primary)!important;color:var(--on-primary)!important}.primary-text{color:var(--primary)!important}.primary-border{border-color:var(--primary)!important}.primary-container{background-color:var(--primary-container)!important;color:var(--on-primary-container)!important}.secondary{background-color:var(--secondary)!important;color:var(--on-secondary)!important}.secondary-text{color:var(--secondary)!important}.secondary-border{border-color:var(--secondary)!important}.secondary-container{background-color:var(--secondary-container)!important;color:var(--on-secondary-container)!important}.tertiary{background-color:var(--tertiary)!important;color:var(--on-tertiary)!important}.tertiary-text{color:var(--tertiary)!important}.tertiary-border{border-color:var(--tertiary)!important}.tertiary-container{background-color:var(--tertiary-container)!important;color:var(--on-tertiary-container)!important}.error{background-color:var(--error)!important;color:var(--on-error)!important}.error-text{color:var(--error)!important}.error-border{border-color:var(--error)!important}.error-container{background-color:var(--error-container)!important;color:var(--on-error-container)!important}.background{background-color:var(--background)!important;color:var(--on-background)!important}.surface,.surface-dim,.surface-bright,.surface-container-lowest,.surface-container-low,.surface-container,.surface-container-high,.surface-container-highest{background-color:var(--surface)!important;color:var(--on-surface)!important}.surface-variant{background-color:var(--surface-variant)!important;color:var(--on-surface-variant)!important}.inverse-surface{background-color:var(--inverse-surface);color:var(--inverse-on-surface)}.inverse-primary{background-color:var(--inverse-primary);color:var(--primary)}.inverse-primary-text{color:var(--inverse-primary)!important}.inverse-primary-border{border-color:var(--inverse-primary)!important}.surface-dim{background-color:var(--surface-dim)!important}.surface-bright{background-color:var(--surface-bright)!important}.surface-container-lowest{background-color:var(--surface-container-lowest)!important}.surface-container{background-color:var(--surface-container)!important}.surface-container-high{background-color:var(--surface-container-high)!important}.surface-container-highest{background-color:var(--surface-container-highest)!important}.surface-container-low{background-color:var(--surface-container-low)!important}.black{background-color:#000!important}.black-border{border-color:#000!important}.black-text{color:#000!important}.white{background-color:#fff!important}.white-border{border-color:#fff!important}.white-text{color:#fff!important}.transparent{background-color:transparent!important;box-shadow:none!important;color:inherit!important}.transparent-border{border-color:transparent!important}.transparent-text{color:transparent!important}.fill:not(i){background-color:var(--surface-variant)!important;color:var(--on-surface-variant)!important}.middle-align{display:flex;align-items:center!important}.bottom-align{display:flex;align-items:flex-end!important}.top-align{display:flex;align-items:flex-start!important}.left-align{text-align:start;justify-content:flex-start!important}.right-align{text-align:end;justify-content:flex-end!important}.center-align{text-align:center;justify-content:center!important}.red,.red6{background-color:#f44336!important}.red-border{border-color:#f44336!important}.red-text{color:#f44336!important}.red1{background-color:#ffebee!important}.red2{background-color:#ffcdd2!important}.red3{background-color:#ef9a9a!important}.red4{background-color:#e57373!important}.red5{background-color:#ef5350!important}.red7{background-color:#e53935!important}.red8{background-color:#d32f2f!important}.red9{background-color:#c62828!important}.red10{background-color:#b71c1c!important}.pink,.pink6{background-color:#e91e63!important}.pink-border{border-color:#e91e63!important}.pink-text{color:#e91e63!important}.pink1{background-color:#fce4ec!important}.pink2{background-color:#f8bbd0!important}.pink3{background-color:#f48fb1!important}.pink4{background-color:#f06292!important}.pink5{background-color:#ec407a!important}.pink7{background-color:#d81b60!important}.pink8{background-color:#c2185b!important}.pink9{background-color:#ad1457!important}.pink10{background-color:#880e4f!important}.purple,.purple6{background-color:#9c27b0!important}.purple-border{border-color:#9c27b0!important}.purple-text{color:#9c27b0!important}.purple1{background-color:#f3e5f5!important}.purple2{background-color:#e1bee7!important}.purple3{background-color:#ce93d8!important}.purple4{background-color:#ba68c8!important}.purple5{background-color:#ab47bc!important}.purple7{background-color:#8e24aa!important}.purple8{background-color:#7b1fa2!important}.purple9{background-color:#6a1b9a!important}.purple10{background-color:#4a148c!important}.deep-purple,.deep-purple6{background-color:#673ab7!important}.deep-purple-border{border-color:#673ab7!important}.deep-purple-text{color:#673ab7!important}.deep-purple1{background-color:#ede7f6!important}.deep-purple2{background-color:#d1c4e9!important}.deep-purple3{background-color:#b39ddb!important}.deep-purple4{background-color:#9575cd!important}.deep-purple5{background-color:#7e57c2!important}.deep-purple7{background-color:#5e35b1!important}.deep-purple8{background-color:#512da8!important}.deep-purple9{background-color:#4527a0!important}.deep-purple10{background-color:#311b92!important}.indigo,.indigo6{background-color:#3f51b5!important}.indigo-border{border-color:#3f51b5!important}.indigo-text{color:#3f51b5!important}.indigo1{background-color:#e8eaf6!important}.indigo2{background-color:#c5cae9!important}.indigo3{background-color:#9fa8da!important}.indigo4{background-color:#7986cb!important}.indigo5{background-color:#5c6bc0!important}.indigo7{background-color:#3949ab!important}.indigo8{background-color:#303f9f!important}.indigo9{background-color:#283593!important}.indigo10{background-color:#1a237e!important}.blue,.blue6{background-color:#2196f3!important}.blue-border{border-color:#2196f3!important}.blue-text{color:#2196f3!important}.blue1{background-color:#e3f2fd!important}.blue2{background-color:#bbdefb!important}.blue3{background-color:#90caf9!important}.blue4{background-color:#64b5f6!important}.blue5{background-color:#42a5f5!important}.blue7{background-color:#1e88e5!important}.blue8{background-color:#1976d2!important}.blue9{background-color:#1565c0!important}.blue10{background-color:#0d47a1!important}.light-blue,.light-blue6{background-color:#03a9f4!important}.light-blue-border{border-color:#03a9f4!important}.light-blue-text{color:#03a9f4!important}.light-blue1{background-color:#e1f5fe!important}.light-blue2{background-color:#b3e5fc!important}.light-blue3{background-color:#81d4fa!important}.light-blue4{background-color:#4fc3f7!important}.light-blue5{background-color:#29b6f6!important}.light-blue7{background-color:#039be5!important}.light-blue8{background-color:#0288d1!important}.light-blue9{background-color:#0277bd!important}.light-blue10{background-color:#01579b!important}.cyan,.cyan6{background-color:#00bcd4!important}.cyan-border{border-color:#00bcd4!important}.cyan-text{color:#00bcd4!important}.cyan1{background-color:#e0f7fa!important}.cyan2{background-color:#b2ebf2!important}.cyan3{background-color:#80deea!important}.cyan4{background-color:#4dd0e1!important}.cyan5{background-color:#26c6da!important}.cyan7{background-color:#00acc1!important}.cyan8{background-color:#0097a7!important}.cyan9{background-color:#00838f!important}.cyan10{background-color:#006064!important}.teal,.teal6{background-color:#009688!important}.teal-border{border-color:#009688!important}.teal-text{color:#009688!important}.teal1{background-color:#e0f2f1!important}.teal2{background-color:#b2dfdb!important}.teal3{background-color:#80cbc4!important}.teal4{background-color:#4db6ac!important}.teal5{background-color:#26a69a!important}.teal7{background-color:#00897b!important}.teal8{background-color:#00796b!important}.teal9{background-color:#00695c!important}.teal10{background-color:#004d40!important}.green,.green6{background-color:#4caf50!important}.green-border{border-color:#4caf50!important}.green-text{color:#4caf50!important}.green1{background-color:#e8f5e9!important}.green2{background-color:#c8e6c9!important}.green3{background-color:#a5d6a7!important}.green4{background-color:#81c784!important}.green5{background-color:#66bb6a!important}.green7{background-color:#43a047!important}.green8{background-color:#388e3c!important}.green9{background-color:#2e7d32!important}.green10{background-color:#1b5e20!important}.light-green,.light-green6{background-color:#8bc34a!important}.light-green-border{border-color:#8bc34a!important}.light-green-text{color:#8bc34a!important}.light-green1{background-color:#f1f8e9!important}.light-green2{background-color:#dcedc8!important}.light-green3{background-color:#c5e1a5!important}.light-green4{background-color:#aed581!important}.light-green5{background-color:#9ccc65!important}.light-green7{background-color:#7cb342!important}.light-green8{background-color:#689f38!important}.light-green9{background-color:#558b2f!important}.light-green10{background-color:#33691e!important}.lime,.lime6{background-color:#cddc39!important}.lime-border{border-color:#cddc39!important}.lime-text{color:#cddc39!important}.lime1{background-color:#f9fbe7!important}.lime2{background-color:#f0f4c3!important}.lime3{background-color:#e6ee9c!important}.lime4{background-color:#dce775!important}.lime5{background-color:#d4e157!important}.lime7{background-color:#c0ca33!important}.lime8{background-color:#afb42b!important}.lime9{background-color:#9e9d24!important}.lime10{background-color:#827717!important}.yellow,.yellow6{background-color:#ffeb3b!important}.yellow-border{border-color:#ffeb3b!important}.yellow-text{color:#ffeb3b!important}.yellow1{background-color:#fffde7!important}.yellow2{background-color:#fff9c4!important}.yellow3{background-color:#fff59d!important}.yellow4{background-color:#fff176!important}.yellow5{background-color:#ffee58!important}.yellow7{background-color:#fdd835!important}.yellow8{background-color:#fbc02d!important}.yellow9{background-color:#f9a825!important}.yellow10{background-color:#f57f17!important}.amber,.amber6{background-color:#ffc107!important}.amber-border{border-color:#ffc107!important}.amber-text{color:#ffc107!important}.amber1{background-color:#fff8e1!important}.amber2{background-color:#ffecb3!important}.amber3{background-color:#ffe082!important}.amber4{background-color:#ffd54f!important}.amber5{background-color:#ffca28!important}.amber7{background-color:#ffb300!important}.amber8{background-color:#ffa000!important}.amber9{background-color:#ff8f00!important}.amber10{background-color:#ff6f00!important}.orange,.orange6{background-color:#ff9800!important}.orange-border{border-color:#ff9800!important}.orange-text{color:#ff9800!important}.orange1{background-color:#fff3e0!important}.orange2{background-color:#ffe0b2!important}.orange3{background-color:#ffcc80!important}.orange4{background-color:#ffb74d!important}.orange5{background-color:#ffa726!important}.orange7{background-color:#fb8c00!important}.orange8{background-color:#f57c00!important}.orange9{background-color:#ef6c00!important}.orange10{background-color:#e65100!important}.deep-orange,.deep-orange6{background-color:#ff5722!important}.deep-orange-border{border-color:#ff5722!important}.deep-orange-text{color:#ff5722!important}.deep-orange1{background-color:#fbe9e7!important}.deep-orange2{background-color:#ffccbc!important}.deep-orange3{background-color:#ffab91!important}.deep-orange4{background-color:#ff8a65!important}.deep-orange5{background-color:#ff7043!important}.deep-orange7{background-color:#f4511e!important}.deep-orange8{background-color:#e64a19!important}.deep-orange9{background-color:#d84315!important}.deep-orange10{background-color:#bf360c!important}.brown,.brown6{background-color:#795548!important}.brown-border{border-color:#795548!important}.brown-text{color:#795548!important}.brown1{background-color:#efebe9!important}.brown2{background-color:#d7ccc8!important}.brown3{background-color:#bcaaa4!important}.brown4{background-color:#a1887f!important}.brown5{background-color:#8d6e63!important}.brown7{background-color:#6d4c41!important}.brown8{background-color:#5d4037!important}.brown9{background-color:#4e342e!important}.brown10{background-color:#3e2723!important}.blue-grey,.blue-grey6{background-color:#607d8b!important}.blue-grey-border{border-color:#607d8b!important}.blue-grey-text{color:#607d8b!important}.blue-grey1{background-color:#eceff1!important}.blue-grey2{background-color:#cfd8dc!important}.blue-grey3{background-color:#b0bec5!important}.blue-grey4{background-color:#90a4ae!important}.blue-grey5{background-color:#78909c!important}.blue-grey7{background-color:#546e7a!important}.blue-grey8{background-color:#455a64!important}.blue-grey9{background-color:#37474f!important}.blue-grey10{background-color:#263238!important}.grey,.grey6{background-color:#9e9e9e!important}.grey-border{border-color:#9e9e9e!important}.grey-text{color:#9e9e9e!important}.grey1{background-color:#fafafa!important}.grey2{background-color:#f5f5f5!important}.grey3{background-color:#eee!important}.grey4{background-color:#e0e0e0!important}.grey5{background-color:#bdbdbd!important}.grey7{background-color:#757575!important}.grey8{background-color:#616161!important}.grey9{background-color:#424242!important}.grey10{background-color:#212121!important}.horizontal{display:inline-flex;flex-direction:row!important;gap:1rem;inline-size:auto!important;max-inline-size:none!important}.horizontal>*{margin-block:0!important}.vertical{display:flex;flex-direction:column!important}:is(a,button,.button,.chip).vertical{display:inline-flex;gap:.25rem;block-size:auto!important;max-block-size:none!important;padding-block:.5rem}.vertical>*{margin-inline:0!important}[class*=divider]{min-inline-size:1.5rem;min-block-size:auto;block-size:.0625rem;background-color:var(--outline-variant);display:block}[class*=divider]+*{margin:0!important}.medium-divider{margin:1rem 0!important}.large-divider{margin:1.5rem 0!important}.small-divider{margin:.5rem 0!important}.divider.vertical{min-inline-size:auto;min-block-size:1.5rem;inline-size:.0625rem}.no-elevate{box-shadow:none!important}.small-elevate,.elevate{box-shadow:var(--elevate1)!important}.medium-elevate{box-shadow:var(--elevate2)!important}.large-elevate{box-shadow:var(--elevate3)!important}.round{border-radius:var(---round)}.small-round,.medium-round,.large-round{border-radius:var(---round)!important}.top-round,.bottom-round,.left-round,.right-round,.medium-round,.round{---round: 2rem}.small-round{---round: .5rem}.large-round{---round: 3.5rem}.no-round,.square,.top-round,.bottom-round,.left-round,.right-round{border-radius:0!important}.top-round{border-start-start-radius:var(---round)!important;border-start-end-radius:var(---round)!important}.bottom-round{border-end-end-radius:var(---round)!important;border-end-start-radius:var(---round)!important}.left-round{border-start-start-radius:var(---round)!important;border-end-start-radius:var(---round)!important}.right-round{border-start-end-radius:var(---round)!important;border-end-end-radius:var(---round)!important}.circle{border-radius:50%}:is(button,.button,.chip).circle{border-radius:2.5rem}:is(.circle,.square):not(i,img,video,svg),:is(.circle,.square).chip.medium{block-size:2.5rem;inline-size:2.5rem;padding:0}:is(.circle,.square)>span{display:none}:is(.circle,.square).small:not(i,img,video,svg),:is(.circle,.square).chip{block-size:2rem;inline-size:2rem}:is(.circle,.square).large:not(i,img,video,svg){block-size:3rem;inline-size:3rem}:is(.circle,.square).extra:not(i,img,video,svg){block-size:3.5rem;inline-size:3.5rem}:is(.circle,.square).round{border-radius:1rem!important}.border:not(table,.field){box-sizing:border-box;border:.0625rem solid var(--outline);background-color:transparent;box-shadow:none}.no-border{border-color:transparent!important}:is(nav,.row,dialog.max,header.fixed,footer.fixed,menu > a,menu.max,table,.tabs):not(.round){border-radius:0}[class*=margin]:not(.left-margin,.right-margin,.top-margin,.bottom-margin,.horizontal-margin,.vertical-margin){margin:var(---margin)!important}[class*=margin]{---margin: 1rem}.no-margin{---margin: 0}.auto-margin{---margin: auto}.tiny-margin{---margin: .25rem}.small-margin{---margin: .5rem}.large-margin{---margin: 1.5rem}.left-margin,.horizontal-margin{margin-inline-start:var(---margin)!important}.right-margin,.horizontal-margin{margin-inline-end:var(---margin)!important}.top-margin,.vertical-margin{margin-block-start:var(---margin)!important}.bottom-margin,.vertical-margin{margin-block-end:var(---margin)!important}.no-opacity{opacity:1!important}.opacity{opacity:0!important}.small-opacity{opacity:.75!important}.medium-opacity{opacity:.5!important}.large-opacity{opacity:.25!important}[class*=padding]:not(.left-padding,.right-padding,.top-padding,.bottom-padding,.horizontal-padding,.vertical-padding){padding:var(---padding)!important}[class*=padding]{---padding: 1rem}.no-padding{---padding: 0}.auto-padding{---padding: auto}.tiny-padding{---padding: .25rem}.small-padding{---padding: .5rem}.large-padding{---padding: 1.5rem}.left-padding,.horizontal-padding{padding-inline-start:var(---padding)!important}.right-padding,.horizontal-padding{padding-inline-end:var(---padding)!important}.top-padding,.vertical-padding{padding-block-start:var(---padding)!important}.bottom-padding,.vertical-padding{padding-block-end:var(---padding)!important}.front{z-index:10!important}.back{z-index:-10!important}.left{inset-inline-start:0}.right{inset-inline-end:0}.top{inset-block-start:0}.bottom{inset-block-end:0}.center{inset-inline-start:50%;transform:translate(-50%)}[dir=rtl] .center{transform:translate(50%)}.middle{inset-block-start:50%;transform:translateY(-50%)}.middle.center{transform:translate(-50%,-50%)}[dir=rtl] .middle.center{transform:translate(50%,-50%)}.scroll{overflow:auto}.no-scroll{overflow:hidden}[class*=width]{max-inline-size:100%}.auto-width{inline-size:auto}.small-width{inline-size:12rem!important}.medium-width{inline-size:24rem!important}.large-width{inline-size:36rem!important}.auto-height{block-size:auto}.small-height{block-size:12rem!important}.medium-height{block-size:24rem!important}.large-height{block-size:36rem!important}.wrap{display:block;white-space:normal}.no-wrap:not(menu){display:flex;white-space:nowrap}.tiny-space:not(nav,ol,ul,.row,.grid,table,.tooltip){block-size:.5rem}:is(.space,.small-space):not(nav,ol,ul,.row,.grid,table,.tooltip){block-size:1rem}.medium-space:not(nav,ol,ul,.row,.grid,table,.tooltip){block-size:2rem}.large-space:not(nav,ol,ul,.row,.grid,table,.tooltip){block-size:3rem}.responsive{inline-size:-webkit-fill-available;inline-size:-moz-available}@media only screen and (max-width: 600px){.m:not(.s),.l:not(.s),.m.l:not(.s){display:none}}@media only screen and (min-width: 601px) and (max-width: 992px){.s:not(.m),.l:not(.m),.s.l:not(.m){display:none}}@media only screen and (min-width: 993px){.m:not(.l),.s:not(.l),.m.s:not(.l){display:none}}html{font-size:var(--size)}body{font-family:var(--font);font-size:.875rem;line-height:1.5}h1,h2,h3,h4,h5,h6{font-weight:400;display:flex;align-items:center;line-height:normal}*+:is(h1,h2,h3,h4,h5,h6){margin-block-start:1rem}h1{font-size:3.5625rem}h2{font-size:2.8125rem}h3{font-size:2.25rem}h4{font-size:2rem}h5{font-size:1.75rem}h6{font-size:1.5rem}h1.small{font-size:3.0625rem}h2.small{font-size:2.3125rem}h3.small{font-size:1.75rem}h4.small{font-size:1.5rem}h5.small{font-size:1.25rem}h6.small{font-size:1rem}h1.large{font-size:4.0625rem}h2.large{font-size:3.3125rem}h3.large{font-size:2.75rem}h4.large{font-size:2.5rem}h5.large{font-size:2.25rem}h6.large{font-size:2rem}.link{color:var(--primary)!important}.inverse-link{color:var(--inverse-primary)!important}.truncate{overflow:hidden;white-space:nowrap!important;text-overflow:ellipsis;flex:inherit}.truncate>*{white-space:nowrap!important}.small-text{font-size:.75rem}.medium-text{font-size:.875rem}.large-text{font-size:1rem}.upper{text-transform:uppercase}.lower{text-transform:lowercase}.capitalize{text-transform:capitalize}.bold{font-weight:700}.overline{text-decoration:line-through}.underline{text-decoration:underline}.italic{font-style:italic}p{margin:.5rem 0}.no-line{line-height:normal}.tiny-line{line-height:1.25}.small-line{line-height:1.5}.medium-line{line-height:1.75}.large-line{line-height:2}.extra-line{line-height:2.25}.wave:after,.chip:after,.wave.light:after,:is(.button,button):after{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit;inline-size:100%;block-size:100%;background-position:center;background-image:radial-gradient(circle,rgb(255 255 255 / .4) 1%,transparent 1%);opacity:0;transition:none}.wave.dark:after,.wave.row:after,.chip:after,:is(.button,button).border:after,:is(.button,button).transparent:after{background-image:radial-gradient(circle,rgb(150 150 150 / .2) 1%,transparent 1%)}:is(.wave,.chip,.button,button):is(:focus-visible,:hover):after{background-size:15000%;opacity:1;transition:var(--speed2) background-size linear}:is(.wave,.chip,.button,button):active:after{background-size:5000%;opacity:0;transition:none}.no-wave:after,.no-wave:is(:hover,:active):after{display:none}.badge{display:inline-flex;align-items:center;justify-content:center;position:absolute;font-size:.6875rem;text-transform:none;z-index:2;padding:0 .25rem;min-block-size:1rem;min-inline-size:1rem;background-color:var(--error);color:var(--on-error);line-height:normal;border-radius:1rem;inset:50% auto auto 50%;transform:translateY(-100%);font-family:var(--font)}.badge.top{transform:translate(-50%,-100%)}.badge.bottom{transform:translate(-50%)}.badge.left{transform:translate(-100%,-50%)}.badge.right{transform:translateY(-50%)}.badge.top.left{transform:translate(-100%,-100%)}.badge.bottom.left{transform:translate(-100%)}.badge.top.right{transform:translateY(-100%)}.badge.bottom.right{transform:translate(0)}.badge.border{border-color:var(--error);color:var(--error);background-color:var(--surface)}.badge:is(.circle,.square){text-align:center;inline-size:auto;block-size:auto;padding:0 .25rem;border-radius:1rem}.badge.square{border-radius:0}.badge.min>*{display:none}.badge.min{clip-path:circle(18.75% at 50% 50%)}nav:is(.left,.right,.top,.bottom)>a>.badge,nav:is(.left,.right,.top,.bottom)>:is(ol,ul)>li>a>.badge{inset:1rem auto auto 50%}.badge.none{inset:auto;transform:none;position:relative;margin:0 .125rem}:is(button,.button,.chip)>.badge.none{margin:0 -.5rem}.button,button{box-sizing:content-box;display:inline-flex;align-items:center;justify-content:center;block-size:2.5rem;min-inline-size:2.5rem;font-size:.875rem;font-weight:500;color:var(--on-primary);padding:0 1.5rem;background-color:var(--primary);margin:0 .5rem;border-radius:1.25rem;transition:var(--speed3) transform,var(--speed3) border-radius,var(--speed3) padding;user-select:none;gap:1rem;line-height:normal}:is(button,.button).small{block-size:2rem;min-inline-size:2rem;font-size:.875rem;border-radius:1rem}:is(button,.button).large{block-size:3rem;min-inline-size:3rem;border-radius:1.5rem}:is(.button,button):is(.extra,.extend){block-size:3.5rem;min-inline-size:3.5rem;font-size:1rem;border-radius:1.75rem}:is(button,.button).border{border-color:var(--outline);color:var(--primary)}:is(button,.button):not(.border,.chip):hover{box-shadow:var(--elevate1)}.extend>span{display:none}.extend:is(:hover,.active){inline-size:auto;padding:0 1.5rem}.extend:is(:hover,.active)>i+span{display:inherit;margin-inline-start:1.5rem}.extend:is(:hover,.active)>:is(img,svg)+span{display:inherit;margin-inline-start:2.5rem}:is(.button,button):is([disabled]){opacity:.5;cursor:not-allowed}:is(.button):is([disabled]){pointer-events:none}:is(.button,button):is([disabled]):before,:is(.button,button):is([disabled]):after{display:none}:is(.button,button).fill{background-color:var(--secondary-container)!important;color:var(--on-secondary-container)!important}:is(.button,button).vertical{border-radius:2rem}article{box-shadow:var(--elevate1);background-color:var(--surface-container-low);color:var(--on-surface);padding:1rem;border-radius:.75rem;display:block;transition:var(--speed3) transform,var(--speed3) border-radius,var(--speed3) padding}*+article{margin-block-start:1rem}article.small{block-size:12rem}article.medium{block-size:20rem}article.large{block-size:32rem}.chip{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;block-size:2rem;min-inline-size:2rem;font-size:.875rem;font-weight:500;background-color:transparent;border:.0625rem solid var(--outline);color:var(--on-surface-variant);padding:0 1rem;margin:0 .5rem;text-transform:none;border-radius:.5rem;transition:var(--speed3) transform,var(--speed3) border-radius,var(--speed3) padding;user-select:none;gap:1rem;line-height:normal}.chip.fill:hover{box-shadow:var(--elevate1)}.chip.medium{block-size:2.5rem;min-inline-size:2.5rem}.chip.large{block-size:3rem;min-inline-size:3rem}.chip.fill{background-color:var(--secondary-container)!important;border:none}.chip.round.small{border-radius:1rem}.chip.round{border-radius:1.25rem}.chip.round.large{border-radius:1.5rem}:is(main,header,footer).responsive{---padding: 6rem;max-inline-size:calc(75rem + var(---padding));margin:0 auto}main.responsive{padding:.5rem;overflow-x:hidden;min-block-size:100vh}:is(main,header,footer).responsive.max{max-inline-size:100%}nav.bottom:not(.s,.m,.l)~.responsive:not(header){padding-bottom:5rem}nav.top:not(.s,.m,.l)~.responsive:not(footer){padding-top:5rem}nav.left:not(.s,.m,.l)~.responsive{padding-left:var(---padding)}nav.right:not(.s,.m,.l)~.responsive{padding-right:var(---padding)}nav.drawer:not(.s,.m,.l)~.responsive{---padding: 20rem}@media only screen and (max-width: 600px){nav.s.bottom~.responsive:not(header){padding-bottom:5rem}nav.s.top~.responsive:not(footer){padding-top:5rem}nav.drawer.s~.responsive{---padding: 20rem}nav.s.left~.responsive{padding-left:var(---padding)}nav.s.right~.responsive{padding-right:var(---padding)}}@media only screen and (min-width: 601px) and (max-width: 992px){nav.m.bottom~.responsive:not(header){padding-bottom:5rem}nav.m.top~.responsive:not(footer){padding-top:5rem}nav.drawer.m~.responsive{---padding: 20rem}nav.m.left~.responsive{padding-left:var(---padding)}nav.m.right~.responsive{padding-right:var(---padding)}}@media only screen and (min-width: 993px){nav.l.bottom~.responsive:not(header){padding-bottom:5rem}nav.l.top~.responsive:not(footer){padding-top:5rem}nav.drawer.l~.responsive{---padding: 20rem}nav.l.left~.responsive{padding-left:var(---padding)}nav.l.right~.responsive{padding-right:var(---padding)}}@media only screen and (max-width: 600px){main.responsive{padding-right:.5rem;padding-left:.5rem}}dialog{display:block;border:none;opacity:0;visibility:hidden;position:fixed;box-shadow:var(--elevate2);color:var(--on-surface);background-color:var(--surface-container-high);padding:1.5rem;z-index:100;inset:10% auto auto 50%;min-inline-size:20rem;max-inline-size:100%;max-block-size:80%;overflow-x:hidden;overflow-y:auto;transition:var(--speed3) all,0s background-color;border-radius:1.75rem;transform:translate(-50%,-4rem)}dialog::backdrop{display:none}dialog.small{inline-size:25%;block-size:25%}dialog.medium{inline-size:50%;block-size:50%}dialog.large{inline-size:75%;block-size:75%}dialog:is(.active,[open]){opacity:1;visibility:visible;transform:translate(-50%)}dialog:is(.active,[open]):is(.left,.right,.top,.bottom,.max){transform:translate(0)}dialog.top{opacity:1;padding:1rem;inset:0 auto auto 0;block-size:auto;inline-size:100%;min-inline-size:auto;max-block-size:100%;transform:translateY(-100%);border-radius:0 0 1rem 1rem}dialog.left{opacity:1;padding:1rem;inset:0 auto auto 0;inline-size:auto;block-size:100%;max-block-size:100%;border-radius:0 1rem 1rem 0;background-color:var(--surface);transform:translate(-100%)}dialog.right{opacity:1;padding:1rem;inset:0 0 auto auto;inline-size:auto;block-size:100%;max-block-size:100%;border-radius:1rem 0 0 1rem;background-color:var(--surface);transform:translate(100%)}dialog.bottom{opacity:1;padding:1rem;inset:auto auto 0 0;block-size:auto;inline-size:100%;min-inline-size:auto;max-block-size:100%;transform:translateY(100%);border-radius:1rem 1rem 0 0}dialog.max{inset:0 auto auto 0;inline-size:100%;block-size:100%;max-inline-size:100%;max-block-size:100%;transform:translateY(4rem);background-color:var(--surface)}dialog.small:is(.left,.right){inline-size:20rem}dialog.medium:is(.left,.right){inline-size:32rem}dialog.large:is(.left,.right){inline-size:44rem}dialog.small:is(.top,.bottom){block-size:16rem}dialog.medium:is(.top,.bottom){block-size:24rem}dialog.large:is(.top,.bottom){block-size:32rem}dialog>a.row:is(:hover,.active){background-color:var(--secondary-container)}dialog>.row{padding:.75rem}summary.none{list-style-type:none}summary.none::-webkit-details-marker{display:none}summary{cursor:pointer}summary:focus{outline:none}.field{block-size:3rem;margin-block-end:2rem}*+.field{margin-block-start:1rem}.grid>*>.field{margin-block-end:1rem}.grid>*>.field+.field{margin-block-start:2rem}.grid.no-space>*>.field+.field{margin-block-start:1rem}.grid.medium-space>*>.field+.field{margin-block-start:2.5rem}.grid.large-space>*>.field+.field{margin-block-start:3rem}.field.small{block-size:2.5rem}.field.large{block-size:3.5rem}.field.extra{block-size:4rem}.field{border-radius:.25rem .25rem 0 0}.field.border{border-radius:.25rem}.field.round.small{border-radius:1.25rem}.field.round{border-radius:1.5rem}.field.round.large{border-radius:1.75rem}.field.round.extra{border-radius:2rem}.field:before{content:"";position:absolute;inset:0;border-radius:inherit;background-color:inherit}.field.fill:before{background-color:var(--surface-container-highest);color:var(--on-surface-variant)}.field>:is(i,img,svg,progress,a:not(.helper,.error)){position:absolute;inset:50% auto auto auto;transform:translateY(-50%);cursor:pointer;z-index:0;inline-size:1.5rem;block-size:1.5rem}.field>:is(i,img,svg,progress,a:not(.helper,.error)),[dir=rtl] .field>:is(i,img,svg,progress,a:not(.helper,.error)):first-child{inset:50% 1rem auto auto}.field>:is(i,img,svg,progress,a:not(.helper,.error)):first-child,[dir=rtl] .field>:is(i,img,svg,progress,a:not(.helper,.error)){inset:50% auto auto 1rem}.field.invalid>i{color:var(--error)}.field>progress.circle{inset-block-start:calc(50% - .75rem)!important;border-width:.1875rem}.field>a:not(.helper,.error){z-index:10}.field>a>:is(i,img,svg,progress,a:not(.helper,.error)){inline-size:1.5rem;block-size:1.5rem}.field>:is(input,textarea,select){appearance:none;border:.0625rem solid transparent;padding:0 .9375rem;font-family:inherit;font-size:1rem;inline-size:100%;block-size:100%;outline:none;z-index:1;background:none;resize:none}.field>:is(input,textarea,select):focus{border:.125rem solid transparent;padding:0 .875rem}input[type=file],input[type=color],:not(.field)>input[type^=date],:not(.field)>input[type^=time],input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit-calendar-picker-indicator{opacity:0;position:absolute;inset:0;inline-size:100%;block-size:100%;margin:0;padding:0;border:0;outline:0;z-index:2!important}input::-webkit-search-decoration,input::-webkit-search-cancel-button,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none}.field.border>:is(input,textarea,select){border-color:var(--outline)}.field.border>:is(input,textarea,select):focus{border-color:var(--primary)}.field.round>:is(input,textarea,select){padding-inline:1.4376rem}.field.round>:is(input,textarea,select):focus{padding-inline:1.375rem}.field.prefix>:is(input,textarea,select){padding-inline-start:2.9375rem}.field.prefix>.slider{margin-inline-start:3.5rem}.field.prefix>:is(input,textarea,select):focus{padding-inline-start:2.875rem}.field.suffix>:is(input,textarea,select){padding-inline-end:2.9375rem}.field.suffix>.slider{margin-inline-end:3.5rem}.field.suffix>:is(input,textarea,select):focus{padding-inline-end:2.875rem}.field:not(.border,.round)>:is(input,textarea,select){border-block-end-color:var(--outline)}.field:not(.border,.round)>:is(input,textarea,select):focus{border-block-end-color:var(--primary)}.field.round:not(.border,.fill)>:is(input,textarea,select),.field.round:not(.border)>:is(input,textarea,select):focus{box-shadow:var(--elevate1)}.field.round:not(.border,.fill)>:is(input,textarea,select):focus{box-shadow:var(--elevate2)}.field.invalid:not(.border,.round)>:is(input,textarea,select),.field.invalid:not(.border,.round)>:is(input,textarea,select):focus{border-block-end-color:var(--error)}.field.invalid.border>:is(input,textarea,select),.field.invalid.border>:is(input,textarea,select):focus{border-color:var(--error)}.field:has(> :disabled){opacity:.5;cursor:not-allowed}.field>:disabled{cursor:not-allowed}.field.small.textarea{block-size:4.5rem}.field.textarea{block-size:5.5rem}.field.large.textarea{block-size:6.5rem}.field.extra.textarea{block-size:7.5rem}.field>select>option{background-color:var(--surface-container);color:var(--on-surface)}.field.label>:is(input,select){padding-block-start:1rem}.field.label.border:not(.fill)>:is(input,select){padding-block-start:0}.field.label.small>textarea{padding-block-start:1.125rem}.field.label>textarea{padding-block-start:1.375rem}.field.label.large>textarea{padding-block-start:1.625rem}.field.label.extra>textarea{padding-block-start:1.875rem}.field.small>textarea,.field.small:not(.label)>textarea:focus,.field.small.border:not(.fill)>textarea{padding-block-start:.625rem}.field>textarea,.field:not(.label)>textarea:focus,.field.border:not(.fill)>textarea{padding-block-start:.875rem}.field.large>textarea,.field.large:not(.label)>textarea:focus,.field.large.border:not(.fill)>textarea{padding-block-start:1.125rem}.field.extra>textarea,.field.extra:not(.label)>textarea:focus,.field.extra.border:not(.fill)>textarea{padding-block-start:1.375rem}.field.small.border:not(.fill)>textarea:focus{padding-block-start:.5625rem!important}.field.border:not(.fill)>textarea:focus{padding-block-start:.8125rem!important}.field.large.border:not(.fill)>textarea:focus{padding-block-start:1.0625rem!important}.field.extra.border:not(.fill)>textarea:focus{padding-block-start:1.3125rem!important}.field.label>label{position:absolute;inset:-.5rem auto auto 1rem;display:flex;inline-size:calc(100% - 5rem);block-size:4rem;line-height:4rem;font-size:1rem;transition:all .2s;gap:.25rem;white-space:nowrap}[dir=rtl] .field.label>label{inset:-.5rem 1rem auto auto}.field.label.small>label{block-size:3.5rem;line-height:3.5rem}.field.label.large>label{block-size:4.5rem;line-height:4.5rem}.field.label.extra>label{block-size:5rem;line-height:5rem}.field.label.border.prefix:not(.fill)>:is(label.active,:focus + label,[placeholder]:not(:placeholder-shown) + label,select + label){inset-inline-start:1rem}.field.label.round>label,.field.label.border.prefix.round:not(.fill)>:is(label.active,:focus + label,[placeholder]:not(:placeholder-shown) + label,select + label){inset-inline-start:1.5rem}.field.label.prefix>label{inset-inline-start:3rem}.field.label>:is(label.active,:focus + label,[placeholder]:not(:placeholder-shown) + label,select + label){block-size:2.5rem;line-height:2.5rem;font-size:.75rem}.field.label.border:not(.fill)>:is(label.active,:focus + label,[placeholder]:not(:placeholder-shown) + label,select + label){block-size:1rem;line-height:1rem}.field.label.border:not(.fill)>label:after{content:"";display:block;margin-block-start:.5rem;border-block-start:.0625rem solid var(--outline);block-size:1rem;transition:none;flex:auto}.field.label.border:not(.fill)>:focus+label:after{border-block-start:.125rem solid var(--primary)}.field.label.border:not(.fill)>:is(input,textarea):is(:focus,[placeholder]:not(:placeholder-shown),.active),.field.label.border:not(.fill)>select{clip-path:polygon(-2% -2%,.75rem -2%,.75rem .5rem,calc(100% - 5rem) .5rem,calc(100% - 5rem) -2%,102% -2%,102% 102%,-2% 102%)}[dir=rtl] .field.label.border:not(.fill)>:is(input,textarea):is(:focus,[placeholder]:not(:placeholder-shown),.active),[dir=rtl] .field.label.border:not(.fill)>select{clip-path:polygon(-2% -2%,5rem -2%,5rem .5rem,calc(100% - .75rem) .5rem,calc(100% - .75rem) -2%,102% -2%,102% 102%,-2% 102%)}.field.label.border.round:not(.fill)>:is(input,textarea):is(:focus,[placeholder]:not(:placeholder-shown),.active),.field.label.border.round:not(.fill)>select{clip-path:polygon(-2% -2%,1.25rem -2%,1.25rem .5rem,calc(100% - 5rem) .5rem,calc(100% - 5rem) -2%,102% -2%,102% 102%,-2% 102%)}[dir=rtl] .field.label.border.round:not(.fill)>:is(input,textarea):is(:focus,[placeholder]:not(:placeholder-shown),.active),[dir=rtl] .field.label.border.round:not(.fill)>select{clip-path:polygon(-2% -2%,5rem -2%,5rem .5rem,calc(100% - 1.25rem) .5rem,calc(100% - 1.25rem) -2%,102% -2%,102% 102%,-2% 102%)}.field.label>:focus+label{color:var(--primary)}.field.label.invalid>label,.field.label.invalid>label:after{color:var(--error)!important;border-color:var(--error)!important}.field.label>label>a{block-size:inherit;line-height:inherit;inline-size:1rem}.field.label>label>a>:is(i,img,svg){block-size:1rem;line-height:1rem;inline-size:1rem;font-size:1rem}.field>:is(.helper,.error){position:absolute;inset:auto auto 0 1rem;transform:translateY(100%);font-size:.75rem;background:none!important;padding-block-start:.125rem}a.helper{color:var(--primary)}.field>.error{color:var(--error)!important}.field.round>:is(.helper,.error){inset-inline-start:1.5rem}.field.invalid>.helper{display:none}table td>.field{margin:0}.grid{---gap: 1rem;display:grid;grid-template-columns:repeat(12,calc(8.33% - var(---gap) + (var(---gap) / 12)));gap:var(---gap)}*+.grid{margin-block-start:1rem}.grid.no-space{---gap: 0rem}.grid.medium-space{---gap: 1.5rem}.grid.large-space{---gap: 2rem}.s1{grid-area:auto/span 1}.s2{grid-area:auto/span 2}.s3{grid-area:auto/span 3}.s4{grid-area:auto/span 4}.s5{grid-area:auto/span 5}.s6{grid-area:auto/span 6}.s7{grid-area:auto/span 7}.s8{grid-area:auto/span 8}.s9{grid-area:auto/span 9}.s10{grid-area:auto/span 10}.s11{grid-area:auto/span 11}.s12{grid-area:auto/span 12}@media only screen and (min-width: 601px){.m1{grid-area:auto/span 1}.m2{grid-area:auto/span 2}.m3{grid-area:auto/span 3}.m4{grid-area:auto/span 4}.m5{grid-area:auto/span 5}.m6{grid-area:auto/span 6}.m7{grid-area:auto/span 7}.m8{grid-area:auto/span 8}.m9{grid-area:auto/span 9}.m10{grid-area:auto/span 10}.m11{grid-area:auto/span 11}.m12{grid-area:auto/span 12}}@media only screen and (min-width: 993px){.l1{grid-area:auto/span 1}.l2{grid-area:auto/span 2}.l3{grid-area:auto/span 3}.l4{grid-area:auto/span 4}.l5{grid-area:auto/span 5}.l6{grid-area:auto/span 6}.l7{grid-area:auto/span 7}.l8{grid-area:auto/span 8}.l9{grid-area:auto/span 9}.l10{grid-area:auto/span 10}.l11{grid-area:auto/span 11}.l12{grid-area:auto/span 12}}i{---size: 1.5rem;font-family:var(--font-icon);font-weight:400;font-style:normal;font-size:var(---size);letter-spacing:normal;text-transform:none;display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;word-wrap:normal;direction:ltr;font-feature-settings:"liga";-webkit-font-smoothing:antialiased;vertical-align:middle;text-align:center;overflow:hidden;inline-size:var(---size);min-inline-size:var(---size);block-size:var(---size);min-block-size:var(---size);box-sizing:content-box;line-height:normal}i.tiny{---size: 1rem}.chip>i,i.small{---size: 1.25rem}i.medium{---size: 1.5rem}i.large{---size: 1.75rem}i.extra{---size: 2rem}i.fill,a.row:is(:hover,:focus)>i,.transparent:is(:hover,:focus)>i{font-variation-settings:"FILL" 1}i>:is(img,svg){inline-size:100%;block-size:100%;background-size:100%;border-radius:inherit;position:absolute;inset:0 auto auto 0;padding:inherit}i[class*=fa-]{font-size:calc(var(---size) * .85);line-height:normal;block-size:auto;min-block-size:auto}.absolute{position:absolute}.fixed{position:fixed}:is(.absolute,.fixed).left.right{inline-size:auto}:is(.absolute,.fixed).left.right.small{block-size:20rem}:is(.absolute,.fixed).left.right.medium{block-size:28rem}:is(.absolute,.fixed).left.right.large{block-size:44rem}:is(.absolute,.fixed).top.bottom.small{inline-size:20rem}:is(.absolute,.fixed).top.bottom.medium{inline-size:28rem}:is(.absolute,.fixed).top.bottom.large{inline-size:44rem}header,footer{display:flex;justify-content:center;flex-direction:column;min-block-size:4rem;padding:0 1rem;background-color:var(--surface-container)}main~footer{min-block-size:5rem}:is(header,footer).fixed.responsive{z-index:12}:is(header,footer,menu > *).fixed{position:sticky;inset:0;z-index:11;background-color:inherit}:is(dialog,menu,nav,article)>:is(header,footer){background-color:inherit;padding:0}:is(dialog,article,[class*=padding])>:is(header,footer).fixed{---translateY: 1rem;transform:translateY(var(---translateY))}:is(dialog,article,[class*=padding])>header.fixed{transform:translateY(calc(-1 * var(---translateY)))}.no-padding>:is(header,footer).fixed{transform:none}.small-padding>:is(header,footer).fixed{---translateY: .5rem}:is(.large-padding,dialog:not(.left,.right,.top,.bottom))>:is(header,footer).fixed{---translateY: 1.5rem}svg{fill:currentColor}:is(img,svg,video):is(.small,.medium,.large,.tiny,.extra,.round,.circle,.responsive){object-fit:cover;object-position:center;transition:var(--speed3) transform,var(--speed3) border-radius,var(--speed3) padding;block-size:3rem;inline-size:3rem}:is(img,svg,video).round{border-radius:.5rem}:is(img,svg,video).tiny{block-size:2rem;inline-size:2rem}:is(img,svg,video).small{block-size:2.5rem;inline-size:2.5rem}:is(img,svg,video).large{block-size:3.5rem;inline-size:3.5rem}:is(img,svg,video).extra{block-size:4rem;inline-size:4rem}:is(img,svg,video).responsive{inline-size:100%;block-size:100%;margin:0 auto}:is(button,.button,.chip):not(.transparent)>.responsive{border:.25rem solid transparent}:is(button.small,.button.small,.chip)>.responsive{inline-size:2rem}:is(button,.button,.chip.medium)>.responsive{inline-size:2.5rem}:is(button,.button,.chip).large>.responsive{inline-size:3rem}:is(button,.button,.chip).extra>.responsive{inline-size:3.5rem}:is(img,svg,video).responsive.tiny{inline-size:100%;block-size:4rem}:is(img,svg,video).responsive.small{inline-size:100%;block-size:8rem}:is(img,svg,video).responsive.medium{inline-size:100%;block-size:12rem}:is(img,svg,video).responsive.large{inline-size:100%;block-size:16rem}:is(img,svg,video).responsive.extra{inline-size:100%;block-size:20rem}:is(img,svg,video).responsive.round{border-radius:2rem}:is(img,svg,video).empty-state{max-inline-size:100%;inline-size:24rem}:is(button,.button,.chip,.field)>:is(img,svg):not(.responsive,.tiny,.small,.medium,.large,.extra),:is(.tabs) :is(img,svg):not(.responsive,.tiny,.small,.medium,.large,.extra){min-inline-size:1.5rem;max-inline-size:1.5rem;min-block-size:1.5rem;max-block-size:1.5rem}:is(button,.button,.chip)>:is(i,img,svg),:is(button,.button,.chip)>.responsive{margin:0 -.5rem}:is(button,.button)>.responsive{margin-inline-start:-1.5rem}:is(button,.button)>span+.responsive{margin-inline-start:-.5rem;margin-inline-end:-1.5rem}.chip>.responsive{margin-inline-start:-1rem}.chip>span+.responsive{margin-inline-start:-.5rem;margin-inline-end:-1rem}:is(.circle,.square)>.responsive{margin:0}.extend>:is(.responsive,i){margin:0;position:absolute;inset-inline:1rem;z-index:1}.extend>.responsive{inset-inline:0;inline-size:3.5rem}.extend.border>.responsive{inline-size:3.375rem}menu>li{all:unset}menu{opacity:0;visibility:hidden;position:absolute;box-shadow:var(--elevate2);background-color:var(--surface-container);z-index:11;inset:auto auto 0 0;inline-size:100%;max-block-size:50vh;max-inline-size:none!important;overflow-x:hidden;overflow-y:auto;font-size:.875rem;font-weight:400;text-transform:none;color:var(--on-surface);line-height:normal;text-align:start;border-radius:.25rem;transform:scale(.8) translateY(120%);transition:var(--speed2) all,0s background-color}menu.no-wrap{inline-size:max-content;white-space:nowrap!important}menu.active,menu:not([data-ui]):active,:not([data-ui]):focus-within>menu{opacity:1;visibility:visible;transform:scale(1) translateY(100%)}menu *{white-space:inherit!important}menu>a,menu>li>a{padding:.5rem 1rem;min-block-size:3rem;flex:1}menu>a:not(.row),menu>li>a:not(.row){display:flex;flex-direction:column;align-items:flex-start}menu>a:is(:hover,:focus,.active),menu>li>a:is(:hover,:focus,.active){background-color:var(--active)}menu.min{inset:0 0 auto 0;transform:none!important;border-radius:inherit}menu.max{position:fixed;inset:0;block-size:100%;max-block-size:none;min-block-size:auto;z-index:100;transform:none!important}menu.no-wrap:is(.min,.max){min-inline-size:16rem}menu.left{inset:auto 0 0 auto}menu.right{inset:auto auto 0 0}nav>:is(ol,ul),nav>:is(ol,ul)>li{all:unset}nav,.row,a.row,nav.drawer>:is(a,label),nav.drawer>:is(ol,ul)>li>:is(a,label){display:flex;align-items:center;align-self:normal;text-align:start;justify-content:flex-start;white-space:nowrap;gap:1rem;margin:0}:is(nav,.row,.max)>:only-child,nav>:is(ol,ul)>li>:only-child{margin:0}*+:is(nav,.row){margin-block-start:1rem}:is(nav,.row)>*{margin:0;white-space:normal;flex:none}:is(nav,.row).no-space{gap:0}:is(nav,.row).no-space>.border+.border{border-inline-start:0}:is(nav,.row).medium-space{gap:1.5rem}:is(nav,.row).large-space{gap:2rem}:is(nav,.row)>.max,:is(nav,.row)>:is(ol,ul)>.max,nav.drawer>:is(a,label)>.max,nav.drawer>:is(ol,ul)>li>:is(a,label)>.max{flex:1}:is(nav,.row).wrap{display:flex;flex-wrap:wrap}:is(header,footer)>:is(nav,.row){min-block-size:inherit}:is(nav,.row)>.border.no-margin+.border.no-margin{border-inline-start:0}nav:is(.left,.right,.top,.bottom){border:0;position:fixed;color:var(--on-surface);transform:none;z-index:100;block-size:auto;inline-size:auto;text-align:center;padding:.5rem;margin:0}nav:is(.left,.right){inline-size:5rem;justify-content:flex-start;flex-direction:column;background-color:var(--surface)}nav:is(.top,.bottom){block-size:5rem;justify-content:center;flex-direction:row;background-color:var(--surface-container)}nav.top{inset:0 0 auto 0}nav.left{inset:0 auto 0 0}nav.right{inset:0 0 0 auto}nav.bottom{inset:auto 0 0 0}nav.drawer{flex-direction:column;align-items:normal;inline-size:20rem;gap:0;padding:.5rem 1rem}nav.drawer:is(.min,.max){inline-size:auto}nav.drawer.max{inline-size:100%}:is(nav,.row)>header{background-color:inherit}nav:is(.left,.right)>header{transform:translateY(-.5rem)}nav.drawer>header{transform:translateY(-.75rem);min-block-size:4.5rem;align-self:stretch}nav.drawer>:is(a,label),nav.drawer>:is(ol,ul)>li>:is(a,label),a.row.wave{padding:.75rem;font-size:inherit}nav.drawer>a,nav.drawer>:is(ol,ul)>li>a{border-radius:2rem}nav.drawer>a:is(:hover,.active),nav.drawer>:is(ol,ul)>li>a:is(:hover,.active){background-color:var(--secondary-container)}nav.drawer>a:is(:hover,:focus,.active)>i,nav.drawer>:is(ol,ul)>li>a:is(:hover,:focus,.active)>i{font-variation-settings:"FILL" 1}nav>:is(ol,ul){all:inherit;flex:auto}nav:not(.left,.right,.bottom,.top)>:is(ol,ul){padding:0}nav:is(.left,.right,.top,.bottom):not(.drawer)>a:not(.button,.chip),nav:is(.left,.right,.top,.bottom):not(.drawer)>:is(ol,ul)>li>a:not(.button,.chip){text-align:center;display:flex;flex-direction:column}nav:is(.top,.bottom):not(.drawer)>a:not(.button,.chip),nav:is(.top,.bottom):not(.drawer)>:is(ol,ul)>li>a:not(.button,.chip){inline-size:3.5rem}nav:is(.left,.right,.top,.bottom):not(.drawer)>a:not(.button,.chip)>i,nav:is(.left,.right,.top,.bottom):not(.drawer)>:is(ol,ul)>li>a:not(.button,.chip)>i{padding:.25rem;border-radius:2rem;transition:var(--speed1) padding linear;margin:0 auto}nav:is(.left,.right,.top,.bottom):not(.drawer)>a:not(.button,.chip):is(:hover,:focus,.active)>i,nav:is(.left,.right,.top,.bottom):not(.drawer)>:is(ol,ul)>li>a:not(.button,.chip):is(:hover,:focus,.active)>i{background-color:var(--secondary-container);color:var(--on-secondary-container);padding:.25rem 1rem;font-variation-settings:"FILL" 1}:is(nav,.row):is(.left-align,.top-align,.vertical){justify-content:flex-start}:is(nav,.row):is(.right-align,.bottom-align){justify-content:flex-end}:is(nav,.row):is(.center-align,.middle-align){justify-content:center}:is(nav,.row):is(.left-align,.top-align,.vertical).vertical{align-items:flex-start}:is(nav,.row):is(.right-align,.bottom-align).vertical{align-items:flex-end}:is(nav,.row):is(.center-align,.middle-align).vertical{align-items:center}nav:is(.left,.right):not(.drawer)>*,nav:is(.left,.right):not(.drawer)>:is(ol,ul)>li{align-self:center}:is(.drawer,.vertical)>:is(li,[class*=divider]):not(.vertical),:is(.drawer,.vertical)>:is(ol,ul)>li:not(.vertical){align-self:stretch}nav:not(.left,.right)>.space{inline-size:.5rem}nav:not(.left,.right)>.medium-space{inline-size:1rem}nav:not(.left,.right)>.large-space{inline-size:1.5rem}@media only screen and (max-width: 600px){nav.top,nav.bottom{justify-content:space-around}}.overlay{opacity:0;visibility:hidden;position:fixed;inset:0 auto auto 0;inline-size:100%;block-size:100%;color:var(--on-surface);background-color:var(--overlay);z-index:100;transition:var(--speed3) all,0s background-color}nav>.overlay{z-index:0}.overlay.active{opacity:1;visibility:visible}.page,:is(.page,dialog):not(.active) .page.active{---transform: translate(0, 0);opacity:0;position:absolute;display:none}.page.active{opacity:1;position:inherit;display:inherit;animation:var(--speed4) to-page ease}.page.active.top{---transform: translate(0, -4rem)}.page.active.bottom{---transform: translate(0, 4rem)}.page.active.left{---transform: translate(-4rem, 0)}.page.active.right{---transform: translate(4rem, 0)}@keyframes to-page{0%{opacity:0;transform:var(---transform)}to{opacity:1;transform:translate(0)}}progress{position:relative;inline-size:100%;block-size:.5rem;color:var(--primary);background:var(--primary-container);border-radius:1rem;flex:none;border:none;overflow:hidden;writing-mode:horizontal-tb}progress.small{inline-size:4rem}progress.medium{inline-size:8rem}progress.large{inline-size:12rem}progress:not(.circle,[value]):after{content:"";position:absolute;inset:0;inline-size:100%;block-size:100%;clip-path:none;background:currentColor;animation:1.6s to-linear ease infinite}progress:not(.circle,[value])::-moz-progress-bar{animation:1.6s to-linear ease infinite}progress:not(.circle,[value])::-webkit-progress-value{animation:1.6s to-linear ease infinite}progress::-webkit-progress-bar{background:none}progress::-webkit-progress-value{background:currentColor}progress::-moz-progress-bar{background:currentColor}progress.circle{display:inline-block;inline-size:2.5rem;block-size:2.5rem;border-radius:50%;border-width:.3rem;border-style:solid;border-color:currentColor;animation:1.6s to-circular linear infinite;background:none;flex:none}progress.circle::-moz-progress-bar{background:none}progress.circle.small{inline-size:1.5rem;block-size:1.5rem;border-width:.2rem}progress.circle.large{inline-size:3.5rem;block-size:3.5rem;border-width:.4rem}:is(nav,.row,.field)>progress:not(.circle,.small,.medium,.large){flex:auto}progress.max{display:unset;position:absolute;inline-size:100%!important;block-size:100%!important;color:var(--active);background:none;inset:0;border-radius:inherit;animation:none;writing-mode:horizontal-tb}progress:is(.horizontal,.vertical,.max){display:unset;inline-size:100%!important}progress.vertical{writing-mode:vertical-lr}:has(> progress)>:not(progress){z-index:1}@keyframes to-linear{0%{margin-inline-start:0%;inline-size:0%}50%{margin-inline-start:0%;inline-size:100%}to{margin-inline-start:100%;inline-size:0%}}@keyframes to-circular{0%{transform:rotate(0);clip-path:polygon(50% 50%,0% 0%,50% 0%,50% 0%,50% 0%,50% 0%,50% 0%,50% 0%,50% 0%)}20%{clip-path:polygon(50% 50%,0% 0%,50% 0%,100% 0%,100% 0%,100% 0%,100% 0%,100% 0%,100% 0%)}30%{clip-path:polygon(50% 50%,0% 0%,50% 0%,100% 0%,100% 50%,100% 50%,100% 50%,100% 50%,100% 50%)}40%{clip-path:polygon(50% 50%,0% 0%,50% 0%,100% 0%,100% 50%,100% 100%,100% 100%,100% 100%,100% 100%)}50%{clip-path:polygon(50% 50%,50% 0%,50% 0%,100% 0%,100% 50%,100% 100%,50% 100%,50% 100%,50% 100%)}60%{clip-path:polygon(50% 50%,100% 50%,100% 50%,100% 50%,100% 50%,100% 100%,50% 100%,0% 100%,0% 100%)}70%{clip-path:polygon(50% 50%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,0% 100%,0% 50%)}80%{clip-path:polygon(50% 50%,0% 100%,0% 100%,0% 100%,0% 100%,0% 100%,0% 100%,0% 100%,0% 50%)}90%{transform:rotate(360deg);clip-path:polygon(50% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%)}to{clip-path:polygon(50% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%,0% 50%)}}.checkbox,.radio,.switch{direction:ltr;inline-size:auto;block-size:auto;line-height:normal;white-space:nowrap;cursor:pointer;display:inline-flex;align-items:center}:is(.checkbox,.radio)>input{inline-size:1.5rem;block-size:1.5rem;opacity:0}.switch>input{inline-size:3.25rem;block-size:2rem;opacity:0}:is(.checkbox,.radio,.switch)>span{display:inline-flex;align-items:center;color:var(--on-surface);font-size:.875rem}:is(.checkbox,.radio)>span:not(:empty){padding-inline-start:.25rem}:is(.checkbox,.radio,.switch)>span:before,.icon>span>i{font-family:var(--font-icon);font-weight:400;font-style:normal;font-size:1.5rem;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;font-feature-settings:"liga";-webkit-font-smoothing:antialiased;vertical-align:middle;text-align:center;overflow:hidden;inline-size:1.5rem;block-size:1.5rem;box-sizing:border-box;margin:0 auto;outline:none;color:var(--primary);position:absolute;inset:auto auto auto -1.5rem;background-color:transparent;border-radius:50%;user-select:none;z-index:1;box-shadow:0 0 0 0 var(--active);transition:var(--speed1) all}.switch>span:before,.switch.icon>span>i{position:absolute;inset:50% auto auto 0;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;transition:var(--speed2) all;font-size:1rem;user-select:none;min-inline-size:auto;content:"";color:var(--surface-variant);background-color:var(--outline)}.switch>span:before,.switch.icon>span>i{transform:translate(-3rem,-50%) scale(.6)}.switch.icon>span>i{transform:translate(-3rem,-50%) scale(1)}.checkbox>span:before{content:"check_box_outline_blank"}.radio>span:before{content:"radio_button_unchecked"}.checkbox>input:checked+span:before{content:"check_box";font-variation-settings:"FILL" 1}.radio>input:checked+span:before{content:"radio_button_checked"}:is(.radio,.checkbox,.switch).icon>span:before{content:""!important;font-variation-settings:unset!important}:is(.checkbox,.radio)>input:not(:disabled):is(:focus,:hover)+span:before{background-color:var(--active);box-shadow:0 0 0 .5rem var(--active)}.switch>input:not(:disabled):is(:focus,:hover)+span:before,.switch.icon>input:not(:disabled):is(:focus,:hover)+span>i{box-shadow:0 0 0 .5rem var(--active)}:is(.checkbox,.radio)>input:checked+span:before,:is(.checkbox,.radio).icon>input:checked+span>i{color:var(--primary)}.icon>input:checked+span>i:first-child,.icon>span>i:last-child{opacity:0}.icon>input:checked+span>i:last-child,.icon>span>i:first-child{opacity:1}.switch>input:checked+span:after{border:none;background-color:var(--primary)}.switch>input:checked+span:before,.switch.icon>input:checked+span>i{content:"check";color:var(--primary);background-color:var(--on-primary)}.switch>input:checked+span:before,.switch.icon>input:checked+span>i{transform:translate(-1.75rem,-50%) scale(1)}:is(.checkbox,.radio,.switch)>input:disabled+span{opacity:.5;cursor:not-allowed}.switch>span:after{content:"";position:absolute;inset:50% auto auto 0;background-color:var(--active);border:.125rem solid var(--outline);box-sizing:border-box;inline-size:3.25rem;block-size:2rem;border-radius:2rem}.switch>span:after{transform:translate(-3.25rem,-50%)}.field>:is(nav,.row){flex-grow:1;padding:0 1rem}.field.round>:is(nav,.row){flex-grow:1;padding:0 1.5rem}.slider{---start: 0%;---end: 0%;---value1: "";---value2: "";display:flex;align-items:center!important;inline-size:auto;block-size:1.25rem;margin:1.125rem;flex:none}.slider.vertical{flex-direction:row!important;margin:.5rem auto!important;padding:50% 0;transform:rotate(-90deg);inline-size:100%}.slider.small{inline-size:4rem}.slider.medium{inline-size:8rem}.slider.large{inline-size:12rem}.slider>input{appearance:none;box-shadow:none;border:none;outline:none;pointer-events:none;inline-size:100%;block-size:1rem;background:none;z-index:1;padding:0;margin:0}.slider>input:focus~.tooltip{visibility:visible}.slider>input:only-of-type{pointer-events:all}.slider>input+input{position:absolute}.slider>input::-webkit-slider-thumb{appearance:none;box-shadow:none;border:none;outline:none;pointer-events:all;block-size:2.75rem;inline-size:.25rem;border-radius:.25rem;background:var(--primary);cursor:grab;margin:0}.slider>input::-webkit-slider-thumb:active{cursor:grabbing}.slider>input::-moz-range-thumb{appearance:none;box-shadow:none;border:none;outline:none;pointer-events:all;block-size:2.75rem;inline-size:.25rem;border-radius:.25rem;background:var(--primary);cursor:grab;margin:0}.slider>input::-moz-range-thumb:active{cursor:grabbing}.slider>input:not(:disabled):is(:focus)::-webkit-slider-thumb{transform:scaleX(.6)}.slider>input:not(:disabled):is(:focus)::-moz-range-thumb{transform:scaleX(.6)}.slider>input:disabled{cursor:not-allowed;opacity:1}.slider>input:disabled::-webkit-slider-thumb{background:#9E9E9E;cursor:not-allowed}.slider>input:disabled::-moz-range-thumb{background:#9E9E9E;cursor:not-allowed}.slider>input:disabled~span{background:#9E9E9E}.slider>span{position:absolute;block-size:1rem;border-radius:1rem 0 0 1rem;background:var(--primary);z-index:0;inset:calc(50% - .5rem) var(---end) auto var(---start);clip-path:polygon(0 0,calc(100% - .5rem) 0,calc(100% - .5rem) 100%,0 100%)}.slider>input+input~span{border-radius:0;clip-path:polygon(.5rem 0,max(.5rem,calc(100% - .5rem)) 0,max(.5rem,calc(100% - .5rem)) 100%,.5rem 100%)}[dir=rtl] .slider>span{inset:calc(50% - .5rem) var(---start) auto var(---end)}.field>.slider{inline-size:100%}.slider:before{content:"";position:absolute;inline-size:100%;block-size:1rem;border-radius:1rem;background:var(--primary-container);clip-path:polygon(calc(var(---start) - .5rem) 0,0 0,0 100%,calc(var(---start) - .5rem) 100%,calc(var(---start) - .5rem) 0,calc(100% - var(---end) + .5rem) 0,100% 0,100% 100%,calc(100% - var(---end) + .5rem) 100%,calc(100% - var(---end) + .5rem) 0)}.slider:has(> [disabled]):before{background:var(--active)}.slider>.tooltip,.slider:hover>.tooltip{opacity:0;inset:0 auto auto calc(100% - var(---end));border-radius:2rem;transition:var(--speed2) ease top,var(--speed2) ease opacity;transform:translate(-50%,-50%)!important;padding:.75rem 1rem;z-index:0}[dir=rtl] .slider>.tooltip{inset:.25rem auto auto var(---end)}.slider>.tooltip+.tooltip{inset:.25rem calc(100% - var(---start)) auto auto;transform:translate(50%,-50%)!important}[dir=rtl] .slider>.tooltip+.tooltip{inset:.25rem var(---start) auto auto}.slider>.tooltip:before{content:var(---value1)}.slider>.tooltip+.tooltip:before{content:var(---value2)}.slider>input:focus~.tooltip{inset-block-start:-1rem!important;opacity:1}.slider.vertical>.tooltip{display:none}:is(nav,.row,.field)>.slider:not(.circle,.small,.medium,.large){flex:auto}.snackbar{---transform-start: translate(-50%, 1rem);---transform-end: translate(-50%, 0);position:fixed;inset:auto auto 6rem 50%;inline-size:80%;block-size:auto;z-index:200;visibility:hidden;display:flex;box-shadow:var(--elevate2);color:var(--inverse-on-surface);background-color:var(--inverse-surface);padding:1rem;opacity:1;cursor:pointer;text-align:start;align-items:center;border-radius:.25rem;gap:.5rem;transform:var(---transform-end)}.snackbar.top{inset:6rem auto auto 50%}.snackbar.active{visibility:visible;animation:var(--speed2) to-snackbar}.snackbar.active.top{---transform-end: translate(-50%, -1rem)}.snackbar>.max{flex:auto}@keyframes to-snackbar{0%{opacity:0;transform:var(---transform-start)}to{opacity:1;transform:var(---transform-end)}}@media only screen and (min-width: 993px){.snackbar{inline-size:40%}}table{---stripes: rgb(0 0 0 / .05);inline-size:100%;border-spacing:0;font-size:.875rem;color:var(--on-surface);text-align:start;background-color:var(--surface)}.dark table{---stripes: rgb(255 255 255 / .05)}table :is(thead,tbody,tfoot,tr,th){background-color:inherit}:is(th,td){inline-size:auto;max-inline-size:1rem;text-align:inherit;padding:.5rem}:is(th,td)>*{vertical-align:middle;z-index:0}table.border>tbody>tr:not(:last-child)>td,thead>tr>th{border-block-end:.0625rem solid var(--outline)}tfoot>tr>th{border-block-start:.0625rem solid var(--outline)}table.stripes>tbody>tr:nth-child(odd){background-color:var(---stripes)}table.no-space :is(th,td){padding:0}table.medium-space :is(th,td){padding:.75rem}table.large-space :is(th,td){padding:1rem}table>.fixed,th.fixed{position:sticky;z-index:1;inset-block-start:0}tfoot.fixed,tfoot th.fixed{inset-block-end:0}:is(td,th).min{inline-size:0;max-inline-size:0%;white-space:nowrap}.tabs{display:flex;white-space:nowrap;border-block-end:.0625rem solid var(--surface-variant)}.tabs.min{padding:0 1rem;gap:2rem}.tabs:not(.left-align,.right-align,.center-align){justify-content:space-around}*+.tabs{margin-block-start:1rem}.tabs>a{display:flex;font-size:.875rem;font-weight:500;color:var(--on-surface-variant);padding:.5rem 1rem;border-block-end:.125rem solid transparent;text-align:center;min-block-size:3rem;inline-size:100%;gap:.25rem}.tabs.min>a{inline-size:auto;padding:.5rem 0}.tabs.small>a{min-block-size:2rem}.tabs.large>a{min-block-size:4rem}.tabs>a.active{color:var(--primary);border-block-end:.125rem solid var(--primary)}.tabs>a.active>i{color:var(--primary)}.tabs:is(.left-align,.center-align,.right-align)>a{inline-size:auto}.tooltip{---space: -.5rem;visibility:hidden;display:flex;align-items:center;justify-content:center;gap:.5rem;background-color:var(--inverse-surface);color:var(--inverse-on-surface);font-size:.75rem;text-align:center;border-radius:.25rem;padding:.5rem;position:absolute;z-index:3;inset:0 auto auto 50%;inline-size:auto;white-space:nowrap;font-weight:500;opacity:0;transition:var(--speed2) all;line-height:normal;transform:translate(-50%,-100%) scale(.9)}.tooltip.left{inset:50% auto auto 0;transform:translate(-100%,-50%) scale(.9)}.tooltip.right{inset:50% 0 auto auto;transform:translate(100%,-50%) scale(.9)}.tooltip.bottom{inset:auto auto 0 50%;transform:translate(-50%,100%) scale(.9)}.tooltip.small{inline-size:8rem;white-space:normal}.tooltip.medium{inline-size:12rem;white-space:normal}.tooltip.large{inline-size:16rem;white-space:normal}:hover>.tooltip{visibility:visible;opacity:1;transform:translate(-50%,-100%) scale(1)}:hover>.tooltip.left{transform:translate(-100%,-50%) scale(1)}:hover>.tooltip.right{transform:translate(100%,-50%) scale(1)}:hover>.tooltip.bottom{transform:translate(-50%,100%) scale(1)}.tooltip.no-space{---space: 0}.tooltip.medium-space{---space: -1rem}.tooltip.large-space{---space: -1.5rem}.tooltip:not(.left,.right,.bottom){margin-block-start:var(---space)!important}.tooltip.left,.tooltip.right{margin-inline:var(---space)!important}.tooltip.bottom{margin-block-end:var(---space)!important}menu:active~.tooltip,:is(button,.button):focus>menu~.tooltip,.field>:focus~menu~.tooltip{visibility:hidden}.slider>.tooltip{---space: -1.25rem}.slider.vertical>.tooltip{---space: -.75rem}.slider.vertical>.tooltip:is(.left,.right){---space: -.5rem}.tooltip.max{display:block;font-size:inherit;white-space:normal;text-align:start;inline-size:20rem;border-radius:.5rem;padding:1rem;box-shadow:var(--elevate2)}[class*=blur],[class*=blur].light{---blur: 1rem;-webkit-backdrop-filter:blur(var(---blur));backdrop-filter:blur(var(---blur));color:var(--on-surface);background-color:#ffffff80}.dark [class*=blur],[class*=blur].dark{background-color:#00000080}.small-blur{---blur: .5rem}.large-blur{---blur: 1.5rem}.shadow{background-color:#00000050}:is(.left-shadow,.right-shadow,.top-shadow,.bottom-shadow){background-color:transparent!important}.left-shadow{background-image:linear-gradient(to right,black,transparent)}.right-shadow{background-image:linear-gradient(to left,black,transparent)}.bottom-shadow{background-image:linear-gradient(to top,black,transparent)}.top-shadow{background-image:linear-gradient(to bottom,black,transparent)} diff --git a/TYTDLite/Assets/beer.min.js b/TYTDLite/Assets/beer.min.js new file mode 100644 index 0000000..5aaffae --- /dev/null +++ b/TYTDLite/Assets/beer.min.js @@ -0,0 +1,4 @@ +export default (() => { +let k,F,N,P;const s={light:"",dark:""},Z=[];async function X(t){return await new Promise(n=>setTimeout(n,t))}function Y(){return"fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{const n=Math.random()*16|0;return(t==="x"?n:n&3|8).toString(16)})}function h(t,n){try{return typeof t=="string"?(n!=null?n:document).querySelector(t):t}catch{return null}}function l(t,n){try{return typeof t=="string"?(n!=null?n:document).querySelectorAll(t):t!=null?t:Z}catch{return Z}}function f(t,n){var e,r;return(r=(e=t==null?void 0:t.classList)==null?void 0:e.contains(n))!=null?r:!1}function L(t,n){var e;return((e=t==null?void 0:t.tagName)==null?void 0:e.toLowerCase())===n}function m(t,n){var e;return((e=t==null?void 0:t.type)==null?void 0:e.toLowerCase())===n}function p(t,n){var e;(e=t==null?void 0:t.classList)==null||e.add(n)}function u(t,n){var e;(e=t==null?void 0:t.classList)==null||e.remove(n)}function g(t,n,e,r=!0){t==null||t.addEventListener(n,e,r)}function G(t,n,e,r=!0){t==null||t.removeEventListener(n,e,r)}function J(t,n){var e;(e=n==null?void 0:n.parentNode)==null||e.insertBefore(t,n)}function D(t){return t==null?void 0:t.previousElementSibling}function H(t){return t==null?void 0:t.nextElementSibling}function T(t){return t==null?void 0:t.parentElement}function tt(t){const n=document.createElement("div");for(const e in t)n.setAttribute(e,t[e]);return n}function x(t){const n=t;m(n,"number")&&!n.value&&(n.value=""),n.placeholder||(n.placeholder=" "),t.getAttribute("data-ui")&&V(t,null)}function nt(t){V(t.currentTarget,null,null,t)}function et(t){const n=t.currentTarget,e=T(n),r=h("input:not([type=file], [type=checkbox], [type=radio]), select, textarea",e);r&&r.focus()}function rt(t){const n=t.currentTarget;x(n)}function at(t){const n=t.currentTarget;x(n)}function Q(t){G(document.body,"click",Q);const n=t.target;l("menu.active").forEach(r=>z(n,r,t))}function it(t){const n=t.currentTarget;u(n,"active"),k&&clearTimeout(k)}function ot(t){const n=t.currentTarget;q(n)}function ct(t){const n=t.currentTarget;I(n)}function ut(t){const n=t.currentTarget;q(n,t)}function st(t){const n=t.currentTarget;I(n,t)}function j(){F&&clearTimeout(F),F=setTimeout(()=>{A()},180)}function q(t,n){if(n&&n.key==="Enter"){const i=D(t);return m(i,"file")?i.click():void 0}const e=t,r=H(t);!m(r,"text")||(r.value=e.files?Array.from(e.files).map(i=>i.name).join(", "):"",r.readOnly=!0,g(r,"keydown",ut,!1),x(r))}function I(t,n){if(n&&n.key==="Enter"){const i=D(t);return m(i,"color")?i.click():void 0}const e=t,r=H(t);!m(r,"text")||(r.readOnly=!0,r.value=e.value,g(r,"keydown",st,!1),x(r))}function W(t){const n=T(t),e=h("span",n),r=l("input",n);if(!r.length||!e)return;const i=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--size"))||16,c=.25*i*100/r[0].offsetWidth,o=[],a=[];for(let y=0;y1&&(d=Math.abs(o[1]-o[0]),v=o[1]>o[0]?o[0]:o[1],b=100-v-d,M>S&&(S=a[1]||0,M=a[0])),n.style.setProperty("---start",`${v}%`),n.style.setProperty("---end",`${b}%`),n.style.setProperty("---value1",`'${S}'`),n.style.setProperty("---value2",`'${M}'`)}function _(t){if(t){const e=t.target;if(e.type==="range")return W(e)}const n=l(".slider > input[type=range]");n.length?g(globalThis,"input",_,!1):G(globalThis,"input",_,!1),n.forEach(W)}async function V(t,n,e,r){if(!(!n&&(n=h(t.getAttribute("data-ui")),!n))){if(L(n,"dialog"))return await ft(t,n);if(L(n,"menu"))return z(t,n,r);if(f(n,"snackbar"))return dt(t,n,e);if(f(n,"page"))return lt(t,n);if(C(t),f(n,"active"))return u(n,"active");p(n,"active")}}function C(t){t.id&&f(t,"page")&&(t=h(`[data-ui="#${t.id}"]`));const n=T(t);if(!f(n,"tabs"))return;l("a",n).forEach(r=>u(r,"active")),p(t,"active")}function lt(t,n){C(t);const e=T(n);if(e)for(let r=0;r{var i,c;if(g(document.body,"click",Q),C(t),f(n,"active")){if(!e)return u(n,"active");const o=e.target,a=h((i=o.getAttribute("data-ui"))!=null?i:""),d=o.closest("menu"),v=!h("menu",(c=o.closest("[data-ui]"))!=null?c:void 0);return a&&a!==d?z(o,a):!a&&!v&&d?!1:u(n,"active")}l("menu.active").forEach(o=>u(o,"active")),p(n,"active")},90)}async function ft(t,n){var d;(d=document.activeElement)==null||d.blur(),C(t);let e=D(n);const r=n,i=f(n,"active")||r.open,c=f(n,"modal"),o=T(n),a=L(o,"nav");f(e,"overlay")||(e=tt({class:"overlay"}),J(e,n),await X(90)),e.onclick=()=>{c||(u(t,"active"),u(n,"active"),u(e,"active"),r.close())},a&&l("dialog, a, .overlay",o).forEach(b=>{u(b,"active"),b.open&&b.close()}),i?(u(t,"active"),u(e,"active"),u(n,"active"),r.close()):(!L(t,"button")&&!f(t,"button")&&!f(t,"chip")&&p(t,"active"),p(e,"active"),p(n,"active"),c?r.showModal():r.show())}function dt(t,n,e){var i;(i=document.activeElement)==null||i.blur(),C(t),l(".snackbar.active").forEach(c=>u(c,"active")),p(n,"active"),g(n,"click",it),k&&clearTimeout(k),e!==-1&&(k=setTimeout(()=>{u(n,"active")},e!=null?e:6e3))}function gt(){if(s.light&&s.dark)return s;const t=document.createElement("body");t.className="light",document.body.appendChild(t);const n=document.createElement("body");n.className="dark",document.body.appendChild(n);const e=getComputedStyle(t),r=getComputedStyle(n),i=["--primary","--on-primary","--primary-container","--on-primary-container","--secondary","--on-secondary","--secondary-container","--on-secondary-container","--tertiary","--on-tertiary","--tertiary-container","--on-tertiary-container","--error","--on-error","--error-container","--on-error-container","--background","--on-background","--surface","--on-surface","--surface-variant","--on-surface-variant","--outline","--outline-variant","--shadow","--scrim","--inverse-surface","--inverse-on-surface","--inverse-primary","--surface-dim","--surface-bright","--surface-container-lowest","--surface-container-low","--surface-container","--surface-container-high","--surface-container-highest"];for(let c=0;c{const r=i=>{let c="";for(const o in i){const a=o.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),d=i[o];c+="--"+a+":"+d+";"}return c};return s.light=r(e.light),s.dark=r(e.dark),document.body.setAttribute("style",s[n]),s})}function pt(t){if(!t)return/dark/i.test(document.body.className)?"dark":"light";document.body.classList.remove("light","dark"),document.body.classList.add(t);const n=t==="light"?s.light:s.dark;return globalThis.materialDynamicColors&&document.body.setAttribute("style",n),t}function vt(){P||(P=new MutationObserver(j),P.observe(document.body,{childList:!0,subtree:!0}),j())}function A(t,n){if(t){if(t==="setup")return vt();if(t==="guid")return Y();if(t==="mode")return pt(n);if(t==="theme")return yt(n);const a=h(t);if(!a)return;V(a,a,n)}l("[data-ui]").forEach(a=>g(a,"click",nt)),l(".field > label").forEach(a=>g(a,"click",et)),l(".field > input:not([type=file], [type=color], [type=range]), .field > select, .field > textarea").forEach(a=>{g(a,"focus",rt),g(a,"blur",at),x(a)}),l(".field > input[type=file]").forEach(a=>{g(a,"change",ot),q(a)}),l(".field > input[type=color]").forEach(a=>{g(a,"change",ct),I(a)}),_()}globalThis.addEventListener&&globalThis.addEventListener("load",async()=>await A("setup"));globalThis.beercss=A;globalThis.ui=A; +return globalThis.ui; +})(); \ No newline at end of file diff --git a/TYTDLite/Assets/favicon.ico b/TYTDLite/Assets/favicon.ico new file mode 100644 index 0000000..7f1f5b6 Binary files /dev/null and b/TYTDLite/Assets/favicon.ico differ diff --git a/TYTDLite/Assets/index.html b/TYTDLite/Assets/index.html new file mode 100644 index 0000000..4c0406e --- /dev/null +++ b/TYTDLite/Assets/index.html @@ -0,0 +1,18 @@ +
+
Download a YouTube Video
+
+
+ + +
+ +
+
+ +
+
Thanks for using TYTD Lite
+

As you are helping preserve YouTube, when you download a video using this site we archive it.
This also means that if it was downloaded before and the video was removed from YouTube you can get it here.

+
\ No newline at end of file diff --git a/TYTDLite/Assets/info.html b/TYTDLite/Assets/info.html new file mode 100644 index 0000000..e69de29 diff --git a/TYTDLite/Assets/material-symbols-outlined.woff2 b/TYTDLite/Assets/material-symbols-outlined.woff2 new file mode 100644 index 0000000..2764906 Binary files /dev/null and b/TYTDLite/Assets/material-symbols-outlined.woff2 differ diff --git a/TYTDLite/Assets/material-symbols-rounded.woff2 b/TYTDLite/Assets/material-symbols-rounded.woff2 new file mode 100644 index 0000000..f4505dc Binary files /dev/null and b/TYTDLite/Assets/material-symbols-rounded.woff2 differ diff --git a/TYTDLite/Assets/material-symbols-sharp.woff2 b/TYTDLite/Assets/material-symbols-sharp.woff2 new file mode 100644 index 0000000..cc5482e Binary files /dev/null and b/TYTDLite/Assets/material-symbols-sharp.woff2 differ diff --git a/TYTDLite/Assets/site.webmanifest b/TYTDLite/Assets/site.webmanifest new file mode 100644 index 0000000..5b776bc --- /dev/null +++ b/TYTDLite/Assets/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "Tesses YouTube Downloader Lite", + "short_name": "TYTD Lite", + "start_url": "./", + "scope": ".", + "icons": [ + { + "src": "./android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "./android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ff0000", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/TYTDLite/Assets/template.html b/TYTDLite/Assets/template.html new file mode 100644 index 0000000..72db890 --- /dev/null +++ b/TYTDLite/Assets/template.html @@ -0,0 +1,29 @@ + + + + + + TYTD Lite + + + + + +
+ +
+
+{{body}} +
+ + + + + \ No newline at end of file diff --git a/TYTDLite/Assets/theme.css b/TYTDLite/Assets/theme.css new file mode 100644 index 0000000..1efd28c --- /dev/null +++ b/TYTDLite/Assets/theme.css @@ -0,0 +1,96 @@ +:root,html, +body { + --primary:#ffb4a8; +--on-primary:#690000; +--primary-container:#930100; +--on-primary-container:#ffdad4; +--secondary:#e7bdb6; +--on-secondary:#442925; +--secondary-container:#5d3f3b; +--on-secondary-container:#ffdad4; +--tertiary:#dec48c; +--on-tertiary:#3e2e04; +--tertiary-container:#564419; +--on-tertiary-container:#fbdfa6; +--error:#ffb4ab; +--on-error:#690005; +--error-container:#93000a; +--on-error-container:#ffb4ab; +--background:#201a19; +--on-background:#ede0dd; +--surface:#181211; +--on-surface:#ede0dd; +--surface-variant:#534341; +--on-surface-variant:#d8c2be; +--outline:#a08c89; +--outline-variant:#534341; +--shadow:#000000; +--scrim:#000000; +--inverse-surface:#ede0dd; +--inverse-on-surface:#362f2e; +--inverse-primary:#c00100; +--surface-dim:#181211; +--surface-bright:#3f3736; +--surface-container-lowest:#120d0c; +--surface-container-low:#201a19; +--surface-container:#251e1d; +--surface-container-high:#2f2827; +--surface-container-highest:#3b3332; +} + +@media (prefers-color-scheme: light) { + :root,html, + body { + --primary:#c00100; +--on-primary:#ffffff; +--primary-container:#ffdad4; +--on-primary-container:#410000; +--secondary:#775651; +--on-secondary:#ffffff; +--secondary-container:#ffdad4; +--on-secondary-container:#2c1512; +--tertiary:#705c2e; +--on-tertiary:#ffffff; +--tertiary-container:#fbdfa6; +--on-tertiary-container:#251a00; +--error:#ba1a1a; +--on-error:#ffffff; +--error-container:#ffdad6; +--on-error-container:#410002; +--background:#fffbff; +--on-background:#201a19; +--surface:#fff8f6; +--on-surface:#201a19; +--surface-variant:#f5ddda; +--on-surface-variant:#534341; +--outline:#857370; +--outline-variant:#d8c2be; +--shadow:#000000; +--scrim:#000000; +--inverse-surface:#362f2e; +--inverse-on-surface:#fbeeec; +--inverse-primary:#ffb4a8; +--surface-dim:#e4d7d5; +--surface-bright:#fff8f6; +--surface-container-lowest:#ffffff; +--surface-container-low:#fef1ee; +--surface-container:#f8ebe9; +--surface-container-high:#f3e5e3; +--surface-container-highest:#ede0dd; + } +} + +.horizonal +{ + display: flex; + flex-direction: column; +} +.vertical +{ + display: flex; + flex-direction: row; +} +.filler +{ + flex-grow: 1; +} \ No newline at end of file diff --git a/TYTDLite/Assets/video_download.html b/TYTDLite/Assets/video_download.html new file mode 100644 index 0000000..ff94e55 --- /dev/null +++ b/TYTDLite/Assets/video_download.html @@ -0,0 +1,90 @@ +{{if notavailable}} +
+

This video is unavailable on YouTube

+
+{{end}} +{{if invalidurl}} +
+

You provided an invalid url, if it was a playlist we don't support playlists.

+
+{{else}} +
+
+
+ +
+
{{title}}
+

{{channel}}

+
+
+
+
+
{{otherstats}}
+
+ +
+ +
+
+
{{desc}}
+ +
+
+
+
+
+
+ +
+
{{title}} by {{channel}}
+
+ +
+ +
+
+
{{otherstats}}
+

{{desc}}

+ +
+ +
+
+
+ +
+ + arrow_drop_down +
+ +
+{{end}} \ No newline at end of file diff --git a/TYTDLite/Assets/video_init_download.html b/TYTDLite/Assets/video_init_download.html new file mode 100644 index 0000000..daad20e --- /dev/null +++ b/TYTDLite/Assets/video_init_download.html @@ -0,0 +1,66 @@ + + +
+ + diff --git a/TYTDLite/Class1.cs b/TYTDLite/Class1.cs new file mode 100644 index 0000000..fe65202 --- /dev/null +++ b/TYTDLite/Class1.cs @@ -0,0 +1,1026 @@ +/* + TYTD Lite: A YouTube Downloader website that archives videos when people download videos using it. + Copyright (C) 2024 Mike Nolan + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using Humanizer; +using LiteDB; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Scriban; +using Tesses.WebServer; +using YoutubeExplode; +using YoutubeExplode.Exceptions; +using YoutubeExplode.Videos; +using YoutubeExplode.Videos.Streams; + +namespace TYTDLite +{ + public class TYTDLiteServer + { + public ILiteDatabase Database {get;} + public ILiteCollection Videos => Database.GetCollection("Videos"); + + List Jobs {get;set;}=new List(); + public string ServerPath {get;} + + public RouteServer Server {get;} + + public YoutubeClient YoutubeClient {get;} + public HttpClient HttpClient {get;} + + Lazy