🎉 Sync 2026-10-01 14:45:51
No files matched your search
@@ -1 +1 @@
|
||||
snapshot
|
||||
both
|
||||
@@ -0,0 +1 @@
|
||||
26.273.20498~1fcad1e
|
||||
@@ -0,0 +1,24 @@
|
||||
# Internal use
|
||||
docs/
|
||||
/resources/
|
||||
|
||||
# Hidden dotfiles/folders
|
||||
.*
|
||||
!.gitignore
|
||||
!.gitkeep
|
||||
|
||||
# Editor files
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Signing keys (secret key is in GitHub Secrets, NEVER commit)
|
||||
/keys/
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
|
||||
# Node modules (for LESS compilation)
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
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
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Copyright (C) 2024-2026 luci-theme-glass contributors
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.0.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Glass - Apple-inspired glassmorphism theme for LuCI
|
||||
LUCI_DEPENDS:=
|
||||
PKG_VERSION:=$(shell cat $(CURDIR)/ucode/template/themes/glass/version | tr -d '[:space:]')
|
||||
PKG_RELEASE:=1
|
||||
|
||||
# Disable CSS minification (backdrop-filter can break with csstidy)
|
||||
CONFIG_LUCI_CSSTIDY:=
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,236 @@
|
||||
# luci-theme-glass
|
||||
|
||||
A glassmorphism theme for OpenWrt LuCI, inspired by Apple's visionOS and macOS. Frosted-glass panels, backdrop blur, translucent buttons, and inset highlights across the entire UI.
|
||||
|
||||
**[Live Demo](https://rchen14b.github.io/luci-theme-glass/)** | **[Download](https://github.com/rchen14b/luci-theme-glass/releases/latest)**
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://buymeacoffee.com/rchen14b)
|
||||
|
||||
## Screenshots
|
||||
|
||||
### Login
|
||||

|
||||
|
||||
### Overview (Light)
|
||||

|
||||
|
||||
### Overview (Dark)
|
||||

|
||||
|
||||
### Software
|
||||

|
||||
|
||||
### Traffic Graph
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
### Design
|
||||
- **Glassmorphism everywhere** — `backdrop-filter: blur() saturate()` with multi-stop gradients, translucent backgrounds, 0.5px glass borders, and inset glow highlights on all panels
|
||||
- **Glass buttons** — Neutral buttons are translucent glass, primary buttons are blue-tinted, danger buttons are red-tinted. No solid-color buttons
|
||||
- **Frosted sidebar** — Fixed sidebar with 30px blur and inset light diffusion
|
||||
- **Glass header** — Top nav bar with glass pill badges for page title and status indicators
|
||||
- **Live status indicators** — CPU load, RAM %, uptime, and WAN throughput in the header bar. Auto-detects WAN interface, resolves bridges, handles DSA hardware offloading. MikroTik-style speed formatting. Color-coded levels and detailed tooltips
|
||||
- **Glass login card** — Frosted login page with translucent inputs
|
||||
|
||||
### Theming
|
||||
- **Auto / Light / Dark mode** — Toggle in the header bar cycles through Auto (follows OS `prefers-color-scheme`), Light, and Dark. Works on every page including login. Saved to `localStorage` so it persists across sessions
|
||||
- **Dark mode glass** — Lower-opacity gradients (`rgba(255,255,255,0.05-0.08)`) with adjusted shadows
|
||||
- **Server-side default** — Set default mode via UCI config (`option mode 'dark'`, `'light'`, or `'normal'` for auto). The client-side toggle overrides this per browser
|
||||
- **Accent color config** — Primary color, blur radius, and glass transparency are adjustable via UCI
|
||||
- **Custom wallpapers** — Drop an image or video into the background folder. It shows through all glass panels
|
||||
|
||||
### Layout
|
||||
- **Responsive** — Sidebar collapses to a slide-out drawer on mobile with hamburger toggle
|
||||
- **Sub-navigation bar** — CBI tab menus get moved into a secondary glass bar below the header
|
||||
- **Sticky header** — Fixed header with smooth transitions
|
||||
|
||||
### Compatibility
|
||||
- **Full LuCI coverage** — Styles all CBI components: sections, tables, forms, dropdowns, checkboxes, textareas, progress bars, tooltips, modals, tab menus
|
||||
- **Page-specific fixes** — Overrides inline CSS from LuCI view JS (package manager layout, port status grid, network status cards)
|
||||
- **OpenWrt 23.05+** — Uses ucode `.ut` templates
|
||||
- **No dependencies** — Pure CSS, no JS frameworks
|
||||
|
||||
## Installation
|
||||
|
||||
### From package repository (auto-update, signed)
|
||||
|
||||
Add the repository to get updates via the package manager. Both opkg and apk feeds are signed.
|
||||
|
||||
**OpenWrt 24.10 and earlier (opkg):**
|
||||
```sh
|
||||
# First install: fetch signing public key (one-time)
|
||||
wget -O /etc/opkg/keys/ef97c468af77cea1 \
|
||||
https://raw.githubusercontent.com/rchen14b/luci-theme-glass/main/root/etc/opkg/keys/ef97c468af77cea1
|
||||
|
||||
# Add feed and install
|
||||
echo "src/gz glass https://rchen14b.github.io/luci-theme-glass/packages" >> /etc/opkg/customfeeds.conf
|
||||
opkg update
|
||||
opkg install luci-theme-glass
|
||||
```
|
||||
|
||||
**OpenWrt 25.12+ (apk):**
|
||||
```sh
|
||||
# First install: fetch signing public key (one-time)
|
||||
wget -O /etc/apk/keys/glass-apk.rsa.pub \
|
||||
https://raw.githubusercontent.com/rchen14b/luci-theme-glass/main/root/etc/apk/keys/glass-apk.rsa.pub
|
||||
|
||||
# Add feed and install
|
||||
echo "https://rchen14b.github.io/luci-theme-glass/apk/packages.adb" >> /etc/apk/repositories.d/customfeeds.list
|
||||
apk update
|
||||
apk add luci-theme-glass
|
||||
```
|
||||
|
||||
After the first install, the public key persists on the router — future updates via `opkg upgrade` / `apk upgrade` just work. The LuCI web-gui "Update lists" button also works without warnings.
|
||||
|
||||
### From release (manual)
|
||||
|
||||
Download the latest package from [Releases](../../releases):
|
||||
|
||||
- **OpenWrt 25.12+** (apk): `apk add --allow-untrusted luci-theme-glass-*.apk`
|
||||
- **OpenWrt 24.10 and earlier** (opkg): `opkg install luci-theme-glass_*.ipk`
|
||||
|
||||
### From source
|
||||
|
||||
```sh
|
||||
# Add to your OpenWrt build tree
|
||||
cd /path/to/openwrt
|
||||
git clone https://github.com/rchen14b/luci-theme-glass.git package/luci-theme-glass
|
||||
|
||||
# Build
|
||||
make package/luci-theme-glass/compile V=s
|
||||
```
|
||||
|
||||
### Manual install (dev)
|
||||
|
||||
```sh
|
||||
# Copy theme files to router
|
||||
scp -r htdocs/luci-static/glass/ root@router:/www/luci-static/glass/
|
||||
scp htdocs/luci-static/resources/menu-glass.js root@router:/www/luci-static/resources/
|
||||
scp -r ucode/template/themes/glass/ root@router:/usr/share/ucode/luci/template/themes/glass/
|
||||
|
||||
# Register and activate
|
||||
ssh root@router "uci set luci.themes.Glass=/luci-static/glass && \
|
||||
uci set luci.main.mediaurlbase=/luci-static/glass && \
|
||||
uci commit luci"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
After installation, select **Glass** in **System > System > Language and Style**.
|
||||
|
||||
### Theme config
|
||||
|
||||
Create `/etc/config/glass` on the router:
|
||||
|
||||
```
|
||||
config global
|
||||
option mode 'normal'
|
||||
option primary '#007AFF'
|
||||
option dark_primary '#0A84FF'
|
||||
option blur '20'
|
||||
option transparency '0.72'
|
||||
option blur_dark '25'
|
||||
option transparency_dark '0.30'
|
||||
```
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `mode` | `normal` | `normal` (auto), `dark`, or `light` |
|
||||
| `primary` | `#007AFF` | Accent color (light mode) |
|
||||
| `dark_primary` | `#0A84FF` | Accent color (dark mode) |
|
||||
| `blur` | `20` | Backdrop blur in px (light mode) |
|
||||
| `transparency` | `0.72` | Glass panel opacity 0-1 (light mode) |
|
||||
| `blur_dark` | `25` | Backdrop blur in px (dark mode) |
|
||||
| `transparency_dark` | `0.30` | Glass panel opacity 0-1 (dark mode) |
|
||||
|
||||
### Custom wallpapers
|
||||
|
||||
Place a file named `bg.*` in `/www/luci-static/glass/background/` on the router.
|
||||
|
||||
Supported: `.jpg`, `.jpeg`, `.png`, `.gif`, `.webp`, `.mp4`, `.webm`
|
||||
|
||||
The background shows through all glass panels.
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js with `lessc`: `npm install -g less`
|
||||
|
||||
### Building CSS
|
||||
|
||||
```sh
|
||||
lessc less/cascade.less htdocs/luci-static/glass/css/cascade.css
|
||||
lessc less/dark.less htdocs/luci-static/glass/css/dark.css
|
||||
```
|
||||
|
||||
### Project structure
|
||||
|
||||
```
|
||||
luci-theme-glass/
|
||||
├── Makefile # OpenWrt package build
|
||||
├── htdocs/luci-static/
|
||||
│ ├── glass/
|
||||
│ │ ├── css/ # Compiled CSS
|
||||
│ │ ├── img/ # Logo and icons
|
||||
│ │ └── background/ # User wallpapers (bg.jpg, etc.)
|
||||
│ └── resources/
|
||||
│ ├── menu-glass.js # Client-side menu renderer
|
||||
│ └── status-glass.js # Header status indicators (CPU, RAM, net, uptime)
|
||||
├── less/ # LESS source
|
||||
│ ├── cascade.less # Master import file
|
||||
│ ├── variables.less # Design tokens (CSS custom properties)
|
||||
│ ├── normalize.less # CSS reset
|
||||
│ ├── glass.less # Glassmorphism mixins
|
||||
│ ├── layout.less # Sidebar, header, footer, content
|
||||
│ ├── components.less # CBI forms, tables, buttons, alerts
|
||||
│ ├── sysauth.less # Login page
|
||||
│ ├── page-fix.less # LuCI page-specific overrides
|
||||
│ ├── dark.less # Dark mode overrides
|
||||
│ └── responsive.less # Mobile breakpoints
|
||||
├── ucode/template/themes/glass/ # Server-side ucode templates
|
||||
│ ├── header.ut # HTML head + sidebar + header
|
||||
│ ├── header_login.ut # Login page variant
|
||||
│ ├── footer.ut # Footer + scripts
|
||||
│ ├── footer_login.ut # Login footer variant
|
||||
│ └── sysauth.ut # Login page
|
||||
├── root/ # Files installed to device root
|
||||
│ ├── etc/uci-defaults/ # First-boot theme registration
|
||||
│ └── usr/share/rpcd/acl.d/ # ACL permissions
|
||||
└── screenshots/
|
||||
```
|
||||
|
||||
### Design system
|
||||
|
||||
Design tokens live in `variables.less`. Glass effects use three LESS mixins:
|
||||
|
||||
| Mixin | Use | Blur | Opacity |
|
||||
|-------|-----|------|---------|
|
||||
| `.glass-effect()` | Panels, cards | `var(--glass-blur)` | `var(--glass-bg)` |
|
||||
| `.glass-frosted()` | Sidebar, login card | 30px | Higher |
|
||||
| `.glass-subtle()` | Secondary elements | Lower | Minimal |
|
||||
|
||||
### Version bump checklist
|
||||
|
||||
1. `Makefile` — `PKG_VERSION`
|
||||
2. `README.md` — version badge
|
||||
3. `ucode/template/themes/glass/sysauth.ut` — login version text
|
||||
4. `ucode/template/themes/glass/header.ut` — sidebar version text
|
||||
5. `ucode/template/themes/glass/footer.ut` — footer version text
|
||||
|
||||
## Credits
|
||||
|
||||
- Architecture based on [luci-theme-argon](https://github.com/jerrykuku/luci-theme-argon)
|
||||
- Glass effects from [glass-ui](https://github.com/crenspire/glass-ui)
|
||||
- Design language from Apple visionOS / macOS
|
||||
|
||||
## License
|
||||
|
||||
Dual-licensed:
|
||||
|
||||
- **Open Source**: [GPL-3.0](LICENSE) — free for personal, educational, and open-source use. Derivatives must also be GPL-3.0.
|
||||
- **Commercial**: Proprietary/closed-source use requires a separate license. Contact the author.
|
||||
@@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
PKG_NAME="luci-theme-glass"
|
||||
PKG_VERSION="$(tr -d '[:space:]' < "$(dirname "$0")/ucode/template/themes/glass/version")"
|
||||
PKG_RELEASE="1"
|
||||
MAINTAINER="Ryan Chen <rchen14b@gmail.com>"
|
||||
DESCRIPTION="Glass - Apple-inspired glassmorphism theme for LuCI"
|
||||
HOMEPAGE="https://github.com/rchen14b/luci-theme-glass"
|
||||
LICENSE="GPL-3.0"
|
||||
|
||||
DIST_DIR="dist"
|
||||
WORK_DIR=$(mktemp -d)
|
||||
|
||||
# Use GNU tar (gtar) on macOS, fall back to tar
|
||||
TAR=$(command -v gtar 2>/dev/null || echo tar)
|
||||
|
||||
trap "rm -rf $WORK_DIR" EXIT
|
||||
|
||||
echo "==> Preparing file tree..."
|
||||
|
||||
DATA_DIR="$WORK_DIR/data"
|
||||
mkdir -p "$DATA_DIR/www/luci-static/glass"
|
||||
mkdir -p "$DATA_DIR/www/luci-static/resources"
|
||||
mkdir -p "$DATA_DIR/www/luci-static/resources/view/system"
|
||||
mkdir -p "$DATA_DIR/usr/share/ucode/luci/template/themes/glass"
|
||||
mkdir -p "$DATA_DIR/usr/share/rpcd/acl.d"
|
||||
mkdir -p "$DATA_DIR/usr/share/luci/menu.d"
|
||||
mkdir -p "$DATA_DIR/etc/uci-defaults"
|
||||
mkdir -p "$DATA_DIR/etc/config"
|
||||
mkdir -p "$DATA_DIR/etc/opkg/keys"
|
||||
mkdir -p "$DATA_DIR/etc/apk/keys"
|
||||
|
||||
cp -r htdocs/luci-static/glass/css "$DATA_DIR/www/luci-static/glass/"
|
||||
cp -r htdocs/luci-static/glass/img "$DATA_DIR/www/luci-static/glass/"
|
||||
mkdir -p "$DATA_DIR/www/luci-static/glass/background"
|
||||
cp htdocs/luci-static/resources/menu-glass.js "$DATA_DIR/www/luci-static/resources/"
|
||||
cp htdocs/luci-static/resources/status-glass.js "$DATA_DIR/www/luci-static/resources/"
|
||||
cp htdocs/luci-static/resources/view/system/glass.js "$DATA_DIR/www/luci-static/resources/view/system/"
|
||||
cp ucode/template/themes/glass/*.ut "$DATA_DIR/usr/share/ucode/luci/template/themes/glass/"
|
||||
cp ucode/template/themes/glass/version "$DATA_DIR/usr/share/ucode/luci/template/themes/glass/"
|
||||
cp root/usr/share/rpcd/acl.d/luci-theme-glass.json "$DATA_DIR/usr/share/rpcd/acl.d/"
|
||||
cp root/usr/share/luci/menu.d/luci-theme-glass.json "$DATA_DIR/usr/share/luci/menu.d/"
|
||||
cp root/etc/uci-defaults/30_luci-theme-glass "$DATA_DIR/etc/uci-defaults/"
|
||||
cp root/etc/config/glass "$DATA_DIR/etc/config/"
|
||||
cp root/etc/opkg/keys/* "$DATA_DIR/etc/opkg/keys/" 2>/dev/null || true
|
||||
cp root/etc/apk/keys/* "$DATA_DIR/etc/apk/keys/" 2>/dev/null || true
|
||||
|
||||
INSTALLED_SIZE=$(du -sk "$DATA_DIR" | cut -f1)
|
||||
INSTALLED_BYTES=$((INSTALLED_SIZE * 1024))
|
||||
BUILD_DATE=$(date +%s)
|
||||
|
||||
mkdir -p "$DIST_DIR"
|
||||
|
||||
# ============================================================
|
||||
# Build IPK (opkg — OpenWrt 24.10 and earlier)
|
||||
# ============================================================
|
||||
echo "==> Building IPK..."
|
||||
|
||||
IPK_DIR="$WORK_DIR/ipk"
|
||||
mkdir -p "$IPK_DIR/control"
|
||||
|
||||
cat > "$IPK_DIR/control/control" <<EOF
|
||||
Package: $PKG_NAME
|
||||
Version: ${PKG_VERSION}-${PKG_RELEASE}
|
||||
Architecture: all
|
||||
Maintainer: $MAINTAINER
|
||||
Section: luci
|
||||
Priority: optional
|
||||
Installed-Size: $INSTALLED_SIZE
|
||||
Description: $DESCRIPTION
|
||||
Homepage: $HOMEPAGE
|
||||
License: $LICENSE
|
||||
EOF
|
||||
|
||||
cat > "$IPK_DIR/control/postinst" <<'SCRIPT'
|
||||
#!/bin/sh
|
||||
if [ "$PKG_UPGRADE" != 1 ]; then
|
||||
uci get luci.themes.Glass >/dev/null 2>&1 || \
|
||||
uci batch <<-EOF
|
||||
set luci.themes.Glass=/luci-static/glass
|
||||
set luci.main.mediaurlbase=/luci-static/glass
|
||||
commit luci
|
||||
EOF
|
||||
fi
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod 755 "$IPK_DIR/control/postinst"
|
||||
|
||||
echo "2.0" > "$IPK_DIR/debian-binary"
|
||||
|
||||
(cd "$DATA_DIR" && $TAR --format=gnu --numeric-owner --owner=0 --group=0 -cf - . | gzip -n > "$IPK_DIR/data.tar.gz")
|
||||
(cd "$IPK_DIR/control" && $TAR --format=gnu --numeric-owner --owner=0 --group=0 -cf - . | gzip -n > "$IPK_DIR/control.tar.gz")
|
||||
(cd "$IPK_DIR" && $TAR --format=gnu --numeric-owner --owner=0 --group=0 -cf - ./debian-binary ./data.tar.gz ./control.tar.gz | gzip -n > "$OLDPWD/$DIST_DIR/${PKG_NAME}_${PKG_VERSION}-${PKG_RELEASE}_all.ipk")
|
||||
|
||||
echo " -> $DIST_DIR/${PKG_NAME}_${PKG_VERSION}-${PKG_RELEASE}_all.ipk"
|
||||
|
||||
# ============================================================
|
||||
# Build APK (apk-tools v3 ADB format — OpenWrt 25.12+)
|
||||
# Requires Docker (uses Alpine container with apk mkpkg)
|
||||
# ============================================================
|
||||
echo "==> Building APK..."
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
APK_FILENAME="${PKG_NAME}-${PKG_VERSION}-r${PKG_RELEASE}.apk"
|
||||
|
||||
if ! command -v docker &>/dev/null; then
|
||||
echo " [SKIP] Docker not found — APK build requires Docker with Alpine"
|
||||
echo " IPK package was built successfully."
|
||||
else
|
||||
# Prepare post-install script for APK
|
||||
APK_SCRIPT="$WORK_DIR/post-install.sh"
|
||||
cat > "$APK_SCRIPT" <<'SCRIPT'
|
||||
#!/bin/sh
|
||||
uci get luci.themes.Glass >/dev/null 2>&1 || \
|
||||
uci batch <<-EOF
|
||||
set luci.themes.Glass=/luci-static/glass
|
||||
set luci.main.mediaurlbase=/luci-static/glass
|
||||
commit luci
|
||||
EOF
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod 755 "$APK_SCRIPT"
|
||||
|
||||
# Build using Alpine container with apk mkpkg
|
||||
docker run --rm \
|
||||
-v "$DATA_DIR:/pkg/files:ro" \
|
||||
-v "$APK_SCRIPT:/pkg/post-install.sh:ro" \
|
||||
-v "$SCRIPT_DIR/$DIST_DIR:/pkg/out" \
|
||||
alpine:latest sh -c "
|
||||
apk add --no-cache apk-tools-mkpkg >/dev/null 2>&1 || true
|
||||
apk mkpkg \
|
||||
--info 'name:$PKG_NAME' \
|
||||
--info 'version:${PKG_VERSION}-r${PKG_RELEASE}' \
|
||||
--info 'description:$DESCRIPTION' \
|
||||
--info 'arch:noarch' \
|
||||
--info 'license:$LICENSE' \
|
||||
--info 'origin:$PKG_NAME' \
|
||||
--info 'url:$HOMEPAGE' \
|
||||
--info 'maintainer:$MAINTAINER' \
|
||||
--script 'post-install:/pkg/post-install.sh' \
|
||||
--files /pkg/files \
|
||||
--output /pkg/out/$APK_FILENAME
|
||||
" 2>&1
|
||||
|
||||
echo " -> $DIST_DIR/$APK_FILENAME"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "==> Done! Packages in $DIST_DIR/"
|
||||
ls -lh "$DIST_DIR/"
|
||||
@@ -0,0 +1,339 @@
|
||||
/* ==========================================================================
|
||||
Dark Mode — luci-theme-glass
|
||||
Compiled separately and injected by header.ut when dark mode is active.
|
||||
========================================================================== */
|
||||
:root {
|
||||
/* ---- Colors — Dark mode ---- */
|
||||
--color-primary: #0A84FF;
|
||||
--color-primary-hover: #409cff;
|
||||
--color-primary-active: #0066d6;
|
||||
--color-primary-rgb: 10, 132, 255;
|
||||
--color-success: #30D158;
|
||||
--color-warning: #FFD60A;
|
||||
--color-danger: #FF453A;
|
||||
--color-info: #64D2FF;
|
||||
--color-text: #f5f5f7;
|
||||
--color-text-secondary: #98989d;
|
||||
--color-text-tertiary: #636366;
|
||||
--color-text-inverse: #1d1d1f;
|
||||
--color-bg: #1c1c1e;
|
||||
--color-bg-elevated: #2c2c2e;
|
||||
--color-bg-secondary: #3a3a3c;
|
||||
--color-border: rgba(255, 255, 255, 0.08);
|
||||
--color-border-strong: rgba(255, 255, 255, 0.16);
|
||||
--color-separator: rgba(84, 84, 88, 0.36);
|
||||
/* ---- Dark glassmorphism ---- */
|
||||
--glass-blur: 25px;
|
||||
--glass-saturate: 180%;
|
||||
--glass-bg: rgba(38, 38, 42, 0.55);
|
||||
--glass-bg-hover: rgba(52, 52, 56, 0.65);
|
||||
--glass-bg-strong: rgba(38, 38, 42, 0.72);
|
||||
--glass-border: rgba(255, 255, 255, 0.12);
|
||||
--glass-shadow: 0 2px 16px rgba(0, 0, 0, 0.2), 0 0 1px rgba(0, 0, 0, 0.25);
|
||||
--glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.3), 0 0 1px rgba(0, 0, 0, 0.15);
|
||||
/* ---- Dark background ---- */
|
||||
--bg-gradient: linear-gradient(135deg, #2c2e3a 0%, #353848 50%, #2a2d38 100%);
|
||||
}
|
||||
/* ---- Dark-mode-specific overrides ---- */
|
||||
/* Inputs need darker backgrounds */
|
||||
.cbi-input-text,
|
||||
.cbi-input-password,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
textarea,
|
||||
select {
|
||||
background: rgba(44, 44, 46, 0.55);
|
||||
}
|
||||
/* Login card */
|
||||
.login-card {
|
||||
background-image: linear-gradient(160deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
background-color: rgba(38, 38, 42, 0.55);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 16px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.login-form .login-field input {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 0 4px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.login-btn {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.06) 25%, rgba(240, 248, 255, 0.07) 50%, rgba(255, 255, 255, 0.05) 75%, rgba(230, 240, 255, 0.06) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.15), inset 0 0 0.5px rgba(255, 255, 255, 0.12), inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
color: var(--color-text);
|
||||
}
|
||||
/* Buttons — glass-ui dark pattern */
|
||||
.btn,
|
||||
.cbi-button {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.06) 25%, rgba(240, 248, 255, 0.07) 50%, rgba(255, 255, 255, 0.05) 75%, rgba(230, 240, 255, 0.06) 100%);
|
||||
background-color: transparent;
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.15), inset 0 0 0.5px rgba(255, 255, 255, 0.12), inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
.btn:hover,
|
||||
.cbi-button:hover {
|
||||
opacity: 0.9;
|
||||
background-color: transparent;
|
||||
}
|
||||
.btn:active,
|
||||
.cbi-button:active {
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.cbi-button-negative,
|
||||
.cbi-button-remove,
|
||||
.cbi-button-reset {
|
||||
background-image: linear-gradient(135deg, rgba(255, 69, 58, 0.12) 0%, rgba(255, 69, 58, 0.08) 50%, rgba(255, 69, 58, 0.1) 100%);
|
||||
background-color: transparent;
|
||||
color: var(--color-danger);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.15), inset 0 0 0.5px rgba(255, 255, 255, 0.08), inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.cbi-button-negative:hover,
|
||||
.cbi-button-remove:hover,
|
||||
.cbi-button-reset:hover {
|
||||
opacity: 0.9;
|
||||
background-color: transparent;
|
||||
}
|
||||
.cbi-button-negative:active,
|
||||
.cbi-button-remove:active,
|
||||
.cbi-button-reset:active {
|
||||
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
/* Sidebar */
|
||||
#sidebar {
|
||||
background-image: linear-gradient(160deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 20%, rgba(240, 248, 255, 0.08) 45%, rgba(255, 255, 255, 0.06) 70%, rgba(230, 240, 255, 0.07) 100%);
|
||||
background-color: rgba(38, 38, 42, 0.55);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 12px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Header bar */
|
||||
#header {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Page actions bar */
|
||||
.cbi-page-actions {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Nav hover & active */
|
||||
.nav-item:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.nav-item.active {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
color: var(--color-text);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.12), inset 0 0 8px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
/* Sub-item active — slider handles highlight */
|
||||
.nav-sub .nav-item.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
/* Sliding selector — dark glass */
|
||||
.nav-sub .nav-slider {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
backdrop-filter: blur(12px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(12px) saturate(150%);
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.08), inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
/* Header tabs */
|
||||
.header-tab:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: var(--color-text);
|
||||
}
|
||||
.header-tab.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
/* Tab slider — dark glass */
|
||||
.tab-slider {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.1), inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Sub-nav bar */
|
||||
#header-sub {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1), 0 0 0 0.5px rgba(255, 255, 255, 0.12) inset, 0 0 12px rgba(255, 255, 255, 0.15) inset;
|
||||
}
|
||||
.sub-tab:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.sub-tab.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
/* Header glass pills */
|
||||
.header-title,
|
||||
#status-indicators,
|
||||
.header-actions {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.02) 50%, rgba(255, 255, 255, 0.03) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25), 0 1px 2px rgba(0, 0, 0, 0.12), inset 0 0.5px 0 rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Theme toggle */
|
||||
.theme-toggle:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.theme-toggle-float {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.08), inset 0 0 0.5px rgba(255, 255, 255, 0.12), inset 0 1px 6px rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
/* Tabs */
|
||||
.cbi-tabmenu {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1), inset 0 0 0.5px rgba(255, 255, 255, 0.12), inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
.cbi-tabmenu li a:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.cbi-tabmenu li.cbi-tab a {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.12), inset 0 0 8px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
/* Section fold button */
|
||||
.cbi-section.fade-in .cbi-title > div:last-child span:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
/* Table row hover */
|
||||
table tbody tr:hover td,
|
||||
.table .tr:hover .td {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
/* Pre / code */
|
||||
pre,
|
||||
#syslog {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
/* Alert colors adjusted for dark */
|
||||
.alert-message,
|
||||
.cbi-section-error {
|
||||
background: rgba(100, 210, 255, 0.08);
|
||||
border-color: rgba(100, 210, 255, 0.18);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 0 6px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
.alert-message.notice,
|
||||
.alert-message.info {
|
||||
background: rgba(100, 210, 255, 0.1);
|
||||
border-color: rgba(100, 210, 255, 0.25);
|
||||
}
|
||||
.alert-message.warning {
|
||||
background: rgba(255, 214, 10, 0.1);
|
||||
border-color: rgba(255, 214, 10, 0.25);
|
||||
}
|
||||
.alert-message.error,
|
||||
.cbi-section-error {
|
||||
background: rgba(255, 69, 58, 0.1);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
}
|
||||
.alert-message.success {
|
||||
background: rgba(48, 209, 88, 0.1);
|
||||
border-color: rgba(48, 209, 88, 0.25);
|
||||
}
|
||||
/* Diagnostics & file browser in dark */
|
||||
#diag-rc-output,
|
||||
.cbi-filebrowser {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 0 6px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
/* Ifacebox zone header in dark — slightly brighter tint */
|
||||
.ifacebox-head[style*="background-color"] {
|
||||
background-color: rgba(var(--zone-color-rgb), 0.2) !important;
|
||||
border-bottom-color: rgba(var(--zone-color-rgb), 0.25) !important;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
/* Zone badges in dark — tint zone color instead of opaque background */
|
||||
.zonebadge[style*="background-color"] {
|
||||
background-color: rgba(var(--zone-color-rgb), 0.25) !important;
|
||||
border-color: rgba(var(--zone-color-rgb), 0.3);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
.zonebadge {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
/* Ifacebox in dark */
|
||||
.ifacebadge {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
/* Port grid boxes in dark — glass-ui dark card */
|
||||
div[style*="display:grid;grid-template-columns:repeat"] > .ifacebox {
|
||||
background-image: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.07) 25%, rgba(240, 248, 255, 0.08) 50%, rgba(255, 255, 255, 0.06) 75%, rgba(230, 240, 255, 0.07) 100%) !important;
|
||||
border-color: rgba(255, 255, 255, 0.15) !important;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 1px 4px rgba(0, 0, 0, 0.1), 0 0 0 0.5px rgba(255, 255, 255, 0.12) inset, 0 0 12px rgba(255, 255, 255, 0.15) inset !important;
|
||||
}
|
||||
/* Network status table badges in dark */
|
||||
.network-status-table .ifacebox-body .ifacebadge {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Dropdown open items hover */
|
||||
.cbi-dropdown[open] > ul.dropdown > li:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
/* Progressbar */
|
||||
.cbi-progressbar {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.cbi-progressbar > div {
|
||||
background: linear-gradient(135deg, rgba(var(--color-primary-rgb), 0.65) 0%, rgba(var(--color-primary-rgb), 0.5) 50%, rgba(var(--color-primary-rgb), 0.6) 100%);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 0 6px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
.cbi-progressbar::after {
|
||||
color: var(--color-text);
|
||||
text-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
/* Ifacebox-body itemlist labels */
|
||||
.ifacebox-body > span > .nowrap > strong {
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
/* UCI Changes dialog in dark */
|
||||
.uci-change-legend-label > ins {
|
||||
background-color: rgba(48, 209, 88, 0.3);
|
||||
border-color: rgba(48, 209, 88, 0.5);
|
||||
}
|
||||
.uci-change-legend-label > del {
|
||||
background-color: rgba(255, 69, 58, 0.3);
|
||||
border-color: rgba(255, 69, 58, 0.5);
|
||||
}
|
||||
.uci-change-legend-label > var {
|
||||
background-color: rgba(100, 210, 255, 0.25);
|
||||
border-color: rgba(100, 210, 255, 0.4);
|
||||
}
|
||||
.uci-change-list ins {
|
||||
background-color: rgba(48, 209, 88, 0.12);
|
||||
border-color: rgba(48, 209, 88, 0.25);
|
||||
}
|
||||
.uci-change-list del {
|
||||
background-color: rgba(255, 69, 58, 0.12);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
}
|
||||
.uci-change-list var {
|
||||
background-color: rgba(100, 210, 255, 0.1);
|
||||
border-color: rgba(100, 210, 255, 0.18);
|
||||
}
|
||||
/* Selection */
|
||||
::selection {
|
||||
background: rgba(var(--color-primary-rgb), 0.35);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#F5F5F7"/>
|
||||
<stop offset="100%" stop-color="#E8E8ED"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="glass" x1="4" y1="4" x2="60" y2="60" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.9"/>
|
||||
<stop offset="40%" stop-color="white" stop-opacity="0.4"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0.6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="edge" x1="4" y1="4" x2="60" y2="60" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.95"/>
|
||||
<stop offset="50%" stop-color="#D1D1D6" stop-opacity="0.4"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0.7"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="refract" cx="18" cy="16" r="36" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.55"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
|
||||
<!-- 3D shadow filter for WiFi arcs -->
|
||||
<filter id="arc-shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="1.5" stdDeviation="1.5" flood-color="#002266" flood-opacity="0.3"/>
|
||||
</filter>
|
||||
|
||||
<!-- Arc stroke gradients — darker Apple blue with depth -->
|
||||
<linearGradient id="arc1" x1="14" y1="26" x2="50" y2="30" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#3A8EF6" stop-opacity="0.3"/>
|
||||
<stop offset="20%" stop-color="#0040DD" stop-opacity="0.9"/>
|
||||
<stop offset="50%" stop-color="#0033BB" stop-opacity="1"/>
|
||||
<stop offset="80%" stop-color="#0040DD" stop-opacity="0.9"/>
|
||||
<stop offset="100%" stop-color="#3A8EF6" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="arc2" x1="20" y1="32" x2="44" y2="36" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#3A8EF6" stop-opacity="0.25"/>
|
||||
<stop offset="25%" stop-color="#0040DD" stop-opacity="0.8"/>
|
||||
<stop offset="50%" stop-color="#0033BB" stop-opacity="0.95"/>
|
||||
<stop offset="75%" stop-color="#0040DD" stop-opacity="0.8"/>
|
||||
<stop offset="100%" stop-color="#3A8EF6" stop-opacity="0.25"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="arc3" x1="26" y1="38" x2="38" y2="42" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#4D9BF7" stop-opacity="0.2"/>
|
||||
<stop offset="30%" stop-color="#0040DD" stop-opacity="0.7"/>
|
||||
<stop offset="50%" stop-color="#0033BB" stop-opacity="0.9"/>
|
||||
<stop offset="70%" stop-color="#0040DD" stop-opacity="0.7"/>
|
||||
<stop offset="100%" stop-color="#4D9BF7" stop-opacity="0.2"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="dot-grad" cx="32" cy="46" r="3.5" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="#0033BB"/>
|
||||
<stop offset="60%" stop-color="#0040DD"/>
|
||||
<stop offset="100%" stop-color="#3A8EF6" stop-opacity="0.4"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
|
||||
<!-- Outer shadow for 3D depth -->
|
||||
<rect width="64" height="64" rx="14" fill="none" filter="url(#arc-shadow)"/>
|
||||
|
||||
<!-- Light background -->
|
||||
<rect width="64" height="64" rx="14" fill="url(#bg)"/>
|
||||
|
||||
<!-- Clean glass pane -->
|
||||
<rect x="4" y="4" width="56" height="56" rx="12" fill="url(#glass)" stroke="url(#edge)" stroke-width="0.75"/>
|
||||
|
||||
<!-- Light refraction highlight -->
|
||||
<rect x="4" y="4" width="56" height="28" rx="12" fill="url(#refract)"/>
|
||||
|
||||
<!-- Inner glow edge -->
|
||||
<rect x="5" y="5" width="54" height="54" rx="11" fill="none" stroke="white" stroke-opacity="0.35" stroke-width="0.5"/>
|
||||
|
||||
<!-- WiFi shadow layer (dark offset below — 3D depth) -->
|
||||
<path d="M14 30a25.5 25.5 0 0 1 36 0" fill="none" stroke="#002266" stroke-opacity="0.18" stroke-width="3" stroke-linecap="round"/>
|
||||
<path d="M20 36a16 16 0 0 1 24 0" fill="none" stroke="#002266" stroke-opacity="0.15" stroke-width="3" stroke-linecap="round"/>
|
||||
<path d="M26 42a7.5 7.5 0 0 1 12 0" fill="none" stroke="#002266" stroke-opacity="0.12" stroke-width="3" stroke-linecap="round"/>
|
||||
|
||||
<!-- WiFi highlight layer (white offset above — raised/embossed) -->
|
||||
<path d="M14 27a25.5 25.5 0 0 1 36 0" fill="none" stroke="white" stroke-opacity="0.65" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M20 33a16 16 0 0 1 24 0" fill="none" stroke="white" stroke-opacity="0.6" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M26 39a7.5 7.5 0 0 1 12 0" fill="none" stroke="white" stroke-opacity="0.55" stroke-width="2" stroke-linecap="round"/>
|
||||
|
||||
<!-- WiFi main arcs — darker blue gradient -->
|
||||
<path d="M14 28a25.5 25.5 0 0 1 36 0" fill="none" stroke="url(#arc1)" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<path d="M20 34a16 16 0 0 1 24 0" fill="none" stroke="url(#arc2)" stroke-width="2.5" stroke-linecap="round"/>
|
||||
<path d="M26 40a7.5 7.5 0 0 1 12 0" fill="none" stroke="url(#arc3)" stroke-width="2.5" stroke-linecap="round"/>
|
||||
|
||||
<!-- Center dot with 3D -->
|
||||
<circle cx="32" cy="48" r="2.5" fill="#002266" fill-opacity="0.15"/>
|
||||
<circle cx="32" cy="46" r="2.5" fill="url(#dot-grad)"/>
|
||||
<circle cx="31.2" cy="45.2" r="0.9" fill="white" fill-opacity="0.4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.1 KiB |
@@ -0,0 +1,327 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require ui';
|
||||
|
||||
return baseclass.extend({
|
||||
__init__: function() {
|
||||
ui.menu.load().then(L.bind(this.render, this));
|
||||
},
|
||||
|
||||
/* Icon SVG paths for top-level sidebar categories (stroke-based, 24x24 viewBox) */
|
||||
icons: {
|
||||
'status': '<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>',
|
||||
'system': '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06a1.65 1.65 0 001.82.33h.09a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82v.09a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/>',
|
||||
'network': '<circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/>',
|
||||
'services': '<polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/>',
|
||||
'nas': '<line x1="22" y1="12" x2="2" y2="12"/><path d="M5.45 5.11L2 12v6a2 2 0 002 2h16a2 2 0 002-2v-6l-3.45-6.89A2 2 0 0016.76 4H7.24a2 2 0 00-1.79 1.11z"/><line x1="6" y1="16" x2="6.01" y2="16"/><line x1="10" y1="16" x2="10.01" y2="16"/>',
|
||||
'vpn': '<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0110 0v4"/>',
|
||||
'docker': '<path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/>',
|
||||
'logout': '<path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>',
|
||||
'_default': '<circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>'
|
||||
},
|
||||
|
||||
getIcon: function(name) {
|
||||
var pathData = this.icons[name] || this.icons['_default'];
|
||||
var markup = '<svg xmlns="http://www.w3.org/2000/svg" class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">' + pathData + '</svg>';
|
||||
var doc = new DOMParser().parseFromString(markup, 'image/svg+xml');
|
||||
return document.importNode(doc.documentElement, true);
|
||||
},
|
||||
|
||||
render: function(tree) {
|
||||
var container = document.getElementById('sidebar-nav');
|
||||
if (!container) return;
|
||||
|
||||
/* Clear existing menu elements to prevent duplicates on re-render (e.g. Save & Apply) */
|
||||
container.innerHTML = '';
|
||||
|
||||
var headerNav = document.getElementById('header-nav');
|
||||
if (headerNav) {
|
||||
/* Remove only tabs and sliders, preserve header-title */
|
||||
var old = headerNav.querySelectorAll('.header-tab, .tab-slider');
|
||||
for (var k = 0; k < old.length; k++) old[k].remove();
|
||||
}
|
||||
|
||||
var headerTabs = document.getElementById('header-tabs');
|
||||
if (headerTabs) headerTabs.innerHTML = '';
|
||||
|
||||
var topChildren = ui.menu.getChildren(tree);
|
||||
|
||||
for (var i = 0; i < topChildren.length; i++) {
|
||||
var topNode = topChildren[i];
|
||||
var isTopActive = L.env.requestpath.length
|
||||
? topNode.name == L.env.requestpath[0]
|
||||
: i == 0;
|
||||
|
||||
if (isTopActive) {
|
||||
this.renderSidebarMenu(container, topNode, topNode.name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Render mode menu (top-level tabs) if more than one category */
|
||||
if (topChildren.length > 1) {
|
||||
this.renderModeMenu(topChildren);
|
||||
}
|
||||
|
||||
/* Set header title from the deepest active menu node */
|
||||
var titleEl = document.getElementById('header-title');
|
||||
if (titleEl) {
|
||||
var node = tree;
|
||||
var title = '';
|
||||
for (var i = 0; i < L.env.dispatchpath.length && node; i++) {
|
||||
node = node.children[L.env.dispatchpath[i]];
|
||||
if (node && node.title)
|
||||
title = node.title;
|
||||
}
|
||||
titleEl.textContent = title ? _(title) : '';
|
||||
}
|
||||
|
||||
/* Render tab menu for sub-sub pages */
|
||||
if (L.env.dispatchpath.length >= 3) {
|
||||
var node = tree;
|
||||
var url = '';
|
||||
for (var i = 0; i < 3 && node; i++) {
|
||||
node = node.children[L.env.dispatchpath[i]];
|
||||
url = url + (url ? '/' : '') + L.env.dispatchpath[i];
|
||||
}
|
||||
if (node)
|
||||
this.renderTabMenu(node, url);
|
||||
}
|
||||
},
|
||||
|
||||
/* Shared: position a slider behind the active tab element */
|
||||
positionTabSlider: function(container, slider, activeEl, animate) {
|
||||
if (!activeEl) return;
|
||||
if (!animate) slider.style.transition = 'none';
|
||||
slider.style.left = activeEl.offsetLeft + 'px';
|
||||
slider.style.width = activeEl.offsetWidth + 'px';
|
||||
slider.style.opacity = '1';
|
||||
if (!animate) {
|
||||
requestAnimationFrame(function() {
|
||||
slider.style.transition = '';
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/* Shared: add slider to a horizontal tab container */
|
||||
addTabSlider: function(container, navigateOnClick) {
|
||||
var slider = E('div', { 'class': 'tab-slider' });
|
||||
container.insertBefore(slider, container.firstChild);
|
||||
var self = this;
|
||||
|
||||
/* Attach click handlers to all tabs */
|
||||
var tabs = container.querySelectorAll('.header-tab, .sub-tab');
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
(function(tab, sl) {
|
||||
tab.addEventListener('click', function(ev) {
|
||||
if (navigateOnClick) {
|
||||
/* Slide first, then navigate */
|
||||
ev.preventDefault();
|
||||
var prev = container.querySelector('.header-tab.active, .sub-tab.active');
|
||||
if (prev) prev.classList.remove('active');
|
||||
tab.classList.add('active');
|
||||
self.positionTabSlider(container, sl, tab, true);
|
||||
document.body.classList.add('page-leaving');
|
||||
var href = tab.href;
|
||||
setTimeout(function() {
|
||||
window.location.href = href;
|
||||
}, 180);
|
||||
} else {
|
||||
/* In-page tab switch — just move slider */
|
||||
self.positionTabSlider(container, sl, tab, true);
|
||||
}
|
||||
});
|
||||
})(tabs[i], slider);
|
||||
}
|
||||
|
||||
/* Position on active tab */
|
||||
requestAnimationFrame(function() {
|
||||
var active = container.querySelector('.header-tab.active, .sub-tab.active');
|
||||
self.positionTabSlider(container, slider, active, false);
|
||||
});
|
||||
|
||||
return slider;
|
||||
},
|
||||
|
||||
renderModeMenu: function(topChildren) {
|
||||
var container = document.getElementById('header-nav');
|
||||
if (!container) return;
|
||||
|
||||
for (var i = 0; i < topChildren.length; i++) {
|
||||
var child = topChildren[i];
|
||||
var isActive = L.env.requestpath.length
|
||||
? child.name == L.env.requestpath[0]
|
||||
: i == 0;
|
||||
|
||||
var item = E('a', {
|
||||
'class': 'header-tab' + (isActive ? ' active' : ''),
|
||||
'href': L.url(child.name),
|
||||
'data-name': child.name
|
||||
}, [ _(child.title) ]);
|
||||
|
||||
container.appendChild(item);
|
||||
}
|
||||
|
||||
/* Add sliding selector */
|
||||
this.addTabSlider(container, true);
|
||||
},
|
||||
|
||||
renderSidebarMenu: function(container, tree, url) {
|
||||
var children = ui.menu.getChildren(tree);
|
||||
if (children.length == 0) return;
|
||||
|
||||
var group = E('div', { 'class': 'nav-group' });
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
var subChildren = ui.menu.getChildren(child);
|
||||
var hasChildren = subChildren.length > 0;
|
||||
|
||||
var isActive = L.env.dispatchpath[1] == child.name;
|
||||
|
||||
/* For items with children, link to first child */
|
||||
var linkUrl = hasChildren
|
||||
? L.url(url, child.name, subChildren[0].name)
|
||||
: L.url(url, child.name);
|
||||
|
||||
var item = E('a', {
|
||||
'class': 'nav-item' + (isActive ? ' open' : ''),
|
||||
'href': linkUrl,
|
||||
'data-name': child.name
|
||||
}, [
|
||||
E('span', { 'class': 'nav-label' }, [ _(child.title) ])
|
||||
]);
|
||||
|
||||
/* Add icon before the label */
|
||||
item.insertBefore(this.getIcon(child.name), item.firstChild);
|
||||
|
||||
if (hasChildren) {
|
||||
item.appendChild(E('svg', {
|
||||
'class': 'nav-arrow',
|
||||
'viewBox': '0 0 24 24',
|
||||
'fill': 'none',
|
||||
'stroke': 'currentColor',
|
||||
'stroke-width': '2'
|
||||
}, [
|
||||
E('polyline', { 'points': '9 18 15 12 9 6' })
|
||||
]));
|
||||
|
||||
}
|
||||
|
||||
group.appendChild(item);
|
||||
|
||||
if (hasChildren) {
|
||||
var subMenu = E('div', {
|
||||
'class': 'nav-sub' + (isActive ? ' open' : '')
|
||||
});
|
||||
|
||||
/* Sliding highlight indicator */
|
||||
var slider = E('div', { 'class': 'nav-slider' });
|
||||
subMenu.appendChild(slider);
|
||||
|
||||
for (var j = 0; j < subChildren.length; j++) {
|
||||
var sub = subChildren[j];
|
||||
var isSubActive = isActive && L.env.dispatchpath[2] == sub.name;
|
||||
|
||||
var subItem = E('a', {
|
||||
'class': 'nav-item' + (isSubActive ? ' active' : ''),
|
||||
'href': L.url(url, child.name, sub.name)
|
||||
}, [
|
||||
E('span', { 'class': 'nav-label' }, [ _(sub.title) ])
|
||||
]);
|
||||
|
||||
/* Slide highlight to clicked item before navigating */
|
||||
(function(el, sl) {
|
||||
el.addEventListener('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
var prev = el.parentNode.querySelector('.nav-item.active');
|
||||
if (prev) prev.classList.remove('active');
|
||||
el.classList.add('active');
|
||||
sl.style.top = el.offsetTop + 'px';
|
||||
sl.style.height = el.offsetHeight + 'px';
|
||||
sl.style.opacity = '1';
|
||||
document.body.classList.add('page-leaving');
|
||||
setTimeout(function() {
|
||||
window.location.href = el.href;
|
||||
}, 180);
|
||||
});
|
||||
})(subItem, slider);
|
||||
|
||||
subMenu.appendChild(subItem);
|
||||
}
|
||||
|
||||
/* Position slider on the active item after render */
|
||||
(function(sm, sl) {
|
||||
requestAnimationFrame(function() {
|
||||
var active = sm.querySelector('.nav-item.active');
|
||||
if (active) {
|
||||
sl.style.transition = 'none';
|
||||
sl.style.top = active.offsetTop + 'px';
|
||||
sl.style.height = active.offsetHeight + 'px';
|
||||
sl.style.opacity = '1';
|
||||
/* Re-enable transition after initial position */
|
||||
requestAnimationFrame(function() {
|
||||
sl.style.transition = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
})(subMenu, slider);
|
||||
|
||||
group.appendChild(subMenu);
|
||||
|
||||
/* Bind click handler to toggle submenu */
|
||||
(function(navItem, subEl) {
|
||||
navItem.addEventListener('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
var isOpen = subEl.classList.contains('open');
|
||||
if (isOpen) {
|
||||
subEl.classList.remove('open');
|
||||
navItem.classList.remove('open');
|
||||
} else {
|
||||
subEl.classList.add('open');
|
||||
navItem.classList.add('open');
|
||||
}
|
||||
});
|
||||
})(item, subMenu);
|
||||
}
|
||||
}
|
||||
|
||||
container.appendChild(group);
|
||||
},
|
||||
|
||||
renderTabMenu: function(tree, url, level) {
|
||||
var container = document.getElementById('header-sub');
|
||||
if (!container) return E([]);
|
||||
|
||||
var children = ui.menu.getChildren(tree);
|
||||
var activeNode = null;
|
||||
|
||||
if (children.length == 0)
|
||||
return E([]);
|
||||
|
||||
/* Clear any CBI tabs that footer.ut added before menu loaded */
|
||||
container.innerHTML = '';
|
||||
container.classList.remove('active');
|
||||
document.body.classList.remove('has-sub-nav');
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
var isActive = L.env.dispatchpath[3 + (level || 0)] == child.name;
|
||||
|
||||
container.appendChild(E('a', {
|
||||
'class': 'sub-tab' + (isActive ? ' active' : ''),
|
||||
'href': L.url(url, child.name)
|
||||
}, [ _(child.title) ]));
|
||||
|
||||
if (isActive)
|
||||
activeNode = child;
|
||||
}
|
||||
|
||||
container.classList.add('active');
|
||||
document.body.classList.add('has-sub-nav');
|
||||
|
||||
/* Add sliding selector */
|
||||
this.addTabSlider(container, true);
|
||||
|
||||
/* Do NOT recurse — deeper menu-tree levels stay in-content as CBI tabmenus */
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,286 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require rpc';
|
||||
'require fs';
|
||||
|
||||
var callSystemInfo = rpc.declare({
|
||||
object: 'system',
|
||||
method: 'info'
|
||||
});
|
||||
|
||||
var callInterfaceDump = rpc.declare({
|
||||
object: 'network.interface',
|
||||
method: 'dump',
|
||||
expect: { 'interface': [] }
|
||||
});
|
||||
|
||||
var callDeviceStatus = rpc.declare({
|
||||
object: 'network.device',
|
||||
method: 'status',
|
||||
params: ['name']
|
||||
});
|
||||
|
||||
return baseclass.extend({
|
||||
prevStats: null,
|
||||
prevTime: null,
|
||||
netDevice: null,
|
||||
netLabel: null,
|
||||
netChecked: false,
|
||||
linkSpeed: null,
|
||||
numCores: 1,
|
||||
|
||||
__init__: function() {
|
||||
var self = this;
|
||||
/* Detect core count once so load average can be converted to %. */
|
||||
L.resolveDefault(fs.read('/proc/cpuinfo'), '').then(function(text) {
|
||||
var m = text.match(/^processor\s*:/gm);
|
||||
self.numCores = (m && m.length) || 1;
|
||||
});
|
||||
this.setupIndicators();
|
||||
},
|
||||
|
||||
icons: {
|
||||
cpu: '<svg xmlns="http://www.w3.org/2000/svg" class="indicator-icon" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 9 4 4 7 11 10 2 13 9"/></svg>',
|
||||
ram: '<svg xmlns="http://www.w3.org/2000/svg" class="indicator-icon" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><path d="M1 3 H13 V10 H8 V9 H6 V10 H1 Z"/><rect x="2.2" y="4.5" width="2" height="3"/><rect x="6" y="4.5" width="2" height="3"/><rect x="9.8" y="4.5" width="2" height="3"/><line x1="2" y1="10" x2="2" y2="11.5"/><line x1="4" y1="10" x2="4" y2="11.5"/><line x1="10" y1="10" x2="10" y2="11.5"/><line x1="12" y1="10" x2="12" y2="11.5"/></svg>',
|
||||
net: '<svg xmlns="http://www.w3.org/2000/svg" class="indicator-icon" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="7" y1="1" x2="7" y2="13"/><polyline points="3 4 7 1 11 4"/><polyline points="3 10 7 13 11 10"/></svg>',
|
||||
uptime: '<svg xmlns="http://www.w3.org/2000/svg" class="indicator-icon" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="7" cy="7" r="6"/><polyline points="7 3 7 7 10 9"/></svg>'
|
||||
},
|
||||
|
||||
makeIcon: function(name) {
|
||||
var markup = this.icons[name];
|
||||
if (!markup) return document.createTextNode('');
|
||||
var doc = new DOMParser().parseFromString(markup, 'image/svg+xml');
|
||||
return document.importNode(doc.documentElement, true);
|
||||
},
|
||||
|
||||
createIndicator: function(name, title) {
|
||||
var el = document.createElement('span');
|
||||
el.setAttribute('data-indicator', name);
|
||||
el.title = title;
|
||||
el.appendChild(this.makeIcon(name));
|
||||
var val = document.createElement('span');
|
||||
val.className = 'indicator-value';
|
||||
/* Restore last known value from session to avoid flash of "--" on page nav */
|
||||
var cached = null;
|
||||
try { cached = sessionStorage.getItem('glass-status-' + name); } catch(e) {}
|
||||
val.textContent = cached || '--';
|
||||
el.appendChild(val);
|
||||
return el;
|
||||
},
|
||||
|
||||
setLevel: function(el, level) {
|
||||
el.setAttribute('data-level', level);
|
||||
},
|
||||
|
||||
setupIndicators: function() {
|
||||
this.container = document.getElementById('status-indicators');
|
||||
if (!this.container) return;
|
||||
|
||||
this.cpuEl = this.createIndicator('cpu', 'CPU Load');
|
||||
this.ramEl = this.createIndicator('ram', 'Memory Usage');
|
||||
this.uptimeEl = this.createIndicator('uptime', 'Uptime');
|
||||
|
||||
this.container.appendChild(this.cpuEl);
|
||||
this.container.appendChild(this.ramEl);
|
||||
this.container.appendChild(this.uptimeEl);
|
||||
|
||||
this.fetchAndUpdate();
|
||||
setInterval(L.bind(this.fetchAndUpdate, this), 5000);
|
||||
},
|
||||
|
||||
fetchAndUpdate: function() {
|
||||
var self = this;
|
||||
|
||||
L.resolveDefault(callSystemInfo(), {}).then(function(info) {
|
||||
self.updateSystem(info);
|
||||
});
|
||||
|
||||
if (!this.netChecked) {
|
||||
this.netChecked = true;
|
||||
L.resolveDefault(callInterfaceDump(), []).then(function(ifaces) {
|
||||
/* Find WAN device — prefer 'wan' over 'wan6' */
|
||||
var wanDev = null;
|
||||
for (var i = 0; i < ifaces.length; i++) {
|
||||
var iface = ifaces[i];
|
||||
if (iface.interface === 'wan') {
|
||||
wanDev = iface.l3_device || iface.device || null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!wanDev) {
|
||||
for (var i = 0; i < ifaces.length; i++) {
|
||||
if (ifaces[i].interface === 'wan6') {
|
||||
wanDev = ifaces[i].l3_device || ifaces[i].device || null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.resolvePhysicalDevice(wanDev || 'wan');
|
||||
});
|
||||
} else if (this.netDevice) {
|
||||
this.pollNetwork();
|
||||
}
|
||||
},
|
||||
|
||||
resolvePhysicalDevice: function(devName) {
|
||||
var self = this;
|
||||
L.resolveDefault(callDeviceStatus(devName), {}).then(function(dev) {
|
||||
if (!dev) return;
|
||||
var members = dev['bridge-members'];
|
||||
if (dev.type === 'bridge' && members && members.length > 0) {
|
||||
/* Bridge stats only count management traffic;
|
||||
use first physical port for real forwarded stats */
|
||||
self.netDevice = members[0];
|
||||
} else if (dev.statistics) {
|
||||
self.netDevice = devName;
|
||||
}
|
||||
if (!self.netDevice) return;
|
||||
|
||||
/* Query physical port for link speed and DSA info */
|
||||
L.resolveDefault(callDeviceStatus(self.netDevice), {}).then(function(phys) {
|
||||
if (phys && phys.speed) {
|
||||
var m = String(phys.speed).match(/^(\d+)/);
|
||||
if (m) self.linkSpeed = parseInt(m[1], 10);
|
||||
}
|
||||
/* DSA port with hardware offload: per-port counters miss
|
||||
offloaded flows; use the conduit (switch master) instead */
|
||||
if (phys && phys.devtype === 'dsa' && phys['hw-tc-offload'] && phys.conduit) {
|
||||
self.netLabel = self.netDevice;
|
||||
self.netDevice = phys.conduit;
|
||||
}
|
||||
self.netEl = self.createIndicator('net', 'Throughput');
|
||||
self.container.insertBefore(self.netEl, self.uptimeEl);
|
||||
self.pollNetwork();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
pollNetwork: function() {
|
||||
var self = this;
|
||||
L.resolveDefault(callDeviceStatus(this.netDevice), {}).then(function(dev) {
|
||||
self.updateNetwork(dev);
|
||||
});
|
||||
},
|
||||
|
||||
updateSystem: function(info) {
|
||||
if (!info) return;
|
||||
|
||||
if (info.load) {
|
||||
var load1 = info.load[0] / 65536;
|
||||
var load5 = (info.load[1] / 65536).toFixed(2);
|
||||
var load15 = (info.load[2] / 65536).toFixed(2);
|
||||
var pct = Math.min(load1 / this.numCores, 1) * 100;
|
||||
var pctStr = pct.toFixed(0) + '%';
|
||||
|
||||
this.cpuEl.querySelector('.indicator-value').textContent = pctStr;
|
||||
try { sessionStorage.setItem('glass-status-cpu', pctStr); } catch(e) {}
|
||||
this.cpuEl.title = 'CPU: ' + pctStr + ' (load ' + load1.toFixed(2) +
|
||||
' / ' + load5 + ' / ' + load15 + ' on ' + this.numCores +
|
||||
(this.numCores === 1 ? ' core)' : ' cores)');
|
||||
|
||||
var level = pct < 60 ? 'ok' : pct < 85 ? 'warn' : 'crit';
|
||||
this.setLevel(this.cpuEl, level);
|
||||
}
|
||||
|
||||
if (info.memory) {
|
||||
var total = info.memory.total;
|
||||
var avail = info.memory.available || info.memory.free;
|
||||
var used = total - avail;
|
||||
var pct = (used / total * 100).toFixed(0);
|
||||
this.ramEl.querySelector('.indicator-value').textContent = pct + '%';
|
||||
try { sessionStorage.setItem('glass-status-ram', pct + '%'); } catch(e) {}
|
||||
this.ramEl.title = 'RAM: ' + this.formatBytes(used) + ' / ' + this.formatBytes(total) + ' (' + pct + '% used)';
|
||||
|
||||
var level = pct < 60 ? 'ok' : pct < 85 ? 'warn' : 'crit';
|
||||
this.setLevel(this.ramEl, level);
|
||||
}
|
||||
|
||||
if (info.uptime) {
|
||||
this.uptimeEl.querySelector('.indicator-value').textContent = this.formatUptime(info.uptime);
|
||||
try { sessionStorage.setItem('glass-status-uptime', this.formatUptime(info.uptime)); } catch(e) {}
|
||||
this.uptimeEl.title = 'Uptime: ' + this.formatUptimeFull(info.uptime);
|
||||
}
|
||||
},
|
||||
|
||||
updateNetwork: function(dev) {
|
||||
if (!dev || !dev.statistics || !this.netEl) return;
|
||||
|
||||
var now = Date.now() / 1000;
|
||||
var rx = dev.statistics.rx_bytes || 0;
|
||||
var tx = dev.statistics.tx_bytes || 0;
|
||||
|
||||
if (this.prevStats && this.prevTime) {
|
||||
var dt = now - this.prevTime;
|
||||
if (dt > 0) {
|
||||
var rxSpeed = (rx - this.prevStats.rx) / dt;
|
||||
var txSpeed = (tx - this.prevStats.tx) / dt;
|
||||
if (rxSpeed < 0) rxSpeed = 0;
|
||||
if (txSpeed < 0) txSpeed = 0;
|
||||
var netText = '\u2193' + this.formatSpeed(rxSpeed) + ' \u2191' + this.formatSpeed(txSpeed);
|
||||
this.netEl.querySelector('.indicator-value').textContent = netText;
|
||||
try { sessionStorage.setItem('glass-status-net', netText); } catch(e) {}
|
||||
var tip = (this.netLabel || this.netDevice) + ': \u2193 ' + this.formatSpeedFull(rxSpeed) + ' / \u2191 ' + this.formatSpeedFull(txSpeed);
|
||||
if (this.linkSpeed)
|
||||
tip += ' (Link: ' + (this.linkSpeed >= 1000 ? (this.linkSpeed / 1000) + ' Gbps' : this.linkSpeed + ' Mbps') + ')';
|
||||
this.netEl.title = tip;
|
||||
|
||||
var peak = Math.max(rxSpeed, txSpeed);
|
||||
var level = peak < 1048576 ? 'ok' : peak < 52428800 ? 'active' : 'busy';
|
||||
this.setLevel(this.netEl, level);
|
||||
}
|
||||
}
|
||||
|
||||
this.prevStats = { rx: rx, tx: tx };
|
||||
this.prevTime = now;
|
||||
},
|
||||
|
||||
formatUptime: function(s) {
|
||||
var d = Math.floor(s / 86400);
|
||||
var h = Math.floor((s % 86400) / 3600);
|
||||
var m = Math.floor((s % 3600) / 60);
|
||||
if (d > 0) return d + 'd ' + h + 'h';
|
||||
return h + 'h ' + m + 'm';
|
||||
},
|
||||
|
||||
formatUptimeFull: function(s) {
|
||||
var d = Math.floor(s / 86400);
|
||||
var h = Math.floor((s % 86400) / 3600);
|
||||
var m = Math.floor((s % 3600) / 60);
|
||||
var parts = [];
|
||||
if (d > 0) parts.push(d + (d === 1 ? ' day' : ' days'));
|
||||
if (h > 0) parts.push(h + (h === 1 ? ' hour' : ' hours'));
|
||||
if (m > 0) parts.push(m + (m === 1 ? ' min' : ' mins'));
|
||||
return parts.join(', ') || '< 1 min';
|
||||
},
|
||||
|
||||
formatBytes: function(bytes) {
|
||||
if (bytes >= 1073741824)
|
||||
return (bytes / 1073741824).toFixed(1) + ' GB';
|
||||
if (bytes >= 1048576)
|
||||
return (bytes / 1048576).toFixed(0) + ' MB';
|
||||
return (bytes / 1024).toFixed(0) + ' KB';
|
||||
},
|
||||
|
||||
formatSpeed: function(bytesPerSec) {
|
||||
var bits = bytesPerSec * 8;
|
||||
if (bits >= 1000000000)
|
||||
return (bits / 1000000000).toFixed(1) + 'G';
|
||||
if (bits >= 1000000)
|
||||
return (bits / 1000000).toFixed(1) + 'M';
|
||||
if (bits >= 1000)
|
||||
return (bits / 1000).toFixed(1) + 'K';
|
||||
return Math.round(bits) + 'b';
|
||||
},
|
||||
|
||||
formatSpeedFull: function(bytesPerSec) {
|
||||
var bits = bytesPerSec * 8;
|
||||
if (bits >= 1000000000)
|
||||
return (bits / 1000000000).toFixed(1) + ' Gbps';
|
||||
if (bits >= 1000000)
|
||||
return (bits / 1000000).toFixed(1) + ' Mbps';
|
||||
if (bits >= 1000)
|
||||
return (bits / 1000).toFixed(1) + ' kbps';
|
||||
return Math.round(bits) + ' bps';
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,137 @@
|
||||
'use strict';
|
||||
'require view';
|
||||
'require form';
|
||||
'require uci';
|
||||
'require fs';
|
||||
|
||||
return view.extend({
|
||||
load: function () {
|
||||
return Promise.all([
|
||||
uci.load('glass'),
|
||||
L.resolveDefault(fs.list('/www/luci-static/glass/background'), [])
|
||||
]);
|
||||
},
|
||||
|
||||
render: function (data) {
|
||||
var bgFiles = (data[1] || []).filter(function(f) {
|
||||
return f.name && !f.name.startsWith('.') && /\.(jpe?g|png|gif|webp|mp4|webm)$/i.test(f.name);
|
||||
});
|
||||
var hasBg = bgFiles.length > 0;
|
||||
var bgName = hasBg ? bgFiles[0].name : null;
|
||||
|
||||
var m, s, o;
|
||||
|
||||
m = new form.Map('glass', _('Glass Theme'),
|
||||
_('Configure the appearance of the Glass theme. Changes take effect after saving and refreshing the page.'));
|
||||
|
||||
/* ── General ── */
|
||||
s = m.section(form.NamedSection, 'global', 'global', _('General'));
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.ListValue, 'mode', _('Theme mode'),
|
||||
_('Controls the overall appearance. "Normal" follows the system preference.'));
|
||||
o.value('normal', _('Auto (follow system)'));
|
||||
o.value('light', _('Light'));
|
||||
o.value('dark', _('Dark'));
|
||||
o.default = 'normal';
|
||||
|
||||
o = s.option(form.Flag, 'status_bar', _('Header status bar'),
|
||||
_('Show live system stats (CPU, RAM, network, uptime) in the header. Disable to reduce resource usage on low-end devices.'));
|
||||
o.default = '1';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.ListValue, 'font_size', _('Base font size'),
|
||||
_('Scales all text in the theme. Larger values improve readability on high-DPI displays.'));
|
||||
o.value('13', _('Small (13px)'));
|
||||
o.value('14', _('Normal (14px)'));
|
||||
o.value('16', _('Large (16px)'));
|
||||
o.value('18', _('Extra Large (18px)'));
|
||||
o.default = '14';
|
||||
|
||||
/* ── Colors ── */
|
||||
s = m.section(form.NamedSection, 'global', 'global', _('Accent Colors'));
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Value, 'primary', _('Primary color (light mode)'),
|
||||
_('Accent color used for active elements, links, and buttons in light mode.'));
|
||||
o.default = '#007AFF';
|
||||
o.placeholder = '#007AFF';
|
||||
o.datatype = 'string';
|
||||
o.renderWidget = function(section_id, option_index, cfgvalue) {
|
||||
var el = form.Value.prototype.renderWidget.apply(this, arguments);
|
||||
var input = el.querySelector('input');
|
||||
if (input) {
|
||||
input.type = 'color';
|
||||
input.style.height = '2.5rem';
|
||||
input.style.cursor = 'pointer';
|
||||
}
|
||||
return el;
|
||||
};
|
||||
|
||||
o = s.option(form.Value, 'dark_primary', _('Primary color (dark mode)'),
|
||||
_('Accent color used for active elements, links, and buttons in dark mode.'));
|
||||
o.default = '#0A84FF';
|
||||
o.placeholder = '#0A84FF';
|
||||
o.datatype = 'string';
|
||||
o.renderWidget = function(section_id, option_index, cfgvalue) {
|
||||
var el = form.Value.prototype.renderWidget.apply(this, arguments);
|
||||
var input = el.querySelector('input');
|
||||
if (input) {
|
||||
input.type = 'color';
|
||||
input.style.height = '2.5rem';
|
||||
input.style.cursor = 'pointer';
|
||||
}
|
||||
return el;
|
||||
};
|
||||
|
||||
/* ── Glass Effects (Light Mode) ── */
|
||||
s = m.section(form.NamedSection, 'global', 'global', _('Glass Effects — Light Mode'));
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Value, 'blur', _('Blur intensity (px)'),
|
||||
_('Backdrop blur radius for glass panels. Higher values create a more frosted appearance.'));
|
||||
o.default = '20';
|
||||
o.placeholder = '20';
|
||||
o.datatype = 'range(0,50)';
|
||||
|
||||
o = s.option(form.Value, 'transparency', _('Panel transparency'),
|
||||
_('Background opacity of glass panels (0 = fully transparent, 1 = fully opaque).'));
|
||||
o.default = '0.72';
|
||||
o.placeholder = '0.72';
|
||||
o.datatype = 'string';
|
||||
|
||||
/* ── Glass Effects (Dark Mode) ── */
|
||||
s = m.section(form.NamedSection, 'global', 'global', _('Glass Effects — Dark Mode'));
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.Value, 'blur_dark', _('Blur intensity (px)'),
|
||||
_('Backdrop blur radius for glass panels in dark mode.'));
|
||||
o.default = '25';
|
||||
o.placeholder = '25';
|
||||
o.datatype = 'range(0,50)';
|
||||
|
||||
o = s.option(form.Value, 'transparency_dark', _('Panel transparency'),
|
||||
_('Background opacity of glass panels in dark mode (0 = fully transparent, 1 = fully opaque).'));
|
||||
o.default = '0.30';
|
||||
o.placeholder = '0.30';
|
||||
o.datatype = 'string';
|
||||
|
||||
/* ── Background ── */
|
||||
s = m.section(form.NamedSection, 'global', 'global', _('Background'));
|
||||
s.anonymous = true;
|
||||
|
||||
o = s.option(form.DummyValue, '_bg_info', _('Current background'));
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function () {
|
||||
if (hasBg) {
|
||||
return '<span style="color:var(--color-success)">' +
|
||||
_('Active') + ': ' + bgName + '</span>';
|
||||
}
|
||||
return '<span style="color:var(--color-text-secondary)">' +
|
||||
_('No background set. Upload an image or video named "bg" (e.g. bg.jpg, bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP.') +
|
||||
'</span>';
|
||||
};
|
||||
|
||||
return m.render();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/* ==========================================================================
|
||||
luci-theme-glass — Master Stylesheet
|
||||
Import order matters: tokens → reset → mixins → layout → components → fixes
|
||||
========================================================================== */
|
||||
|
||||
@import "variables";
|
||||
@import "normalize";
|
||||
@import "glass";
|
||||
@import "layout";
|
||||
@import "components";
|
||||
@import "sysauth";
|
||||
@import "responsive";
|
||||
@import "page-fix";
|
||||
@@ -0,0 +1,576 @@
|
||||
/* ==========================================================================
|
||||
Dark Mode — luci-theme-glass
|
||||
Compiled separately and injected by header.ut when dark mode is active.
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
/* ---- Colors — Dark mode ---- */
|
||||
--color-primary: #0A84FF;
|
||||
--color-primary-hover: #409cff;
|
||||
--color-primary-active: #0066d6;
|
||||
--color-primary-rgb: 10, 132, 255;
|
||||
|
||||
--color-success: #30D158;
|
||||
--color-warning: #FFD60A;
|
||||
--color-danger: #FF453A;
|
||||
--color-info: #64D2FF;
|
||||
|
||||
--color-text: #f5f5f7;
|
||||
--color-text-secondary: #98989d;
|
||||
--color-text-tertiary: #636366;
|
||||
--color-text-inverse: #1d1d1f;
|
||||
|
||||
--color-bg: #1c1c1e;
|
||||
--color-bg-elevated: #2c2c2e;
|
||||
--color-bg-secondary: #3a3a3c;
|
||||
|
||||
--color-border: rgba(255, 255, 255, 0.08);
|
||||
--color-border-strong: rgba(255, 255, 255, 0.16);
|
||||
--color-separator: rgba(84, 84, 88, 0.36);
|
||||
|
||||
/* ---- Dark glassmorphism ---- */
|
||||
--glass-blur: 25px;
|
||||
--glass-saturate: 180%;
|
||||
--glass-bg: rgba(38, 38, 42, 0.55);
|
||||
--glass-bg-hover: rgba(52, 52, 56, 0.65);
|
||||
--glass-bg-strong: rgba(38, 38, 42, 0.72);
|
||||
--glass-border: rgba(255, 255, 255, 0.12);
|
||||
--glass-shadow: 0 2px 16px rgba(0, 0, 0, 0.20),
|
||||
0 0 1px rgba(0, 0, 0, 0.25);
|
||||
--glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.30),
|
||||
0 0 1px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* ---- Dark background ---- */
|
||||
--bg-gradient: linear-gradient(135deg, #2c2e3a 0%, #353848 50%, #2a2d38 100%);
|
||||
}
|
||||
|
||||
/* ---- Dark-mode-specific overrides ---- */
|
||||
|
||||
/* Inputs need darker backgrounds */
|
||||
.cbi-input-text,
|
||||
.cbi-input-password,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
textarea,
|
||||
select {
|
||||
background: rgba(44, 44, 46, 0.55);
|
||||
}
|
||||
|
||||
/* Login card */
|
||||
.login-card {
|
||||
background-image: linear-gradient(
|
||||
160deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
background-color: rgba(38, 38, 42, 0.55);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow:
|
||||
0 8px 40px rgba(0, 0, 0, 0.25),
|
||||
0 2px 8px rgba(0, 0, 0, 0.12),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.10),
|
||||
inset 0 0 16px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.login-form .login-field input {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.08) 0%,
|
||||
rgba(255, 255, 255, 0.06) 25%,
|
||||
rgba(240, 248, 255, 0.07) 50%,
|
||||
rgba(255, 255, 255, 0.05) 75%,
|
||||
rgba(230, 240, 255, 0.06) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.30),
|
||||
0 1px 4px rgba(0, 0, 0, 0.15),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.12),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
/* Buttons — glass-ui dark pattern */
|
||||
.btn,
|
||||
.cbi-button {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.08) 0%,
|
||||
rgba(255, 255, 255, 0.06) 25%,
|
||||
rgba(240, 248, 255, 0.07) 50%,
|
||||
rgba(255, 255, 255, 0.05) 75%,
|
||||
rgba(230, 240, 255, 0.06) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.30),
|
||||
0 1px 4px rgba(0, 0, 0, 0.15),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.12),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.90;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow:
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.30),
|
||||
inset 0 1px 2px rgba(0, 0, 0, 0.20);
|
||||
}
|
||||
}
|
||||
|
||||
.cbi-button-negative,
|
||||
.cbi-button-remove,
|
||||
.cbi-button-reset {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 69, 58, 0.12) 0%,
|
||||
rgba(255, 69, 58, 0.08) 50%,
|
||||
rgba(255, 69, 58, 0.10) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
color: var(--color-danger);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.30),
|
||||
0 1px 4px rgba(0, 0, 0, 0.15),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.90;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow:
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.30),
|
||||
inset 0 1px 2px rgba(0, 0, 0, 0.20);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
#sidebar {
|
||||
background-image: linear-gradient(
|
||||
160deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 20%,
|
||||
rgba(240, 248, 255, 0.08) 45%,
|
||||
rgba(255, 255, 255, 0.06) 70%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
background-color: rgba(38, 38, 42, 0.55);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow:
|
||||
0 8px 40px rgba(0, 0, 0, 0.25),
|
||||
0 2px 8px rgba(0, 0, 0, 0.12),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.10),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Header bar */
|
||||
#header {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 2px 16px rgba(0, 0, 0, 0.20),
|
||||
0 1px 4px rgba(0, 0, 0, 0.10),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.10),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Page actions bar */
|
||||
.cbi-page-actions {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 2px 16px rgba(0, 0, 0, 0.20),
|
||||
0 1px 4px rgba(0, 0, 0, 0.10),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.10),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Nav hover & active */
|
||||
.nav-item:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
color: var(--color-text);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow:
|
||||
0 2px 6px rgba(0, 0, 0, 0.30),
|
||||
inset 0 1px 2px rgba(255, 255, 255, 0.12),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* Sub-item active — slider handles highlight */
|
||||
.nav-sub .nav-item.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
|
||||
/* Sliding selector — dark glass */
|
||||
.nav-sub .nav-slider {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
backdrop-filter: blur(12px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(12px) saturate(150%);
|
||||
box-shadow:
|
||||
0 1px 4px rgba(0, 0, 0, 0.20),
|
||||
inset 0 1px 1px rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
/* Header tabs */
|
||||
.header-tab {
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
color: var(--color-text);
|
||||
}
|
||||
&.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tab slider — dark glass */
|
||||
.tab-slider {
|
||||
background: rgba(255, 255, 255, 0.10);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow:
|
||||
0 2px 6px rgba(0, 0, 0, 0.30),
|
||||
inset 0 1px 2px rgba(255, 255, 255, 0.10),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Sub-nav bar */
|
||||
#header-sub {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.20),
|
||||
0 1px 4px rgba(0, 0, 0, 0.10),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.12) inset,
|
||||
0 0 12px rgba(255, 255, 255, 0.15) inset;
|
||||
}
|
||||
|
||||
.sub-tab {
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Header glass pills */
|
||||
.header-title,
|
||||
#status-indicators,
|
||||
.header-actions {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.04) 0%,
|
||||
rgba(255, 255, 255, 0.02) 50%,
|
||||
rgba(255, 255, 255, 0.03) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.10);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.25),
|
||||
0 1px 2px rgba(0, 0, 0, 0.12),
|
||||
inset 0 0.5px 0 rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Theme toggle */
|
||||
.theme-toggle:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.theme-toggle-float {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.18),
|
||||
0 1px 2px rgba(0, 0, 0, 0.08),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.12),
|
||||
inset 0 1px 6px rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.cbi-tabmenu {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.20),
|
||||
0 1px 4px rgba(0, 0, 0, 0.10),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.12),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
|
||||
li {
|
||||
a:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
&.cbi-tab a {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 2px 6px rgba(0, 0, 0, 0.30),
|
||||
inset 0 1px 2px rgba(255, 255, 255, 0.12),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Section fold button */
|
||||
.cbi-section.fade-in .cbi-title > div:last-child span:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* Table row hover */
|
||||
table tbody tr:hover td,
|
||||
.table .tr:hover .td {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
/* Pre / code */
|
||||
pre,
|
||||
#syslog {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* Alert colors adjusted for dark */
|
||||
.alert-message,
|
||||
.cbi-section-error {
|
||||
background: rgba(100, 210, 255, 0.08);
|
||||
border-color: rgba(100, 210, 255, 0.18);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.20),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.alert-message.notice,
|
||||
.alert-message.info {
|
||||
background: rgba(100, 210, 255, 0.10);
|
||||
border-color: rgba(100, 210, 255, 0.25);
|
||||
}
|
||||
|
||||
.alert-message.warning {
|
||||
background: rgba(255, 214, 10, 0.10);
|
||||
border-color: rgba(255, 214, 10, 0.25);
|
||||
}
|
||||
|
||||
.alert-message.error,
|
||||
.cbi-section-error {
|
||||
background: rgba(255, 69, 58, 0.10);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
}
|
||||
|
||||
.alert-message.success {
|
||||
background: rgba(48, 209, 88, 0.10);
|
||||
border-color: rgba(48, 209, 88, 0.25);
|
||||
}
|
||||
|
||||
/* Diagnostics & file browser in dark */
|
||||
#diag-rc-output,
|
||||
.cbi-filebrowser {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.18),
|
||||
0 1px 2px rgba(0, 0, 0, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
/* Ifacebox zone header in dark — slightly brighter tint */
|
||||
.ifacebox-head[style*="background-color"] {
|
||||
background-color: rgba(var(--zone-color-rgb), 0.20) !important;
|
||||
border-bottom-color: rgba(var(--zone-color-rgb), 0.25) !important;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* Zone badges in dark — tint zone color instead of opaque background */
|
||||
.zonebadge[style*="background-color"] {
|
||||
background-color: rgba(var(--zone-color-rgb), 0.25) !important;
|
||||
border-color: rgba(var(--zone-color-rgb), 0.30);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.zonebadge {
|
||||
border-color: rgba(255, 255, 255, 0.08);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
/* Ifacebox in dark */
|
||||
.ifacebadge {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-color: rgba(255, 255, 255, 0.10);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
/* Port grid boxes in dark — glass-ui dark card */
|
||||
div[style*="display:grid;grid-template-columns:repeat"] > .ifacebox {
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0.07) 25%,
|
||||
rgba(240, 248, 255, 0.08) 50%,
|
||||
rgba(255, 255, 255, 0.06) 75%,
|
||||
rgba(230, 240, 255, 0.07) 100%
|
||||
) !important;
|
||||
border-color: rgba(255, 255, 255, 0.15) !important;
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.20),
|
||||
0 1px 4px rgba(0, 0, 0, 0.10),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.12) inset,
|
||||
0 0 12px rgba(255, 255, 255, 0.15) inset !important;
|
||||
}
|
||||
|
||||
/* Network status table badges in dark */
|
||||
.network-status-table .ifacebox-body .ifacebadge {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Dropdown open items hover */
|
||||
.cbi-dropdown[open] > ul.dropdown > li:hover {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
/* Progressbar */
|
||||
.cbi-progressbar {
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: rgba(255, 255, 255, 0.06);
|
||||
|
||||
> div {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(var(--color-primary-rgb), 0.65) 0%,
|
||||
rgba(var(--color-primary-rgb), 0.50) 50%,
|
||||
rgba(var(--color-primary-rgb), 0.60) 100%
|
||||
);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.15),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
&::after {
|
||||
color: var(--color-text);
|
||||
text-shadow: 0 0 4px rgba(0, 0, 0, 0.40);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ifacebox-body itemlist labels */
|
||||
.ifacebox-body > span > .nowrap > strong {
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
|
||||
/* UCI Changes dialog in dark */
|
||||
.uci-change-legend-label {
|
||||
> ins {
|
||||
background-color: rgba(48, 209, 88, 0.30);
|
||||
border-color: rgba(48, 209, 88, 0.50);
|
||||
}
|
||||
> del {
|
||||
background-color: rgba(255, 69, 58, 0.30);
|
||||
border-color: rgba(255, 69, 58, 0.50);
|
||||
}
|
||||
> var {
|
||||
background-color: rgba(100, 210, 255, 0.25);
|
||||
border-color: rgba(100, 210, 255, 0.40);
|
||||
}
|
||||
}
|
||||
|
||||
.uci-change-list {
|
||||
ins {
|
||||
background-color: rgba(48, 209, 88, 0.12);
|
||||
border-color: rgba(48, 209, 88, 0.25);
|
||||
}
|
||||
del {
|
||||
background-color: rgba(255, 69, 58, 0.12);
|
||||
border-color: rgba(255, 69, 58, 0.25);
|
||||
}
|
||||
var {
|
||||
background-color: rgba(100, 210, 255, 0.10);
|
||||
border-color: rgba(100, 210, 255, 0.18);
|
||||
}
|
||||
}
|
||||
|
||||
/* Selection */
|
||||
::selection {
|
||||
background: rgba(var(--color-primary-rgb), 0.35);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* ==========================================================================
|
||||
Glassmorphism Mixins — luci-theme-glass
|
||||
========================================================================== */
|
||||
|
||||
/* Standard glass panel — default for cards, sections, dropdowns */
|
||||
.glass-effect() {
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid var(--glass-border);
|
||||
box-shadow: var(--glass-shadow);
|
||||
}
|
||||
|
||||
/* Frosted glass — stronger blur, higher opacity (sidebar, login card) */
|
||||
.glass-frosted() {
|
||||
background: var(--glass-bg-strong);
|
||||
backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid var(--glass-border);
|
||||
box-shadow: var(--glass-shadow-lg);
|
||||
}
|
||||
|
||||
/* Subtle glass — minimal effect for secondary/nested elements */
|
||||
.glass-subtle() {
|
||||
background: rgba(255, 255, 255, 0.40);
|
||||
backdrop-filter: blur(10px) saturate(120%);
|
||||
-webkit-backdrop-filter: blur(10px) saturate(120%);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
/* Glass hover state */
|
||||
.glass-hover() {
|
||||
background: var(--glass-bg-hover);
|
||||
box-shadow: var(--glass-shadow-lg);
|
||||
}
|
||||
|
||||
/* Inner glow — top highlight for glass panels */
|
||||
.glass-inner-glow() {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.6),
|
||||
transparent
|
||||
);
|
||||
border-radius: inherit;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,798 @@
|
||||
/* ==========================================================================
|
||||
Layout — Sidebar, Header, Content
|
||||
========================================================================== */
|
||||
|
||||
/* ---- Background layer ---- */
|
||||
#bg-wrap {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
background: var(--bg-gradient);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
|
||||
img, video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Sidebar ---- */
|
||||
#sidebar {
|
||||
position: fixed;
|
||||
top: var(--sidebar-gap);
|
||||
left: var(--sidebar-gap);
|
||||
width: var(--sidebar-width);
|
||||
height: calc(100vh - var(--sidebar-gap) * 2);
|
||||
z-index: var(--z-sidebar);
|
||||
/* True glassmorphism — multi-stop gradient, stronger for readability */
|
||||
background-image: linear-gradient(
|
||||
160deg,
|
||||
rgba(255, 255, 255, 0.22) 0%,
|
||||
rgba(255, 255, 255, 0.18) 20%,
|
||||
rgba(245, 250, 255, 0.20) 45%,
|
||||
rgba(255, 255, 255, 0.16) 70%,
|
||||
rgba(240, 245, 255, 0.19) 100%
|
||||
);
|
||||
background-color: rgba(255, 255, 255, 0.62);
|
||||
backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.40);
|
||||
box-shadow:
|
||||
0 8px 40px rgba(0, 0, 0, 0.08),
|
||||
0 2px 8px rgba(0, 0, 0, 0.04),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.50),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.15);
|
||||
border-radius: var(--radius-xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: transform var(--transition-slow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--space-lg) var(--space-xl);
|
||||
height: var(--header-height);
|
||||
border-bottom: 0.5px solid var(--color-separator);
|
||||
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.brand {
|
||||
margin-left: var(--space-md);
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: var(--space-md) var(--space-xl);
|
||||
border-top: 0.5px solid var(--color-separator);
|
||||
text-align: center;
|
||||
|
||||
.sidebar-version {
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Sidebar navigation ---- */
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: var(--space-sm) 0;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-group {
|
||||
margin-bottom: var(--space-xs);
|
||||
|
||||
.nav-group-title {
|
||||
padding: var(--space-sm) var(--space-xl);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-tertiary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.55rem var(--space-xl);
|
||||
margin: 1px var(--space-sm);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-lg);
|
||||
color: var(--color-text);
|
||||
cursor: pointer;
|
||||
transition: background var(--transition-fast), color var(--transition-fast);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: rgba(255, 255, 255, 0.45);
|
||||
color: var(--color-text);
|
||||
font-weight: var(--font-weight-medium);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.08),
|
||||
inset 0 1px 1px rgba(255, 255, 255, 0.60),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: var(--space-md);
|
||||
flex-shrink: 0;
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
&.active .nav-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-label {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-arrow {
|
||||
margin-left: auto;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0.4;
|
||||
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity var(--transition-fast);
|
||||
}
|
||||
|
||||
&.open .nav-arrow {
|
||||
transform: rotate(90deg);
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-sub {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
opacity: 0;
|
||||
transition: max-height 0.35s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
opacity 0.25s ease;
|
||||
|
||||
&.open {
|
||||
/* Upper bound for the expand animation. Must exceed the tallest submenu
|
||||
encountered in the wild (System commonly reaches ~14 items once third-
|
||||
party apps like theme-config, scheduled-tasks, etc. are installed). */
|
||||
max-height: 2000px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding-left: calc(var(--space-xl) + 32px);
|
||||
font-size: var(--font-size-base);
|
||||
transform: translateX(-8px);
|
||||
opacity: 0;
|
||||
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
opacity 0.2s ease,
|
||||
color var(--transition-fast);
|
||||
|
||||
/* Sub-item active state — no background, slider handles it */
|
||||
&.active {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
}
|
||||
|
||||
&.open .nav-item {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Stagger sub-items (nth-of-type since slider is first child)
|
||||
&.open .nav-item:nth-of-type(1) { transition-delay: 0.03s; }
|
||||
&.open .nav-item:nth-of-type(2) { transition-delay: 0.06s; }
|
||||
&.open .nav-item:nth-of-type(3) { transition-delay: 0.09s; }
|
||||
&.open .nav-item:nth-of-type(4) { transition-delay: 0.12s; }
|
||||
&.open .nav-item:nth-of-type(5) { transition-delay: 0.15s; }
|
||||
&.open .nav-item:nth-of-type(6) { transition-delay: 0.18s; }
|
||||
&.open .nav-item:nth-of-type(7) { transition-delay: 0.21s; }
|
||||
&.open .nav-item:nth-of-type(8) { transition-delay: 0.24s; }
|
||||
&.open .nav-item:nth-of-type(n+9) { transition-delay: 0.27s; }
|
||||
|
||||
.nav-slider {
|
||||
position: absolute;
|
||||
left: var(--space-sm);
|
||||
right: var(--space-sm);
|
||||
top: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
border-radius: var(--radius-md);
|
||||
background: rgba(255, 255, 255, 0.35);
|
||||
backdrop-filter: blur(12px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(12px) saturate(150%);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.45);
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.04),
|
||||
inset 0 1px 1px rgba(255, 255, 255, 0.35),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.10);
|
||||
transition: top 0.3s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
height 0.2s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
opacity 0.2s ease;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Sidebar user area ---- */
|
||||
.sidebar-user {
|
||||
padding: var(--space-lg) var(--space-xl);
|
||||
border-top: 0.5px solid var(--color-separator);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.user-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--radius-full);
|
||||
background: var(--color-bg-secondary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
margin-left: var(--space-md);
|
||||
overflow: hidden;
|
||||
|
||||
.user-name {
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: var(--font-size-sm);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.user-host {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Top header nav bar ---- */
|
||||
#header {
|
||||
position: fixed;
|
||||
top: var(--sidebar-gap);
|
||||
left: calc(var(--sidebar-width) + var(--sidebar-gap) * 2);
|
||||
right: var(--sidebar-gap);
|
||||
height: 44px;
|
||||
z-index: var(--z-header);
|
||||
border-radius: var(--radius-lg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 4px 4px 4px 6px;
|
||||
gap: var(--space-xs);
|
||||
transition: left var(--transition-slow);
|
||||
|
||||
/* True glassmorphism — multi-stop gradient like sub-nav */
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.35);
|
||||
box-shadow:
|
||||
0 2px 16px rgba(0, 0, 0, 0.06),
|
||||
0 1px 4px rgba(0, 0, 0, 0.03),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.40),
|
||||
inset 0 0 8px rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
/* ---- Header top-level tabs ---- */
|
||||
#header-nav,
|
||||
#header-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-sep {
|
||||
width: 1px;
|
||||
height: 18px;
|
||||
background: var(--color-separator);
|
||||
margin: 0 var(--space-xs);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-tab {
|
||||
padding: 6px var(--space-lg);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-secondary);
|
||||
text-decoration: none;
|
||||
transition: background var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast);
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--color-text);
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Horizontal sliding selector for header tabs */
|
||||
.tab-slider {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
border-radius: var(--radius-md);
|
||||
background: rgba(255, 255, 255, 0.45);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow:
|
||||
0 1px 3px rgba(0, 0, 0, 0.08),
|
||||
inset 0 1px 1px rgba(255, 255, 255, 0.60),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.15);
|
||||
transition: left 0.3s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
width 0.2s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
opacity 0.2s ease;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.header-tab,
|
||||
.sub-tab {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* ---- Status indicators (center of header) ---- */
|
||||
#status-indicators {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
padding: 4px var(--space-md);
|
||||
.header-glass-pill();
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-indicator] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-secondary);
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
transition: color 0.3s ease;
|
||||
|
||||
.indicator-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.6;
|
||||
transition: color 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
/* Level colors — neutral by default, color only when noteworthy */
|
||||
&[data-level="warn"] {
|
||||
color: #FF9500;
|
||||
.indicator-icon { opacity: 0.85; }
|
||||
}
|
||||
&[data-level="crit"] {
|
||||
color: #FF3B30;
|
||||
.indicator-icon { opacity: 0.9; }
|
||||
}
|
||||
&[data-level="active"] {
|
||||
color: #007AFF;
|
||||
.indicator-icon { opacity: 0.8; }
|
||||
}
|
||||
&[data-level="busy"] {
|
||||
color: #AF52DE;
|
||||
.indicator-icon { opacity: 0.85; }
|
||||
}
|
||||
}
|
||||
|
||||
[data-indicator] + [data-indicator] {
|
||||
border-left: 0.5px solid rgba(128, 128, 128, 0.25);
|
||||
padding-left: var(--space-sm);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Glass pill badges (title + indicators) ---- */
|
||||
.header-glass-pill() {
|
||||
height: 2.25rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: var(--radius-md);
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.10) 25%,
|
||||
rgba(240, 248, 255, 0.12) 50%,
|
||||
rgba(255, 255, 255, 0.08) 75%,
|
||||
rgba(230, 240, 255, 0.10) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.18);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.06),
|
||||
0 1px 2px rgba(0, 0, 0, 0.03),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.08) inset,
|
||||
0 1px 6px rgba(255, 255, 255, 0.10) inset;
|
||||
backdrop-filter: blur(12px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(12px) saturate(180%);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text);
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
padding: 4px var(--space-md);
|
||||
.header-glass-pill();
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
padding: 4px var(--space-md);
|
||||
.header-glass-pill();
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-indicator] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-secondary);
|
||||
white-space: nowrap;
|
||||
cursor: default;
|
||||
|
||||
&[data-style="active"] {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Theme toggle button ---- */
|
||||
.theme-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: var(--radius-sm);
|
||||
background: none;
|
||||
color: var(--color-text-secondary);
|
||||
cursor: pointer;
|
||||
transition: color var(--transition-fast);
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
|
||||
.theme-icon {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Show only the icon matching current theme */
|
||||
html[data-theme="auto"] .theme-icon-auto,
|
||||
html:not([data-theme]) .theme-icon-auto {
|
||||
display: block;
|
||||
}
|
||||
html[data-theme="light"] .theme-icon-light {
|
||||
display: block;
|
||||
}
|
||||
html[data-theme="dark"] .theme-icon-dark {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Floating variant for login page */
|
||||
.theme-toggle-float {
|
||||
position: fixed;
|
||||
top: var(--space-lg);
|
||||
right: var(--space-lg);
|
||||
z-index: var(--z-dropdown);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: var(--radius-md);
|
||||
.header-glass-pill();
|
||||
|
||||
.theme-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile hamburger */
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: var(--space-sm);
|
||||
margin-right: var(--space-md);
|
||||
color: var(--color-text);
|
||||
|
||||
svg {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Sub-navigation bar (CBI tabs) ---- */
|
||||
#header-sub {
|
||||
position: fixed;
|
||||
top: calc(var(--sidebar-gap) + 44px + 4px);
|
||||
left: calc(var(--sidebar-width) + var(--sidebar-gap) * 2);
|
||||
width: fit-content;
|
||||
max-width: calc(100vw - var(--sidebar-width) - var(--sidebar-gap) * 3);
|
||||
height: 2.25rem;
|
||||
z-index: var(--z-header);
|
||||
border-radius: var(--radius-md);
|
||||
display: none;
|
||||
align-items: center;
|
||||
padding: 3px 4px;
|
||||
gap: 2px;
|
||||
overflow-x: auto;
|
||||
transition: left var(--transition-slow);
|
||||
|
||||
/* Glass tab-list background — from glass-ui */
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.08),
|
||||
0 1px 4px rgba(0, 0, 0, 0.04),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.08) inset,
|
||||
0 0 12px rgba(255, 255, 255, 0.10) inset;
|
||||
|
||||
/* Hide scrollbar */
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
scrollbar-width: none;
|
||||
|
||||
&.active {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sub-nav tab items — glass-ui TabsTrigger pattern */
|
||||
.sub-tab {
|
||||
padding: 4px var(--space-md);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-secondary);
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
transition: background var(--transition-fast), color var(--transition-fast),
|
||||
box-shadow var(--transition-fast), backdrop-filter var(--transition-fast);
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--color-text);
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sub-tab slider — inset to match sub-tab content area */
|
||||
#header-sub > .tab-slider {
|
||||
border-radius: var(--radius-sm);
|
||||
top: 3px;
|
||||
bottom: 3px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* ---- Page transition ---- */
|
||||
@keyframes page-enter {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(12px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Main content area ---- */
|
||||
#content-wrap {
|
||||
margin-left: calc(var(--sidebar-width) + var(--sidebar-gap) * 2);
|
||||
margin-top: calc(44px + var(--sidebar-gap) * 2);
|
||||
min-height: calc(100vh - 44px - var(--sidebar-gap) * 2);
|
||||
padding: var(--content-padding);
|
||||
transition: margin-left var(--transition-slow);
|
||||
animation: page-enter 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
/* JS view content — fade in when LuCI replaces the spinner */
|
||||
#view > :not(.spinning) {
|
||||
animation: page-enter 0.25s cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||
}
|
||||
|
||||
/* Style LuCI's "Loading view..." spinner as a centered glass card */
|
||||
#view > .spinning {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
padding: var(--space-lg) var(--space-xl);
|
||||
border-radius: var(--radius-lg);
|
||||
.glass-effect();
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/* Fade-out before navigation */
|
||||
body.page-leaving #content-wrap {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
/* Push content down when sub-nav is visible */
|
||||
body.has-sub-nav #content-wrap {
|
||||
margin-top: calc(44px + 36px + var(--sidebar-gap) * 2 + 4px);
|
||||
}
|
||||
|
||||
#content {
|
||||
max-width: var(--content-max-width);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Mobile overlay */
|
||||
.sidebar-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: calc(var(--z-sidebar) - 1);
|
||||
opacity: 0;
|
||||
transition: opacity var(--transition-normal);
|
||||
|
||||
&.active {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Page title ---- */
|
||||
.page-title {
|
||||
margin-bottom: var(--space-xl);
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.page-description {
|
||||
margin-top: var(--space-xs);
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Footer ---- */
|
||||
.glass-footer {
|
||||
margin-left: calc(var(--sidebar-width) + var(--sidebar-gap) * 2);
|
||||
padding: var(--space-lg) var(--content-padding);
|
||||
text-align: right;
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
transition: margin-left var(--transition-slow);
|
||||
|
||||
a {
|
||||
color: var(--color-text-tertiary);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.footer-sep {
|
||||
margin: 0 var(--space-sm);
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/* ==========================================================================
|
||||
Normalize / Reset — luci-theme-glass
|
||||
Minimal reset for LuCI pages.
|
||||
========================================================================== */
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Glass scrollbar */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(128, 128, 128, 0.35) transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(128, 128, 128, 0.35);
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(128, 128, 128, 0.55);
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--color-text);
|
||||
background: var(--color-bg);
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-fast);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary-hover);
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea,
|
||||
button {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 0.5px solid var(--color-border);
|
||||
margin: var(--space-md) 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding-left: 1.5em;
|
||||
margin: var(--space-sm) 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
line-height: 1.25;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
h1 { font-size: var(--font-size-2xl); }
|
||||
h2 { font-size: var(--font-size-xl); }
|
||||
h3 { font-size: 1.125rem; }
|
||||
h4 { font-size: 1rem; }
|
||||
|
||||
::selection {
|
||||
background: rgba(var(--color-primary-rgb), 0.25);
|
||||
}
|
||||
|
||||
/* LuCI injects <input type="submit" class="hidden"> at the top of every
|
||||
CBI form. Without this rule the input renders as an unstyled browser
|
||||
button (seen in PassWall, OpenAppFilter, etc). Both bootstrap and argon
|
||||
themes ship this utility rule. */
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
/* ==========================================================================
|
||||
Page Fixes — LuCI-specific overrides and quirks
|
||||
========================================================================== */
|
||||
|
||||
/* LuCI wraps everything in #maincontent */
|
||||
#maincontent {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ---- Interface boxes (general) ---- */
|
||||
.ifacebox {
|
||||
.glass-effect();
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
border-radius: var(--radius-md);
|
||||
padding: 0;
|
||||
margin-bottom: var(--space-md);
|
||||
line-height: 1.25;
|
||||
overflow: visible;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.ifacebox-head {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
margin: 0;
|
||||
border-bottom: 0.5px solid var(--color-separator);
|
||||
|
||||
/* Zone-colored header — tinted glass instead of opaque */
|
||||
&[style*="background-color"] {
|
||||
background-color: rgba(var(--zone-color-rgb), 0.50) !important;
|
||||
border-radius: var(--radius-md) var(--radius-md) 0 0;
|
||||
backdrop-filter: blur(4px);
|
||||
-webkit-backdrop-filter: blur(4px);
|
||||
border-bottom: 0.5px solid rgba(var(--zone-color-rgb), 0.20);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.20);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(var(--color-primary-rgb), 0.75) 0%,
|
||||
rgba(var(--color-primary-rgb), 0.60) 50%,
|
||||
rgba(var(--color-primary-rgb), 0.70) 100%
|
||||
);
|
||||
color: var(--color-text-inverse);
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
border-bottom: none;
|
||||
backdrop-filter: blur(4px);
|
||||
-webkit-backdrop-filter: blur(4px);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.20),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
.ifacebox-body {
|
||||
line-height: 1.5;
|
||||
font-size: var(--font-size-sm);
|
||||
padding: var(--space-sm) var(--space-lg) var(--space-lg);
|
||||
|
||||
/* L.itemlist output — key-value pairs */
|
||||
> span {
|
||||
display: block;
|
||||
padding: var(--space-xs) 0;
|
||||
|
||||
> .nowrap {
|
||||
display: inline-block;
|
||||
margin-right: var(--space-md);
|
||||
margin-bottom: 2px;
|
||||
|
||||
> strong {
|
||||
color: var(--color-text-secondary);
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Device badge row */
|
||||
> div {
|
||||
margin-top: var(--space-sm);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Port status grid (29_ports.js) ---- */
|
||||
div[style*="display:grid;grid-template-columns:repeat"] {
|
||||
gap: var(--space-md) !important;
|
||||
margin-bottom: var(--space-lg) !important;
|
||||
|
||||
> .ifacebox {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
border-radius: var(--radius-md) !important;
|
||||
/* Glass-ui card pattern */
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
) !important;
|
||||
background-color: transparent !important;
|
||||
backdrop-filter: blur(10px) saturate(180%) !important;
|
||||
-webkit-backdrop-filter: blur(10px) saturate(180%) !important;
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12) !important;
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.08),
|
||||
0 1px 4px rgba(0, 0, 0, 0.04),
|
||||
0 0 0 0.5px rgba(255, 255, 255, 0.08) inset,
|
||||
0 0 12px rgba(255, 255, 255, 0.10) inset !important;
|
||||
|
||||
> .ifacebox-head {
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
> .ifacebox-body {
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: 1.3;
|
||||
|
||||
img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin: 2px auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zone color bar */
|
||||
> .ifacebox-head.cbi-tooltip-container {
|
||||
padding: 0;
|
||||
border-bottom: none;
|
||||
|
||||
.zonebadge {
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Network status table (30_network.js) ---- */
|
||||
.network-status-table {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-md);
|
||||
|
||||
.ifacebox {
|
||||
flex: 1 1 300px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ifacebox-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
.ifacebadge {
|
||||
flex: 1 1 auto;
|
||||
min-width: 200px;
|
||||
|
||||
> span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Interface badges ---- */
|
||||
.ifacebadge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-xs);
|
||||
padding: 2px var(--space-sm);
|
||||
margin-right: 0.4em;
|
||||
min-width: max-content;
|
||||
background: rgba(255, 255, 255, 0.40);
|
||||
backdrop-filter: blur(8px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(8px) saturate(180%);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.20);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.30),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.08);
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zone badges */
|
||||
.zonebadge {
|
||||
display: inline-block;
|
||||
padding: 2px var(--space-sm);
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(6px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(6px) saturate(160%);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.20),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.zonebadge .ifacebadge {
|
||||
margin: 1px 2px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
/* ---- Tooltips ---- */
|
||||
.cbi-tooltip-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cbi-tooltip {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: var(--z-toast);
|
||||
left: 0;
|
||||
bottom: 100%;
|
||||
margin-bottom: var(--space-xs);
|
||||
.glass-effect();
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
font-size: var(--font-size-sm);
|
||||
max-width: 300px;
|
||||
white-space: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
&.left {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cbi-tooltip-container:hover > .cbi-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* System log */
|
||||
#syslog {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Terminal / command output */
|
||||
pre {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
overflow-x: auto;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
/* Flatten pre inside modals — avoid box-in-box */
|
||||
.modal pre {
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
padding: var(--space-sm) 0;
|
||||
}
|
||||
|
||||
/* Native progress element (package manager, etc.) */
|
||||
progress {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
border: none;
|
||||
border-radius: var(--radius-full);
|
||||
overflow: hidden;
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
&::-webkit-progress-value {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(var(--color-primary-rgb), 0.75) 0%,
|
||||
rgba(var(--color-primary-rgb), 0.60) 50%,
|
||||
rgba(var(--color-primary-rgb), 0.70) 100%
|
||||
);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
|
||||
&::-moz-progress-bar {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(var(--color-primary-rgb), 0.75) 0%,
|
||||
rgba(var(--color-primary-rgb), 0.60) 50%,
|
||||
rgba(var(--color-primary-rgb), 0.70) 100%
|
||||
);
|
||||
border-radius: var(--radius-full);
|
||||
}
|
||||
}
|
||||
|
||||
/* ACL/UBUS error page styling */
|
||||
#error-message {
|
||||
text-align: center;
|
||||
padding: var(--space-3xl);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* LuCI diagnostics ping/traceroute output */
|
||||
#diag-rc-output {
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.06),
|
||||
0 1px 2px rgba(0, 0, 0, 0.03),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.30),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* File upload */
|
||||
.cbi-filebrowser {
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.06),
|
||||
0 1px 2px rgba(0, 0, 0, 0.03),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.30),
|
||||
inset 0 0 6px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* Apply config spinner */
|
||||
#cbi_apply_overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.25);
|
||||
z-index: var(--z-overlay);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#cbi_apply_overlay .spinning {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding-left: 0 !important;
|
||||
border: 3px solid var(--color-bg-secondary);
|
||||
border-top-color: var(--color-primary);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Utility classes ---- */
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.hide-xs {
|
||||
@media (max-width: 640px) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Standalone section headings (DHCP, WiFi assoclist) ---- */
|
||||
#maincontent h3,
|
||||
#view h3 {
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
margin: var(--space-xl) 0 var(--space-md);
|
||||
}
|
||||
|
||||
/* ---- Table sort indicators ---- */
|
||||
.th[data-sort-direction] {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: var(--space-xs);
|
||||
vertical-align: middle;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
}
|
||||
|
||||
&[data-sort-direction="asc"]::after {
|
||||
border-bottom: 5px solid var(--color-text-secondary);
|
||||
}
|
||||
|
||||
&[data-sort-direction="desc"]::after {
|
||||
border-top: 5px solid var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.th[data-sortable-row] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ---- Table placeholder (empty state) ---- */
|
||||
.tr.placeholder .td {
|
||||
text-align: center;
|
||||
padding: var(--space-2xl) var(--space-lg);
|
||||
color: var(--color-text-tertiary);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* ---- Software / Package Manager page ---- */
|
||||
[data-page="admin-system-opkg"],
|
||||
[data-page="admin-system-package-manager"] {
|
||||
/* Action buttons — glass pill style */
|
||||
div.btn {
|
||||
display: inline-flex;
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
}
|
||||
|
||||
/* Override opkg.js inline CSS for controls layout */
|
||||
.controls {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
justify-content: flex-start !important;
|
||||
gap: var(--space-md) var(--space-lg) !important;
|
||||
margin: 0 0 var(--space-lg) 0 !important;
|
||||
}
|
||||
|
||||
/* All control sections — override inline flex: 1 1 33% */
|
||||
.controls > div {
|
||||
padding: 0 !important;
|
||||
white-space: normal !important;
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
align-items: flex-end !important;
|
||||
}
|
||||
|
||||
/* Disk space — full width row */
|
||||
.controls > div:first-child {
|
||||
flex: 1 1 100% !important;
|
||||
}
|
||||
|
||||
/* Filter — share row, grow equally */
|
||||
.controls > div:nth-child(2) {
|
||||
flex: 1 1 200px !important;
|
||||
}
|
||||
|
||||
/* Download / install — share row, grow equally */
|
||||
.controls > div:nth-child(3) {
|
||||
flex: 1 1 280px !important;
|
||||
}
|
||||
|
||||
/* Actions — own row */
|
||||
.controls > div:nth-child(4) {
|
||||
flex: 1 1 100% !important;
|
||||
}
|
||||
|
||||
/* Translation filter — own row */
|
||||
.controls > div:nth-child(5) {
|
||||
flex: 1 1 100% !important;
|
||||
}
|
||||
|
||||
/* Labels — block above their control group */
|
||||
.controls > div > label {
|
||||
flex-basis: 100% !important;
|
||||
min-width: 0 !important;
|
||||
margin-bottom: var(--space-xs) !important;
|
||||
font-weight: var(--font-weight-medium) !important;
|
||||
font-size: var(--font-size-sm) !important;
|
||||
color: var(--color-text-secondary) !important;
|
||||
}
|
||||
|
||||
/* Control groups — input + button inline */
|
||||
.controls .control-group {
|
||||
display: flex !important;
|
||||
gap: var(--space-sm) !important;
|
||||
flex: 1 1 auto !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
.controls .control-group input[type="text"] {
|
||||
flex: 1 1 auto !important;
|
||||
min-width: 120px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
/* Action buttons — inline row with gap */
|
||||
.controls > div:nth-child(4) > .control-group {
|
||||
gap: var(--space-sm) !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ==========================================================================
|
||||
Responsive — Media queries for tablet & mobile
|
||||
========================================================================== */
|
||||
|
||||
/* Tablet: sidebar overlay */
|
||||
@media (max-width: 1024px) {
|
||||
#sidebar {
|
||||
transform: translateX(calc(-100% - var(--sidebar-gap)));
|
||||
|
||||
&.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
#header {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#header-sub {
|
||||
left: 0;
|
||||
max-width: calc(100vw - var(--sidebar-gap));
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.glass-footer {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sidebar-overlay.active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide status indicators on small screens */
|
||||
@media (max-width: 768px) {
|
||||
#status-indicators {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile: tighter spacing */
|
||||
@media (max-width: 640px) {
|
||||
:root {
|
||||
--content-padding: 16px;
|
||||
--sidebar-width: 280px;
|
||||
}
|
||||
|
||||
.cbi-value {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cbi-value-title {
|
||||
flex: none;
|
||||
padding-right: 0;
|
||||
padding-bottom: var(--space-xs);
|
||||
}
|
||||
|
||||
.cbi-page-actions {
|
||||
flex-direction: column;
|
||||
|
||||
.cbi-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: var(--space-2xl) var(--space-xl);
|
||||
}
|
||||
|
||||
.cbi-tabmenu {
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
li a {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
table.cbi-section-table,
|
||||
.table {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/* ==========================================================================
|
||||
Login Page (sysauth) — luci-theme-glass
|
||||
========================================================================== */
|
||||
|
||||
.login-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
padding: var(--space-xl);
|
||||
}
|
||||
|
||||
.login-card {
|
||||
/* True frosted glass — translucent, not white box */
|
||||
background-image: linear-gradient(
|
||||
160deg,
|
||||
rgba(255, 255, 255, 0.25) 0%,
|
||||
rgba(255, 255, 255, 0.20) 25%,
|
||||
rgba(245, 250, 255, 0.22) 50%,
|
||||
rgba(255, 255, 255, 0.18) 75%,
|
||||
rgba(240, 248, 255, 0.21) 100%
|
||||
);
|
||||
background-color: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
-webkit-backdrop-filter: blur(30px) saturate(var(--glass-saturate));
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.35);
|
||||
box-shadow:
|
||||
0 8px 40px rgba(0, 0, 0, 0.10),
|
||||
0 2px 8px rgba(0, 0, 0, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.50),
|
||||
inset 0 0 16px rgba(255, 255, 255, 0.15);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: var(--space-3xl) var(--space-2xl);
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-logo {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin: 0 auto var(--space-lg);
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: var(--font-size-xl);
|
||||
font-weight: var(--font-weight-bold);
|
||||
margin-bottom: var(--space-xs);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.login-subtitle {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-secondary);
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
.login-version {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-tertiary);
|
||||
margin-bottom: var(--space-2xl);
|
||||
}
|
||||
|
||||
.login-form {
|
||||
text-align: left;
|
||||
|
||||
.login-field {
|
||||
margin-bottom: var(--space-lg);
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-secondary);
|
||||
margin-bottom: var(--space-xs);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
background: rgba(255, 255, 255, 0.30);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.35);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--color-text);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
box-shadow:
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.25),
|
||||
inset 0 0 4px rgba(255, 255, 255, 0.08);
|
||||
transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(var(--color-primary-rgb), 0.15),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
/* Glass button — glass-ui .glass-bg pattern */
|
||||
background-image: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.15) 0%,
|
||||
rgba(255, 255, 255, 0.12) 25%,
|
||||
rgba(240, 248, 255, 0.13) 50%,
|
||||
rgba(255, 255, 255, 0.11) 75%,
|
||||
rgba(230, 240, 255, 0.12) 100%
|
||||
);
|
||||
background-color: transparent;
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.08),
|
||||
0 1px 4px rgba(0, 0, 0, 0.04),
|
||||
inset 0 0 0.5px rgba(255, 255, 255, 0.08),
|
||||
inset 0 0 12px rgba(255, 255, 255, 0.10);
|
||||
color: var(--color-text);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.90;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.80;
|
||||
box-shadow:
|
||||
inset 0 2px 4px rgba(0, 0, 0, 0.15),
|
||||
inset 0 1px 2px rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
}
|
||||
|
||||
.login-error {
|
||||
background: rgba(255, 59, 48, 0.10);
|
||||
border: 1px solid rgba(255, 59, 48, 0.30);
|
||||
color: var(--color-danger);
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-sm);
|
||||
margin-bottom: var(--space-lg);
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/* ==========================================================================
|
||||
Design Tokens — luci-theme-glass
|
||||
All CSS custom properties live here for easy theming.
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
/* ---- Typography ---- */
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue",
|
||||
"Segoe UI", Roboto, "Noto Sans", sans-serif;
|
||||
--font-mono: "SF Mono", SFMono-Regular, ui-monospace, Menlo, Consolas,
|
||||
"Liberation Mono", monospace;
|
||||
--font-size-base: 0.875rem;
|
||||
--font-size-sm: 0.8125rem;
|
||||
--font-size-lg: 1rem;
|
||||
--font-size-xl: 1.25rem;
|
||||
--font-size-2xl: 1.75rem;
|
||||
--line-height: 1.5;
|
||||
--font-weight-normal: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-semibold: 600;
|
||||
--font-weight-bold: 700;
|
||||
|
||||
/* ---- Colors — Light mode ---- */
|
||||
--color-primary: #007AFF;
|
||||
--color-primary-hover: #0066d6;
|
||||
--color-primary-active: #004fad;
|
||||
--color-primary-rgb: 0, 122, 255;
|
||||
|
||||
--color-success: #34C759;
|
||||
--color-warning: #FF9500;
|
||||
--color-danger: #FF3B30;
|
||||
--color-info: #5AC8FA;
|
||||
|
||||
--color-text: #1d1d1f;
|
||||
--color-text-secondary: #6e6e73;
|
||||
--color-text-tertiary: #aeaeb2;
|
||||
--color-text-inverse: #ffffff;
|
||||
|
||||
--color-bg: #f5f5f7;
|
||||
--color-bg-elevated: #ffffff;
|
||||
--color-bg-secondary: #e8e8ed;
|
||||
|
||||
--color-border: rgba(0, 0, 0, 0.08);
|
||||
--color-border-strong: rgba(0, 0, 0, 0.16);
|
||||
--color-separator: rgba(60, 60, 67, 0.12);
|
||||
|
||||
/* ---- Glassmorphism ---- */
|
||||
--glass-blur: 20px;
|
||||
--glass-saturate: 180%;
|
||||
--glass-bg: rgba(255, 255, 255, 0.72);
|
||||
--glass-bg-hover: rgba(255, 255, 255, 0.82);
|
||||
--glass-bg-strong: rgba(255, 255, 255, 0.85);
|
||||
--glass-border: rgba(255, 255, 255, 0.45);
|
||||
--glass-shadow: 0 2px 16px rgba(0, 0, 0, 0.06),
|
||||
0 0 1px rgba(0, 0, 0, 0.08);
|
||||
--glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.10),
|
||||
0 0 1px rgba(0, 0, 0, 0.06);
|
||||
|
||||
/* ---- Layout ---- */
|
||||
--sidebar-width: 260px;
|
||||
--sidebar-collapsed-width: 64px;
|
||||
--sidebar-gap: 10px;
|
||||
--header-height: 56px;
|
||||
--content-max-width: none;
|
||||
--content-padding: 24px;
|
||||
|
||||
/* ---- Radius ---- */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 10px;
|
||||
--radius-lg: 14px;
|
||||
--radius-xl: 20px;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* ---- Spacing ---- */
|
||||
--space-xs: 4px;
|
||||
--space-sm: 8px;
|
||||
--space-md: 12px;
|
||||
--space-lg: 16px;
|
||||
--space-xl: 24px;
|
||||
--space-2xl: 32px;
|
||||
--space-3xl: 48px;
|
||||
|
||||
/* ---- Transitions ---- */
|
||||
--transition-fast: 0.15s ease;
|
||||
--transition-normal: 0.25s ease;
|
||||
--transition-slow: 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
|
||||
/* ---- Z-index ---- */
|
||||
--z-dropdown: 100;
|
||||
--z-sticky: 200;
|
||||
--z-sidebar: 300;
|
||||
--z-header: 400;
|
||||
--z-overlay: 500;
|
||||
--z-modal: 600;
|
||||
--z-toast: 700;
|
||||
|
||||
/* ---- Background ---- */
|
||||
--bg-gradient: linear-gradient(135deg, #b8c4d0 0%, #d5dce5 50%, #ddd5cc 100%);
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: de\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Zum Fortfahren anmelden"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,242 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Poedit 3.8\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr "Colores de acento"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
"Color de acento utilizado para elementos activos, enlaces y botones en el "
|
||||
"modo oscuro."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
"Color de acento utilizado para elementos activos, enlaces y botones en el "
|
||||
"modo claro."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr "Activo"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr "Automático (seguir el del sistema)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr "Radio de desenfoque del fondo para paneles de cristal en modo oscuro."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
"Radio de desenfoque del fondo para paneles de cristal. Los valores más altos "
|
||||
"crean una apariencia más esmerilada."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr "Fondo"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
"Opacidad de fondo de los paneles de cristal (0 = totalmente transparente, 1 "
|
||||
"= totalmente opaco)."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
"Opacidad de fondo de los paneles de cristal en modo oscuro (0 = totalmente "
|
||||
"transparente, 1 = totalmente opaco)."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr "Tamaño de fuente base"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr "Intensidad del desenfoque (px)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
"Configure la apariencia del tema Glass. Los cambios surtirán efecto después "
|
||||
"de guardar y actualizar la página."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
"Controla la apariencia general. La opción «Normal» respeta la preferencia "
|
||||
"del sistema."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr "Fondo actual"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr "Oscuro"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr "Extra grande (18px)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr "Efectos de vidrio - Modo oscuro"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr "Efectos de vidrio - Modo claro"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr "Tema Glass"
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr "Configuración de Glass"
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr "Ir a la configuración de contraseñas..."
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr "Conceder acceso para luci-theme-glass"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr "Barra de estado del encabezado"
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr "Nombre de usuario y/o contraseña incorrectos. Inténtelo de nuevo."
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr "¡Se requiere JavaScript!"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr "Grande (16px)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr "Claro"
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr "Iniciar sesión"
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr "Acceso"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
"No se ha configurado ningún fondo. Cargue una imagen o video llamado \"bg\" "
|
||||
"(por ejemplo, bg.jpg, bg.png, bg.mp4) a /www/luci-static/glass/background/ a "
|
||||
"través de SCP."
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr "¡No se ha establecido ninguna contraseña!"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr "Normal (14px)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr "Transparencia del panel"
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr "Color principal (modo oscuro)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr "Color principal (modo claro)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
"Ajusta el tamaño de todo el texto del tema. Los valores mayores mejoran la "
|
||||
"legibilidad en pantallas de alta resolución."
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
"Muestra estadísticas del sistema en tiempo real (CPU, RAM, red, tiempo de "
|
||||
"actividad) en el encabezado. Desactive para reducir el consumo de recursos "
|
||||
"en dispositivos de gama baja."
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Inicia sesión para continuar"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr "Pequeño (13px)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr "Modo del tema"
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
"Este enrutador no tiene contraseña. Configure una contraseña de "
|
||||
"administrador para proteger la interfaz web."
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr "Nombre de usuario"
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
"Debe activar JavaScript en su navegador o LuCI no funcionará correctamente."
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: fr\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Connectez-vous pour continuer"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: ja\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "続行するにはサインインしてください"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: ko\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "계속하려면 로그인하세요"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: pt_BR\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Faça login para continuar"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: ru\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "Войдите для продолжения"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,206 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1 @@
|
||||
zh_Hans
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: zh_Hans\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "登录以继续"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,209 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Language: zh_Hant\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:52
|
||||
msgid "Accent Colors"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:72
|
||||
msgid "Accent color used for active elements, links, and buttons in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:56
|
||||
msgid ""
|
||||
"Accent color used for active elements, links, and buttons in light mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:128
|
||||
msgid "Active"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:33
|
||||
msgid "Auto (follow system)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:108
|
||||
msgid "Backdrop blur radius for glass panels in dark mode."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:92
|
||||
msgid ""
|
||||
"Backdrop blur radius for glass panels. Higher values create a more frosted "
|
||||
"appearance."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:120
|
||||
msgid "Background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:98
|
||||
msgid ""
|
||||
"Background opacity of glass panels (0 = fully transparent, 1 = fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:114
|
||||
msgid ""
|
||||
"Background opacity of glass panels in dark mode (0 = fully transparent, 1 = "
|
||||
"fully opaque)."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:43
|
||||
msgid "Base font size"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:91
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:107
|
||||
msgid "Blur intensity (px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:25
|
||||
msgid ""
|
||||
"Configure the appearance of the Glass theme. Changes take effect after "
|
||||
"saving and refreshing the page."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:32
|
||||
msgid ""
|
||||
"Controls the overall appearance. \"Normal\" follows the system preference."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:123
|
||||
msgid "Current background"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:35
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:48
|
||||
msgid "Extra Large (18px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:28
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:104
|
||||
msgid "Glass Effects — Dark Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:88
|
||||
msgid "Glass Effects — Light Mode"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:24
|
||||
msgid "Glass Theme"
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/luci/menu.d/luci-theme-glass.json:3
|
||||
msgid "Glass Theme Config"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:204
|
||||
msgid "Go to password configuration..."
|
||||
msgstr ""
|
||||
|
||||
#: root/usr/share/rpcd/acl.d/luci-theme-glass.json:3
|
||||
msgid "Grant access for luci-theme-glass"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:38
|
||||
msgid "Header status bar"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:111
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:211
|
||||
msgid "JavaScript required!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:47
|
||||
msgid "Large (16px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:34
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:129
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:51
|
||||
msgid "Login"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:131
|
||||
msgid ""
|
||||
"No background set. Upload an image or video named \"bg\" (e.g. bg.jpg, "
|
||||
"bg.png, bg.mp4) to /www/luci-static/glass/background/ via SCP."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:201
|
||||
msgid "No password set!"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:46
|
||||
msgid "Normal (14px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:97
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:113
|
||||
msgid "Panel transparency"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:124
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:71
|
||||
msgid "Primary color (dark mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:55
|
||||
msgid "Primary color (light mode)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:44
|
||||
msgid ""
|
||||
"Scales all text in the theme. Larger values improve readability on high-DPI "
|
||||
"displays."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:39
|
||||
msgid ""
|
||||
"Show live system stats (CPU, RAM, network, uptime) in the header. Disable to "
|
||||
"reduce resource usage on low-end devices."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:106
|
||||
msgid "Sign in to continue"
|
||||
msgstr "登入以繼續"
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:45
|
||||
msgid "Small (13px)"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/system/glass.js:31
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:202
|
||||
msgid ""
|
||||
"There is no password set on this router. Please configure a root password to "
|
||||
"protect the web interface."
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/sysauth.ut:117
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: ucode/template/themes/glass/header.ut:212
|
||||
msgid ""
|
||||
"You must enable JavaScript in your browser or LuCI will not work properly."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsUzec0+6lptCFX88129L
|
||||
y7dDRwWkVL8tBIBwh67C2o54DN2AWgUkmuwnoZa+6UMtHFkyi8GLpw2ISNjiKzJn
|
||||
GU8G21rg288OIQthhYIWVM3+eQ4J3yMA/r/1JQV80IDZ/awdfPRCjQQoJN96d5Km
|
||||
gvKZeDp0UjcoD+gUy8S3LzCTNUwwjd9vnEZDTz1d+NckNM4JTTR1d+WFTwSeNAcE
|
||||
jN/pNPPB/oyiUfyKLYHiDrBZputcnQ2suHC/DIVUSTQNhAyAst9UnUO3Jhv298HE
|
||||
OrAhUZnwVC9F788Er+9mZAGpcqpPhZ+UDztOoO/aVt56ire/MBGLDkwYVN2W5wCo
|
||||
QwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,10 @@
|
||||
config global 'global'
|
||||
option mode 'normal'
|
||||
option primary '#007AFF'
|
||||
option dark_primary '#0A84FF'
|
||||
option blur '20'
|
||||
option transparency '0.72'
|
||||
option blur_dark '25'
|
||||
option transparency_dark '0.30'
|
||||
option status_bar '1'
|
||||
option font_size '14'
|
||||
@@ -0,0 +1,2 @@
|
||||
untrusted comment: luci-theme-glass package signing key public key
|
||||
RWTvl8Ror3fOoUBhvj1JRuc+0SQ/8vIDJNCPrSXN5UNQJRGizXf/rxX/
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Always keep Glass in the theme list so it remains selectable in LuCI
|
||||
uci -q set luci.themes.Glass=/luci-static/glass
|
||||
|
||||
# Set as default only on fresh install -- don't stomp user choice on upgrade
|
||||
[ "$PKG_UPGRADE" = 1 ] || uci -q set luci.main.mediaurlbase=/luci-static/glass
|
||||
|
||||
uci -q commit luci
|
||||
rm -f /tmp/luci-indexcache /tmp/luci-modulecache
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"admin/system/glass": {
|
||||
"title": "Glass Theme Config",
|
||||
"order": 90,
|
||||
"action": {
|
||||
"type": "view",
|
||||
"path": "system/glass"
|
||||
},
|
||||
"depends": {
|
||||
"acl": [
|
||||
"luci-theme-glass"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"luci-theme-glass": {
|
||||
"description": "Grant access for luci-theme-glass",
|
||||
"read": {
|
||||
"uci": [ "glass" ],
|
||||
"file": {
|
||||
"/www/luci-static/glass/background/*": [ "list" ]
|
||||
},
|
||||
"ubus": {
|
||||
"network.interface": [ "dump" ],
|
||||
"network.device": [ "status" ]
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "glass" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 1.7 MiB |
@@ -0,0 +1,185 @@
|
||||
{# luci-theme-glass — Main page footer template #}
|
||||
{%
|
||||
import { readfile, access } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
const glass_version = trim(readfile('/usr/share/ucode/luci/template/themes/glass/version')) ?? '?';
|
||||
let glass_status_bar = '1';
|
||||
let _cfg = cursor();
|
||||
if (access('/etc/config/glass')) {
|
||||
glass_status_bar = _cfg.get_first('glass', 'global', 'status_bar') ?? '1';
|
||||
}
|
||||
%}
|
||||
{% if (!blank_page): %}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="glass-footer">
|
||||
<span>GlassTheme v{{ glass_version }}</span>
|
||||
<span class="footer-sep">|</span>
|
||||
<a href="https://github.com/openwrt/luci" target="_blank">{{ version.luciname }} ({{ version.luciversion }})</a>
|
||||
<span class="footer-sep">|</span>
|
||||
<a href="{{ version.disturl }}" target="_blank">{{ version.distname }} {{ version.distversion }}</a>
|
||||
</footer>
|
||||
|
||||
<script src="{{ resource }}/luci.js"></script>
|
||||
<script>
|
||||
L.require('menu-glass');
|
||||
{% if (glass_status_bar == '1'): %}
|
||||
L.require('status-glass');
|
||||
{% endif %}
|
||||
|
||||
if (history.scrollRestoration) history.scrollRestoration = 'manual';
|
||||
|
||||
(function() {
|
||||
var toggle = document.getElementById('menu-toggle');
|
||||
var sidebar = document.getElementById('sidebar');
|
||||
var overlay = document.getElementById('sidebar-overlay');
|
||||
|
||||
function openSidebar() {
|
||||
sidebar.classList.add('open');
|
||||
overlay.classList.add('active');
|
||||
}
|
||||
|
||||
function closeSidebar() {
|
||||
sidebar.classList.remove('open');
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
|
||||
if (toggle) toggle.addEventListener('click', function() {
|
||||
sidebar.classList.contains('open') ? closeSidebar() : openSidebar();
|
||||
});
|
||||
|
||||
if (overlay) overlay.addEventListener('click', closeSidebar);
|
||||
})();
|
||||
|
||||
/* Theme toggle — auto / light / dark cycle */
|
||||
(function(){
|
||||
var btn=document.getElementById('theme-toggle');
|
||||
if(!btn)return;
|
||||
var order=['auto','light','dark'];
|
||||
var labels={auto:'Theme: Auto',light:'Theme: Light',dark:'Theme: Dark'};
|
||||
var cur=document.documentElement.dataset.theme||'auto';
|
||||
btn.title=labels[cur];btn.setAttribute('aria-label',labels[cur]);
|
||||
btn.addEventListener('click',function(){
|
||||
var cur=document.documentElement.dataset.theme||'auto';
|
||||
var next=order[(order.indexOf(cur)+1)%3];
|
||||
document.documentElement.dataset.theme=next;
|
||||
try{localStorage.setItem('glass-theme',next)}catch(e){}
|
||||
var d=document.getElementById('dark-styles'),m=document.getElementById('meta-theme-color');
|
||||
if(next==='dark'){d.media='all';if(m)m.content='#2c2e3a'}
|
||||
else if(next==='light'){d.media='not all';if(m)m.content='#f5f5f7'}
|
||||
else{d.media='(prefers-color-scheme: dark)';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
btn.title=labels[next];btn.setAttribute('aria-label',labels[next]);
|
||||
});
|
||||
/* Update theme-color meta when OS changes in auto mode */
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change',function(e){
|
||||
if(document.documentElement.dataset.theme!=='auto')return;
|
||||
var m=document.getElementById('meta-theme-color');
|
||||
if(m)m.content=e.matches?'#2c2e3a':'#f5f5f7';
|
||||
});
|
||||
})();
|
||||
|
||||
/* Move CBI tabmenus into sub-nav bar; attach descriptions as tooltips */
|
||||
(function() {
|
||||
var headerSub = document.getElementById('header-sub');
|
||||
var headerTitle = document.getElementById('header-title');
|
||||
var content = document.getElementById('maincontent');
|
||||
if (!content) return;
|
||||
|
||||
function processContent() {
|
||||
/* Attach page description as tooltip on header title */
|
||||
if (headerTitle && !headerTitle.title) {
|
||||
var descr = content.querySelector('.cbi-map-descr');
|
||||
if (descr && !descr.dataset.moved) {
|
||||
descr.dataset.moved = '1';
|
||||
headerTitle.title = descr.textContent.trim();
|
||||
}
|
||||
}
|
||||
|
||||
/* Move top-level CBI tabmenus into sub-nav bar.
|
||||
Skip if renderTabMenu already populated header-sub (menu-tree tabs).
|
||||
Nested tabmenus (e.g. DNS Records sub-tabs inside a tab panel)
|
||||
stay in-content so they don't get mixed with top-level tabs. */
|
||||
if (!headerSub) return;
|
||||
if (headerSub.querySelector('.sub-tab')) return; /* Already has menu-tree tabs */
|
||||
var allTabmenus = content.querySelectorAll('.cbi-tabmenu');
|
||||
if (allTabmenus.length === 0) return;
|
||||
|
||||
/* Only move the first CBI tabmenu to sub-nav.
|
||||
Any deeper tabmenus (e.g. DNS Records sub-tabs, dnsmasq section tabs)
|
||||
stay in-content with glass styling. */
|
||||
var topTabmenus = [allTabmenus[0]];
|
||||
if (!topTabmenus[0]) return;
|
||||
|
||||
/* Skip rebuild if we're in the middle of a tab click */
|
||||
if (headerSub._switching) return;
|
||||
|
||||
/* Clear existing sub-tabs to prevent duplicates on re-render (Save & Apply) */
|
||||
headerSub.innerHTML = '';
|
||||
headerSub.classList.remove('active');
|
||||
document.body.classList.remove('has-sub-nav');
|
||||
|
||||
/* Sliding selector for sub-tabs */
|
||||
var slider = document.createElement('div');
|
||||
slider.className = 'tab-slider';
|
||||
headerSub.appendChild(slider);
|
||||
|
||||
topTabmenus.forEach(function(ul) {
|
||||
var items = ul.querySelectorAll('li');
|
||||
items.forEach(function(li) {
|
||||
var a = li.querySelector('a');
|
||||
if (!a) return;
|
||||
/* Skip hidden tabs (e.g. DNSSEC when not available) */
|
||||
if (li.style.display === 'none') return;
|
||||
var tab = a.cloneNode(true);
|
||||
tab.className = 'sub-tab' + (li.classList.contains('cbi-tab') ? ' active' : '');
|
||||
tab.addEventListener('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
/* Guard: prevent MutationObserver from rebuilding during tab switch */
|
||||
headerSub._switching = true;
|
||||
a.click();
|
||||
setTimeout(function() { headerSub._switching = false; }, 100);
|
||||
headerSub.querySelectorAll('.sub-tab').forEach(function(t) {
|
||||
t.classList.remove('active');
|
||||
});
|
||||
tab.classList.add('active');
|
||||
/* Slide to clicked tab */
|
||||
slider.style.left = tab.offsetLeft + 'px';
|
||||
slider.style.width = tab.offsetWidth + 'px';
|
||||
slider.style.opacity = '1';
|
||||
});
|
||||
headerSub.appendChild(tab);
|
||||
});
|
||||
|
||||
ul.style.display = 'none';
|
||||
});
|
||||
|
||||
headerSub.classList.add('active');
|
||||
document.body.classList.add('has-sub-nav');
|
||||
|
||||
/* Position slider on active sub-tab */
|
||||
requestAnimationFrame(function() {
|
||||
var active = headerSub.querySelector('.sub-tab.active');
|
||||
if (active) {
|
||||
slider.style.transition = 'none';
|
||||
slider.style.left = active.offsetLeft + 'px';
|
||||
slider.style.width = active.offsetWidth + 'px';
|
||||
slider.style.opacity = '1';
|
||||
requestAnimationFrame(function() {
|
||||
slider.style.transition = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
processContent();
|
||||
new MutationObserver(function() {
|
||||
processContent();
|
||||
}).observe(content, { childList: true, subtree: true });
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
||||
{% if (js): %}<script>{{ js }}</script>{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
{# luci-theme-glass — Login page footer (empty, sysauth.ut is self-contained) #}
|
||||
@@ -0,0 +1,215 @@
|
||||
{#
|
||||
luci-theme-glass — Main page header template
|
||||
Apple-inspired glassmorphism theme for LuCI
|
||||
-#}
|
||||
|
||||
{%
|
||||
import { readfile, access } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
import { getuid, getspnam } from 'luci.core';
|
||||
|
||||
const glass_version = trim(readfile('/usr/share/ucode/luci/template/themes/glass/version')) ?? '?';
|
||||
const boardinfo = ubus.call('system', 'board');
|
||||
const hostname = striptags(boardinfo?.hostname ?? 'OpenWrt');
|
||||
|
||||
http.prepare_content('text/html; charset=UTF-8');
|
||||
|
||||
/* Read theme config */
|
||||
let glass_mode = 'normal';
|
||||
let glass_primary = '#007AFF';
|
||||
let glass_dark_primary = '#0A84FF';
|
||||
let glass_blur = '20';
|
||||
let glass_transparency = '0.72';
|
||||
let glass_blur_dark = '25';
|
||||
let glass_transparency_dark = '0.30';
|
||||
let glass_font_size = '14';
|
||||
|
||||
let cfg = cursor();
|
||||
if (access('/etc/config/glass')) {
|
||||
glass_mode = cfg.get_first('glass', 'global', 'mode') ?? glass_mode;
|
||||
glass_primary = cfg.get_first('glass', 'global', 'primary') ?? glass_primary;
|
||||
glass_dark_primary = cfg.get_first('glass', 'global', 'dark_primary') ?? glass_dark_primary;
|
||||
glass_blur = cfg.get_first('glass', 'global', 'blur') ?? glass_blur;
|
||||
glass_transparency = cfg.get_first('glass', 'global', 'transparency') ?? glass_transparency;
|
||||
glass_blur_dark = cfg.get_first('glass', 'global', 'blur_dark') ?? glass_blur_dark;
|
||||
glass_transparency_dark = cfg.get_first('glass', 'global', 'transparency_dark') ?? glass_transparency_dark;
|
||||
glass_font_size = cfg.get_first('glass', 'global', 'font_size') ?? glass_font_size;
|
||||
}
|
||||
|
||||
/* Read dark.css for inline injection */
|
||||
const dark_css = readfile('/www/luci-static/glass/css/dark.css');
|
||||
|
||||
/* Find background media */
|
||||
let bg_src = null;
|
||||
let bg_type = 'image';
|
||||
const bg_dir = '/www/luci-static/glass/background';
|
||||
const img_exts = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
||||
const vid_exts = ['.mp4', '.webm'];
|
||||
|
||||
for (let ext in img_exts) {
|
||||
if (access(bg_dir + '/bg' + ext)) {
|
||||
bg_src = media + '/background/bg' + ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bg_src) {
|
||||
for (let ext in vid_exts) {
|
||||
if (access(bg_dir + '/bg' + ext)) {
|
||||
bg_src = media + '/background/bg' + ext;
|
||||
bg_type = 'video';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
-%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ dispatcher.lang }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<meta name="theme-color" id="meta-theme-color" content="{{ glass_mode == 'dark' ? '#2c2e3a' : '#f5f5f7' }}">
|
||||
<title>{{ hostname }}{{ node?.title ? ` - ${striptags(node.title)}` : '' }} - LuCI</title>
|
||||
<link rel="icon" href="{{ media }}/img/glass-logo.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="{{ media }}/css/cascade.css">
|
||||
<style id="dark-styles" media="{% if (glass_mode == 'dark'): %}all{% elif (glass_mode == 'light'): %}not all{% else %}(prefers-color-scheme: dark){% endif %}">
|
||||
{{ dark_css }}
|
||||
</style>
|
||||
{% if (access('/etc/config/glass')): %}
|
||||
<style>
|
||||
html {
|
||||
font-size: {{ glass_font_size }}px;
|
||||
}
|
||||
:root {
|
||||
--color-primary: {{ glass_primary }};
|
||||
--glass-blur: {{ glass_blur }}px;
|
||||
--glass-bg: rgba(255, 255, 255, {{ glass_transparency }});
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-primary: {{ glass_dark_primary }};
|
||||
--glass-blur: {{ glass_blur_dark }}px;
|
||||
--glass-bg: rgba(38, 38, 42, {{ glass_transparency_dark }});
|
||||
}
|
||||
}
|
||||
[data-theme="dark"] {
|
||||
--color-primary: {{ glass_dark_primary }};
|
||||
--glass-blur: {{ glass_blur_dark }}px;
|
||||
--glass-bg: rgba(38, 38, 42, {{ glass_transparency_dark }});
|
||||
}
|
||||
[data-theme="light"] {
|
||||
--color-primary: {{ glass_primary }};
|
||||
--glass-blur: {{ glass_blur }}px;
|
||||
--glass-bg: rgba(255, 255, 255, {{ glass_transparency }});
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
<script>
|
||||
(function(){
|
||||
var d=document.getElementById('dark-styles'),m=document.getElementById('meta-theme-color'),s;
|
||||
try{s=localStorage.getItem('glass-theme')}catch(e){}
|
||||
if(s){
|
||||
if(s==='dark'){d.media='all';if(m)m.content='#2c2e3a'}
|
||||
else if(s==='light'){d.media='not all';if(m)m.content='#f5f5f7'}
|
||||
else{s='auto';d.media='(prefers-color-scheme: dark)';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
}else{
|
||||
var media=d.media;
|
||||
if(media==='all')s='dark';else if(media==='not all')s='light';else{s='auto';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
}
|
||||
document.documentElement.dataset.theme=s;
|
||||
})();
|
||||
</script>
|
||||
{% if (node?.css): %}
|
||||
<link rel="stylesheet" href="{{ resource }}/{{ node.css }}">
|
||||
{% endif %}
|
||||
{% if (css): %}
|
||||
<style>{{ css }}</style>
|
||||
{% endif %}
|
||||
<script src="{{ dispatcher.build_url('admin/translations', dispatcher.lang) }}"></script>
|
||||
<script src="{{ resource }}/cbi.js"></script>
|
||||
</head>
|
||||
<body class="lang_{{ dispatcher.lang }}" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
|
||||
|
||||
<div id="bg-wrap">
|
||||
{% if (bg_src && bg_type == 'video'): %}
|
||||
<video autoplay muted loop playsinline>
|
||||
<source src="{{ bg_src }}">
|
||||
</video>
|
||||
{% elif (bg_src): %}
|
||||
<img src="{{ bg_src }}" alt="">
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if (!blank_page): %}
|
||||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||||
|
||||
<aside id="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<span class="brand">{{ hostname }}</span>
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-nav" id="sidebar-nav">
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-footer">
|
||||
<span class="sidebar-version">GlassTheme v{{ glass_version }}</span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<header id="header">
|
||||
<button class="menu-toggle" id="menu-toggle" aria-label="Toggle menu">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="3" y1="6" x2="21" y2="6"/>
|
||||
<line x1="3" y1="12" x2="21" y2="12"/>
|
||||
<line x1="3" y1="18" x2="21" y2="18"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<nav id="header-nav">
|
||||
<span class="header-title" id="header-title"></span>
|
||||
</nav>
|
||||
<div id="header-tabs"></div>
|
||||
|
||||
<div id="status-indicators"></div>
|
||||
|
||||
<div class="header-actions" id="indicators">
|
||||
<button class="theme-toggle" id="theme-toggle" type="button" title="Theme: Auto" aria-label="Theme: Auto">
|
||||
<svg class="theme-icon theme-icon-auto" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="9" cy="9" r="7.25"/>
|
||||
<path d="M9 1.75A7.25 7.25 0 019 16.25" fill="currentColor" stroke="none"/>
|
||||
</svg>
|
||||
<svg class="theme-icon theme-icon-light" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="9" cy="9" r="3.5"/>
|
||||
<line x1="9" y1="1" x2="9" y2="3"/><line x1="9" y1="15" x2="9" y2="17"/>
|
||||
<line x1="2.87" y1="2.87" x2="4.28" y2="4.28"/><line x1="13.72" y1="13.72" x2="15.13" y2="15.13"/>
|
||||
<line x1="1" y1="9" x2="3" y2="9"/><line x1="15" y1="9" x2="17" y2="9"/>
|
||||
<line x1="2.87" y1="15.13" x2="4.28" y2="13.72"/><line x1="13.72" y1="4.28" x2="15.13" y2="2.87"/>
|
||||
</svg>
|
||||
<svg class="theme-icon theme-icon-dark" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15.54 9.98a7 7 0 01-8.52-8.52 7.5 7.5 0 108.52 8.52z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav id="header-sub"></nav>
|
||||
|
||||
<main id="content-wrap">
|
||||
<div id="content">
|
||||
<div id="maincontent">
|
||||
{% if (getuid() == 0 && getspnam('root')?.pwdp === ''): %}
|
||||
<div class="alert-message warning">
|
||||
<h4>{{ _('No password set!') }}</h4>
|
||||
<p>{{ _('There is no password set on this router. Please configure a root password to protect the web interface.') }}</p>
|
||||
{% if (dispatcher.lookup("admin/system/admin")): %}
|
||||
<div class="right"><a class="btn cbi-button-positive" href="{{ dispatcher.build_url("admin/system/admin") }}">{{ _('Go to password configuration...') }}</a></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<noscript>
|
||||
<div class="alert-message warning">
|
||||
<h4>{{ _('JavaScript required!') }}</h4>
|
||||
<p>{{ _('You must enable JavaScript in your browser or LuCI will not work properly.') }}</p>
|
||||
</div>
|
||||
</noscript>
|
||||
{% endif %}
|
||||
@@ -0,0 +1 @@
|
||||
{# luci-theme-glass — Login header (not used, sysauth.ut is self-contained) #}
|
||||
@@ -0,0 +1,160 @@
|
||||
{# luci-theme-glass — Login page (self-contained, argon-style) #}
|
||||
{%
|
||||
import { readfile, access } from 'fs';
|
||||
import { cursor } from 'uci';
|
||||
|
||||
const glass_version = trim(readfile('/usr/share/ucode/luci/template/themes/glass/version')) ?? '?';
|
||||
const boardinfo = ubus.call('system', 'board');
|
||||
const hostname = striptags(boardinfo?.hostname ?? 'OpenWrt');
|
||||
|
||||
http.prepare_content('text/html; charset=UTF-8');
|
||||
|
||||
/* Read theme config */
|
||||
let glass_mode = 'normal';
|
||||
let cfg = cursor();
|
||||
if (access('/etc/config/glass')) {
|
||||
glass_mode = cfg.get_first('glass', 'global', 'mode') ?? glass_mode;
|
||||
}
|
||||
|
||||
/* Read dark.css */
|
||||
const dark_css = readfile('/www/luci-static/glass/css/dark.css');
|
||||
|
||||
/* Find background media */
|
||||
let bg_src = null;
|
||||
let bg_type = 'image';
|
||||
const bg_dir = '/www/luci-static/glass/background';
|
||||
const img_exts = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
||||
const vid_exts = ['.mp4', '.webm'];
|
||||
|
||||
for (let ext in img_exts) {
|
||||
if (access(bg_dir + '/bg' + ext)) {
|
||||
bg_src = media + '/background/bg' + ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bg_src) {
|
||||
for (let ext in vid_exts) {
|
||||
if (access(bg_dir + '/bg' + ext)) {
|
||||
bg_src = media + '/background/bg' + ext;
|
||||
bg_type = 'video';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
-%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ dispatcher.lang }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<meta name="theme-color" id="meta-theme-color" content="{{ glass_mode == 'dark' ? '#2c2e3a' : '#f5f5f7' }}">
|
||||
<title>{{ _('Login') }} - {{ hostname }} - LuCI</title>
|
||||
<link rel="icon" href="{{ media }}/img/glass-logo.svg" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="{{ media }}/css/cascade.css">
|
||||
<style id="dark-styles" media="{% if (glass_mode == 'dark'): %}all{% elif (glass_mode == 'light'): %}not all{% else %}(prefers-color-scheme: dark){% endif %}">
|
||||
{{ dark_css }}
|
||||
</style>
|
||||
<script>
|
||||
(function(){
|
||||
var d=document.getElementById('dark-styles'),m=document.getElementById('meta-theme-color'),s;
|
||||
try{s=localStorage.getItem('glass-theme')}catch(e){}
|
||||
if(s){
|
||||
if(s==='dark'){d.media='all';if(m)m.content='#2c2e3a'}
|
||||
else if(s==='light'){d.media='not all';if(m)m.content='#f5f5f7'}
|
||||
else{s='auto';d.media='(prefers-color-scheme: dark)';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
}else{
|
||||
var media=d.media;
|
||||
if(media==='all')s='dark';else if(media==='not all')s='light';else{s='auto';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
}
|
||||
document.documentElement.dataset.theme=s;
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body class="lang_{{ dispatcher.lang }}">
|
||||
|
||||
<button class="theme-toggle theme-toggle-float" id="theme-toggle" type="button" title="Theme: Auto" aria-label="Theme: Auto">
|
||||
<svg class="theme-icon theme-icon-auto" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="9" cy="9" r="7.25"/>
|
||||
<path d="M9 1.75A7.25 7.25 0 019 16.25" fill="currentColor" stroke="none"/>
|
||||
</svg>
|
||||
<svg class="theme-icon theme-icon-light" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="9" cy="9" r="3.5"/>
|
||||
<line x1="9" y1="1" x2="9" y2="3"/><line x1="9" y1="15" x2="9" y2="17"/>
|
||||
<line x1="2.87" y1="2.87" x2="4.28" y2="4.28"/><line x1="13.72" y1="13.72" x2="15.13" y2="15.13"/>
|
||||
<line x1="1" y1="9" x2="3" y2="9"/><line x1="15" y1="9" x2="17" y2="9"/>
|
||||
<line x1="2.87" y1="15.13" x2="4.28" y2="13.72"/><line x1="13.72" y1="4.28" x2="15.13" y2="2.87"/>
|
||||
</svg>
|
||||
<svg class="theme-icon theme-icon-dark" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15.54 9.98a7 7 0 01-8.52-8.52 7.5 7.5 0 108.52 8.52z"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div id="bg-wrap">
|
||||
{% if (bg_src && bg_type == 'video'): %}
|
||||
<video autoplay muted loop playsinline>
|
||||
<source src="{{ bg_src }}">
|
||||
</video>
|
||||
{% elif (bg_src): %}
|
||||
<img src="{{ bg_src }}" alt="">
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="login-wrap">
|
||||
<div class="login-card">
|
||||
<img class="login-logo" src="{{ media }}/img/glass-logo.svg" alt="Logo">
|
||||
<h1 class="login-title">{{ hostname }}</h1>
|
||||
<p class="login-subtitle">{{ _('Sign in to continue') }}</p>
|
||||
<p class="login-version">GlassTheme v{{ glass_version }}</p>
|
||||
|
||||
{% if (fuser): %}
|
||||
<div class="login-error">
|
||||
{{ _('Invalid username and/or password! Please try again.') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form class="login-form" method="post" action="{{ http.getenv('REQUEST_URI') }}">
|
||||
<div class="login-field">
|
||||
<label for="luci_username">{{ _('Username') }}</label>
|
||||
<input type="text" id="luci_username" name="luci_username"
|
||||
value="{{ entityencode(duser, true) }}"
|
||||
autocomplete="username">
|
||||
</div>
|
||||
|
||||
<div class="login-field">
|
||||
<label for="luci_password">{{ _('Password') }}</label>
|
||||
<input type="password" id="luci_password" name="luci_password"
|
||||
autocomplete="current-password">
|
||||
</div>
|
||||
|
||||
<input type="submit" class="login-btn" value="{{ _('Log in') }}">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var pw = document.getElementById('luci_password');
|
||||
if (pw) pw.focus();
|
||||
|
||||
(function(){
|
||||
var btn=document.getElementById('theme-toggle');
|
||||
if(!btn)return;
|
||||
var order=['auto','light','dark'];
|
||||
var labels={auto:'Theme: Auto',light:'Theme: Light',dark:'Theme: Dark'};
|
||||
var cur=document.documentElement.dataset.theme||'auto';
|
||||
btn.title=labels[cur];btn.setAttribute('aria-label',labels[cur]);
|
||||
btn.addEventListener('click',function(){
|
||||
var cur=document.documentElement.dataset.theme||'auto';
|
||||
var next=order[(order.indexOf(cur)+1)%3];
|
||||
document.documentElement.dataset.theme=next;
|
||||
try{localStorage.setItem('glass-theme',next)}catch(e){}
|
||||
var d=document.getElementById('dark-styles'),m=document.getElementById('meta-theme-color');
|
||||
if(next==='dark'){d.media='all';if(m)m.content='#2c2e3a'}
|
||||
else if(next==='light'){d.media='not all';if(m)m.content='#f5f5f7'}
|
||||
else{d.media='(prefers-color-scheme: dark)';if(m)m.content=window.matchMedia('(prefers-color-scheme: dark)').matches?'#2c2e3a':'#f5f5f7'}
|
||||
btn.title=labels[next];btn.setAttribute('aria-label',labels[next]);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
1.1.6
|
||||
@@ -0,0 +1,12 @@
|
||||
.research/
|
||||
.reasonix/
|
||||
*.ipk
|
||||
*.apk
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
reasonix.toml
|
||||
# CDP/headless 调试临时目录
|
||||
.liquid-tmp/
|
||||
@@ -0,0 +1,61 @@
|
||||
# 更新日志
|
||||
|
||||
> 本文件归档 **[README.md](README.md)** 的全部历史更新条目;README 正文只保留最近一次更新。
|
||||
> English version: **[ChangeLogs_EN.md](ChangeLogs_EN.md)**
|
||||
|
||||
- **2026-09-28 · v1.0(主版本升级)**:透明度调节 + 在线更新 + 登录体验 + 宽表格自适应
|
||||
- **玻璃透明度滑杆**:顶栏颜色区拖动 0–100 即时生效、点刻度回默认;菜单、按钮、主题色背景同步变化,亮 / 暗各有默认;登录页同样可调,设置存在路由器上、换设备保留
|
||||
- **在线检查更新**:点页脚版本号即可检查新版本、一键更新;检查中 / 已是最新 / 有新版本 / 失败 四种状态一目了然,失败会明确提示;手机页脚也显示版本、按钮加大
|
||||
- **登录页**:登录前调好的明暗 / 主题色 / 透明度,登录后弹提示一键应用(30 秒可忽略);logo 换上毛玻璃光晕;修复明暗切换闪动与误触提交
|
||||
- **下拉菜单**:玻璃外观重做,宽度随最长选项伸缩、贴边自动上弹、点内容不闪烁;暗色下选项更清楚;无线设置等页面异常的下拉恢复正常
|
||||
- **提示弹窗**:成功提示(如“密码已更改”)改为屏幕居中玻璃弹窗、6 秒自动关闭;手机上按钮自动换行不溢出
|
||||
- **宽表格自适应**:表格超出屏幕时先折叠操作按钮(一行一个)把宽度让给文字,文字不再被挤窄或裁掉;手机上表格收回屏内、无需左右拖动
|
||||
- **其他修复**:菜单滑块切分类不再停在原处;OpenClash 打开不再先闪黑;选中标签改高对比配色,暗色下更清楚
|
||||
|
||||
- **2026-08-18 · v0.7**:移动端体验优化 + 多处体验优化
|
||||
- **移动端体验优化**
|
||||
- 滚动页面时浏览器工具栏 / 地址栏自动收缩,移动端获得更大视野
|
||||
- 底部横幅避让全面屏手势条
|
||||
- EasyTier 重启、刷新版本确认框在手机上居中显示
|
||||
- **多处体验优化**
|
||||
- 修复按钮描边不贴合圆角、边缘出现竖缝的问题(普通按钮 / 保存并应用 / 分割按钮)
|
||||
- **2026-08-15 · v0.6**:菜单搜索 + 多处体验优化
|
||||
- **菜单搜索**:颜色区新增搜索入口,点击推出搜索框,实时过滤菜单项,支持中英文匹配
|
||||
- **多处体验优化**:多实例配置(如 Dropbear)独立卡片显示;刷新按钮玻璃质感;iStoreOS 页面标签适配主题样式
|
||||
- **2026-08-13 · v0.5**:弹窗居中 + 状态条样式优化
|
||||
- **弹窗居中**:应用配置提示(正在等待 / 已应用 / 无待应用)与待应用变更窗口在移动端正确居中显示;超高表单弹窗(如添加 DHCP)保持正常滚动
|
||||
- **状态条样式**:磁盘 / 内存使用条加深主题色、玻璃渐变质感,条内显示已用 / 总量
|
||||
- **2026-08-08 · v0.3**:自定义主题色 + 颜色开关优化 + 移动端 / 暗色模式改进
|
||||
- **自定义主题色**:5 套预置色之外新增自定义色——点击彩虹圆点下拉输入 hex 颜色编码(`#RRGGBB`),离开输入框即保存并全局生效;非法输入自动回退默认蓝(仍保持自定义模式启用);经 uci 持久化,换设备保留
|
||||
- **颜色开关**:外框统一 35px 高;自定义色选中时圆点内部显示自定义色、外圈彩虹渐变描边(一眼识别);Bing 壁纸按钮方形描边贴合图标、启用时单层白色描边
|
||||
- **移动端**:首屏不再闪现"菜单先展开再收缩"(禁用桌面入场动画干扰抽屉收起态,加载完成即可操作);底部 foot 高度缩减
|
||||
- **暗色模式**:模式开关图标(外链 svg)反色为浅色,深色背景下清晰可见
|
||||
- **修复**:自定义色保存(controller 白名单支持 `accent=custom` / `accent_custom`)、登录页颜色开关定位、颜色区外框高度
|
||||
|
||||
- **2026-08-08 · v0.2-r52**:移动端体验优化 + 下拉菜单优化
|
||||
- **移动端接口页**:接口小框(ifacebox)与其所在行卡片左缘间隔优化为 4px,显示更整齐
|
||||
- **移动端层叠卡片缩进**:弹出窗口宽 95%、嵌套卡片每层向内缩 2px,展示更大操作区
|
||||
- **移动端菜单**:点击空白处退出菜单
|
||||
- **桌面端弹出式层叠卡片**:显示效果优化(modal 80% 宽、嵌套卡片逐层限宽防溢出)
|
||||
- **下拉菜单**:单选 / 多选交互与显示效果优化
|
||||
|
||||
- **2026-08-07 · v0.2**:配置持久化(uci)+ Bing 每日壁纸 + 多项修复
|
||||
- **配置持久化(uci)**:亮/暗/自动模式、5 套主题色、Bing 开关统一存入 `uci /etc/config/liquid`,换客户端(浏览器/设备)仍保留;改动经 LuCI RPC 直接提交,立即生效、无"待应用"提示
|
||||
- **Bing 每日壁纸(锁屏)**:主题色前新增 Bing 开关按钮(字母 b logo);启用后锁屏显示 Bing 当日壁纸(缓存于各设备 `/tmp/liquid/`);无互联网或按钮关闭时自动回退默认壁纸(亮/暗各按模式)
|
||||
- **锁屏只读**:登录页仅本地预览,不写入配置
|
||||
- **uci 优先**:修复本地 localStorage 旧值覆盖 uci 新配置的问题,页面加载即应用路由器端配置
|
||||
- **接口页修复**:未加入防火墙区域的接口 head 色条由白色改为灰色(亮色浅灰 / 暗色近黑),暗色下接口名不再不可见
|
||||
- **CI**:GitHub Actions 双平台(x86 + MT798x)× 双格式(ipk / apk)自动构建发布
|
||||
- 版本号 0.2-r1
|
||||
|
||||
- **2026-08-07 · v0.1 首次发布**:全新 macOS 风格 Liquid Glass(液态玻璃)LuCI 主题,带来以下功能:
|
||||
- **液态玻璃设计语言**:侧栏、内容卡片、登录页、页脚统一 frosted-glass(模糊 + 高光 + 主题色光晕),暗色下玻璃更实、文字更清晰
|
||||
- **三态模式切换**:亮色 / 暗色 / 跟随系统,顶栏一键切换,`localStorage` 持久化、加载无闪烁
|
||||
- **主题色**:5 套主题色(蓝 / 玫红 / 橙黄 / 郁金香紫 / 黄绿),菜单、按钮、Tab、logo 全链路联动
|
||||
- **菜单**:默认全部折叠(点击一级菜单才展开二级)、hover 追踪滑块、选中玻璃胶囊、移动端滑出菜单
|
||||
- **下拉控件**:一体化渐变胶囊(主体 + 分隔箭头,同"保存并应用"),视口边缘自动向上弹出、不被页脚遮挡
|
||||
- **悬浮内容框(tooltip)**:磨砂玻璃底、顶层显示不被相邻卡片遮挡、边缘自动避让、互斥防残留
|
||||
- **表格**:行内单元格等高(分割线对齐)、移动端按内容宽度 + 横向滚动(长列不重叠)
|
||||
- **接口 / 设备页**:SVG 图标统一、连接状态由图标文件区分(不再半透误导)
|
||||
- **锁屏(登录页)**:macOS 风格玻璃登录卡片 + Monterey 壁纸 + 主题色水滴 logo
|
||||
- **兼容**:LuCI ≥ 23(OpenWrt 23.05 / 24.10 / master)
|
||||
@@ -0,0 +1,61 @@
|
||||
# Changelog
|
||||
|
||||
> Full history of the entries from **[README_EN.md](README_EN.md)**; the README body only keeps the latest one.
|
||||
> 中文版本:**[ChangeLogs.md](ChangeLogs.md)**
|
||||
|
||||
- **2026-09-28 · v1.0 (major release)**: opacity slider + online update + lock screen polish + wide-table adaptivity
|
||||
- **Glass opacity slider**: drag 0–100 in the top-bar color area for an instant preview, click the tick to reset; menus, buttons and accent backgrounds follow along, with separate light / dark defaults; also on the lock screen, and the setting stays on your router across devices
|
||||
- **Online update check**: click the footer version to check and install a new release; checking / up to date / update available / failed are all clearly shown, and failures report an error instead of hanging; mobile footers show the version too, with bigger buttons
|
||||
- **Lock screen**: mode, accent and opacity picked before signing in are offered with one click after login (30-second countdown, dismissible); the logo gets a frosted glass glow; fixed mode-switch flicker and accidental submits
|
||||
- **Dropdowns**: refreshed glass look — width follows the longest option, menus flip up near the edge, no flash on click; clearer highlights in dark mode; previously broken dropdowns (e.g. wireless settings) work again
|
||||
- **Notifications**: success messages (e.g. "password changed") now show as a centered glass dialog that closes after 6 seconds; buttons wrap on phones instead of overflowing
|
||||
- **Wide tables**: when a table no longer fits the screen, action buttons stack one per line so text keeps its width — no more squeezed or clipped columns; on phones the table stays on screen with no sideways scrolling
|
||||
- **Fixes**: the sidebar slider no longer sticks to the previous category; OpenClash no longer flashes dark on open; the selected tab uses a high-contrast color for dark mode
|
||||
|
||||
- **2026-08-18 · v0.7**: mobile UX polish + general UX polish
|
||||
- **Mobile**
|
||||
- Toolbar / address bar auto-collapses on scroll, giving a larger view on phones
|
||||
- Bottom banner clears the fullscreen gesture bar
|
||||
- EasyTier restart / refresh-version dialogs center on mobile
|
||||
- **General**
|
||||
- Fixed button borders not hugging rounded corners / edge seams (plain buttons, Save & Apply, split-select)
|
||||
- **2026-08-15 · v0.6**: menu search + UX polish
|
||||
- **Menu search**: new search entry in the color area — opens a search box that filters menu items in real time, matching Chinese and English titles
|
||||
- **UX polish**: multi-instance configs (e.g. Dropbear) show as separate cards; refresh button gets a frosted glass look; iStoreOS page tabs adopt the theme tab style
|
||||
- **2026-08-13 · v0.5**: centered modals + status-bar style polish
|
||||
- **Centered modals**: apply-progress toasts (applying / applied / nothing to apply) and the pending-changes dialog are now properly centered on mobile; tall form modals (e.g. add DHCP) keep normal scrolling
|
||||
- **Status bars**: disk / memory usage bars get a deeper accent color with a glass gradient, showing used / total inline
|
||||
- **2026-08-08 · v0.3**: custom accent color + color-switch polish + mobile / dark-mode improvements
|
||||
- **Custom accent color**: beyond the 5 presets — click the rainbow dot to drop a hex input (`#RRGGBB`); leaving the field saves and applies instantly; invalid values fall back to default blue (custom mode stays enabled); persisted via uci across clients
|
||||
- **Color switch**: pill fixed at 35px; a selected custom dot shows its color inside with a rainbow ring for instant recognition; the Bing wallpaper button gets a square outline hugging its icon and a single white ring when active
|
||||
- **Mobile**: no first-load menu flash (desktop entry animation disabled so the drawer starts closed and usable immediately); footer height trimmed
|
||||
- **Dark mode**: mode-switch icons (external svg) inverted to light so they stay visible on dark backgrounds
|
||||
- **Fixes**: custom-color persistence (controller whitelist accepts `accent=custom` / `accent_custom`), login-page color-switch position, pill height
|
||||
|
||||
- **2026-08-08 · v0.2-r52**: mobile UX & dropdown improvements
|
||||
- **Mobile interfaces page**: ifacebox aligned 4px from its row card's left edge for a cleaner look
|
||||
- **Mobile nested-card insets**: modal at 95% width, each nested layer steps in 2px, giving a larger usable area
|
||||
- **Mobile menu**: tapping outside closes the menu
|
||||
- **Desktop modal / nested cards**: improved display (modal at 80% width, nested layers width-constrained to prevent overflow)
|
||||
- **Dropdowns**: single-select & multi-select interaction and display polish
|
||||
|
||||
- **2026-08-07 · v0.2**: persistent config (uci) + Bing daily wallpaper + fixes
|
||||
- **Persistent config (uci)**: light/dark/auto mode, the 5 accent colors and the Bing switch are stored in `uci /etc/config/liquid`, so the settings follow the router across clients (browsers / devices); changes are committed through the theme's own ucode endpoint and take effect immediately with no "pending apply" entries or save prompts.
|
||||
- **Bing daily wallpaper (lock screen)**: a Bing toggle button (letter-b logo) sits before the five accent colors; when enabled, the lock screen shows Bing's picture of the day (cached per device in `/tmp/liquid/`); when offline or disabled it falls back to the default wallpaper (per mode).
|
||||
- **Lock screen read-only**: the login page only previews locally and never writes configuration.
|
||||
- **uci wins**: fixed stale localStorage overriding the uci config — every reload applies the router-wide config.
|
||||
- **Interfaces page fix**: the head bar of interfaces not assigned to any firewall zone is now gray (light: light gray / dark: near-black) so the interface name stays readable in dark mode.
|
||||
- **CI**: GitHub Actions build & release on two platforms (x86 + MT798x) × two formats (ipk / apk).
|
||||
- Version bumped to 0.2-r1.
|
||||
|
||||
- **2026-08-07 · v0.1 (initial release)**: a brand-new macOS-style Liquid Glass LuCI theme
|
||||
- **Liquid glass design language**: frosted glass (blur + highlight + theme glow) across sidebar, content cards, login page and footer
|
||||
- **Three-way mode**: light / dark / auto from the top bar, persisted, no flash on load
|
||||
- **Accent colors**: 5 themes driving menus, buttons, tabs and logo
|
||||
- **Menu**: collapsed by default, hover-tracking slider, selected glass capsule, mobile slide-out menu
|
||||
- **Dropdowns**: gradient capsule (body + divider + arrow, same as "Save & Apply"), auto-flip at viewport edges
|
||||
- **Tooltips**: frosted glass, top-level display, edge avoidance
|
||||
- **Tables**: equal-height rows, horizontal scroll on mobile (no long-column overlap)
|
||||
- **Interfaces / Devices**: uniform SVG icons, link state told by the icon file
|
||||
- **Lock screen**: macOS-style frosted login card + Monterey wallpaper + accent-colored waterdrop logo
|
||||
- **Compatibility**: LuCI ≥ 23 (OpenWrt 23.05 / 24.10 / master)
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
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:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
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
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,67 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-theme-liquid
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_MAINTAINER:=然后七年 <z@7ze.top>
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
# OpenWrt 23.05 的 luci.mk 版本规则只取 PKG_VERSION(忽略 PKG_RELEASE),
|
||||
# 导致 GitHub Action 编译出的 ipk 没有 r 小版本(0.4 vs 0.4-r1)。
|
||||
# 用 override VERSION 强制统一为 PKG_VERSION-rPKG_RELEASE。注意:必须
|
||||
# 写在 include luci.mk 之前——luci.mk 末尾会立即 eval BuildPackage,
|
||||
# 其 ipk 命名/control 里的 $(VERSION) 在那一刻固化,写后面就晚了。
|
||||
# luci.mk 的 VERSION:= 是普通赋值(被 override 压住),且本值在新版
|
||||
# luci.mk 与 i18n 子包(PKG_PO_VERSION)下与默认一致,不影响 apk/新版。
|
||||
override VERSION:=$(if $(PKG_RELEASE),$(PKG_VERSION)-r$(PKG_RELEASE),$(PKG_VERSION))
|
||||
|
||||
LUCI_TITLE:=Liquid glass theme for LuCI (>= 23)
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+luci-base
|
||||
|
||||
# 汉化/子包版本与主包保持同步
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)-r$(PKG_RELEASE)
|
||||
|
||||
# csstidy 会破坏 @media 块(只保留首条规则,其余泄漏到块外无条件生效),
|
||||
# 导致移动端断点样式全部失效;本主题关闭 CSS 压缩,样式原样打包。
|
||||
CONFIG_LUCI_CSSTIDY:=
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
# 公钥信任不在此处写(去冗余):apk 装机时生成的 post-install 会先
|
||||
# 调 default_postinst —— 它会执行包内 etc/uci-defaults/99-zed-apk-key-liquid
|
||||
# 完成公钥条件写入并消费该脚本;固件场景由首次开机执行同一脚本覆盖
|
||||
# (构建期 --no-scripts 不跑脚本,文件随镜像保留);装 r9 之前的设备
|
||||
# 由 OTA 安装前自举兜底。23.05 为 opkg 系统,不使用 apk 钥匙。
|
||||
|
||||
# 23.05 opkg 不执行 uci-defaults,必须在 postinst 中设置主题配置。
|
||||
# 确保 mediaurlbase 指向 liquid,否则 fallback 到 null。
|
||||
if [ "$$(uci -q get luci.main.mediaurlbase)" != "/luci-static/liquid" ]; then
|
||||
uci set luci.main.mediaurlbase=/luci-static/liquid
|
||||
uci commit luci
|
||||
fi
|
||||
|
||||
rm -f /tmp/luci-indexcache.*
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
/etc/init.d/rpcd reload 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postrm
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
uci -q delete luci.themes.Liquid
|
||||
[ "$$(uci -q get luci.main.mediaurlbase)" = "/luci-static/liquid" ] && \
|
||||
uci -q delete luci.main.mediaurlbase
|
||||
uci commit luci
|
||||
}
|
||||
exit 0
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
@@ -0,0 +1,177 @@
|
||||
<!-- markdownlint-configure-file {
|
||||
"MD013": {
|
||||
"code_blocks": false,
|
||||
"tables": false,
|
||||
"line_length":200
|
||||
},
|
||||
"MD033": false,
|
||||
"MD041": false
|
||||
} -->
|
||||
|
||||
[license]: /LICENSE
|
||||
[license-badge]: https://img.shields.io/github/license/zzsj0928/luci-theme-liquid?style=flat-square&a=1
|
||||
[prs]: https://github.com/zzsj0928/luci-theme-liquid/pulls
|
||||
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
||||
[issues]: https://github.com/zzsj0928/luci-theme-liquid/issues/new
|
||||
[issues-badge]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg?style=flat-square
|
||||
[release]: https://github.com/zzsj0928/luci-theme-liquid/releases
|
||||
[release-badge]: https://img.shields.io/github/v/release/zzsj0928/luci-theme-liquid?style=flat-square
|
||||
[download]: https://github.com/zzsj0928/luci-theme-liquid/releases
|
||||
[download-badge]: https://img.shields.io/github/downloads/zzsj0928/luci-theme-liquid/total?style=flat-square
|
||||
[en-us-link]: /README_EN.md
|
||||
[zh-cn-link]: /README.md
|
||||
[official]: https://github.com/openwrt/openwrt
|
||||
[immortalwrt]: https://github.com/immortalwrt/immortalwrt
|
||||
[luci-mod]: https://github.com/xylz0928/luci-mod
|
||||
|
||||
<div align="center">
|
||||
<p align="center"><img src="logo.svg" width="500"></p>
|
||||
|
||||
# 💧 luci-theme-liquid
|
||||
|
||||
**macOS 风格 Liquid Glass(液态玻璃)OpenWrt LuCI 主题**,适用于 **LuCI ≥ 23**(OpenWrt 23.05 / 24.10 / master)。
|
||||
|
||||
支持**亮色 / 暗色 / 跟随系统**三态切换、**5 套主题色 + 自定义颜色**、可调玻璃模糊与透明度;登录页、侧栏、内容卡片、下拉、悬浮框全链路液态玻璃质感。
|
||||
|
||||
[![license][license-badge]][license]
|
||||
[![prs][prs-badge]][prs]
|
||||
[![issues][issues-badge]][issues]
|
||||
[![release][release-badge]][release]
|
||||
[![download][download-badge]][download]
|
||||
|
||||
**简体中文** | [English][en-us-link]
|
||||
|
||||
[特性](#特性) •
|
||||
[更新日志](#更新日志) •
|
||||
[兼容性](#兼容性) •
|
||||
[编译安装](#编译安装) •
|
||||
[界面展示](#界面展示) •
|
||||
[致谢](#致谢)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/zzsj0928/ReadmeContents/master/liquid/luci-theme-liquid_pc.gif">
|
||||
|
||||
</div>
|
||||
|
||||
## 特性
|
||||
|
||||
- **液态玻璃设计语言**:侧栏、内容卡片、登录卡片、页脚统一 frosted-glass(模糊 + 高光 + 主题色光晕),暗色下玻璃更实、文字更清晰。
|
||||
- **亮 / 暗 / 跟随系统**:顶栏右侧一键切换,设置存在路由器上(换浏览器、换设备仍在),加载即生效、无闪烁;锁屏页同样可切。
|
||||
- **主题色**:**远空蓝**、**勃艮第红**、**落日金**、**暮山紫**、**青金萃** 5 套 + 自定义色(点彩虹圆点输入 `#RRGGBB`),选中菜单、悬停滑块、按钮、Tab、logo 全链路联动。
|
||||
- **玻璃透明度滑杆**:顶栏颜色区拖动 0–100 实时调节玻璃深浅,点默认刻度一键还原;亮 / 暗各有默认值;菜单、按钮、主题色背景同步变化;锁屏页同样可调。
|
||||
- **菜单搜索**:顶栏搜索按钮下推抽屉式搜索框,输入即实时过滤菜单,中文名与英文原题都能匹配,点外部或再点按钮收回。
|
||||
- **左侧菜单**:默认全部折叠,点一级才展开二级;悬停追踪滑块 + 选中玻璃胶囊;多实例配置(如 Dropbear)自动拆成独立卡片;移动端滑出菜单避让顶栏、点空白关闭。
|
||||
- **下拉控件**:玻璃胶囊外观,宽度随最长选项自动伸缩、贴近窗口边缘自动向上弹出、点内容区不闪烁;暗色下选项高亮更清楚。
|
||||
- **表格自适应**:行内单元格等高;表格超出屏幕时先把操作按钮竖排(一行一个)把宽度让给文字,文字不再被挤窄或裁掉;手机上表格收回屏内、无需左右拖动。
|
||||
- **接口 / 设备页**:接口图标统一 24px、始终不透明(连接状态由图标本身区分);行内等高,按钮平时一行、放不下时自动竖排让位文字;移动端接口小框与所在行卡片保持 4px 间隔。
|
||||
- **移动端适配**:弹出窗口 95% 宽、嵌套卡片逐层向内缩进;抽屉菜单点空白关闭、首屏直接收起无闪烁;提示按钮自动换行不溢出。
|
||||
- **在线检查更新**:点页脚版本号即可检查新版本、一键更新,检查中 / 已是最新 / 有新版本 / 失败 四态清晰;手机页脚同样显示主题版本。
|
||||
- **提示弹窗**:成功提示(如“密码已更改”)升级为屏幕居中的玻璃弹窗,6 秒自动关闭。
|
||||
- **锁屏(登录页)**:macOS 风格玻璃登录卡片 + Monterey 壁纸(亮/暗)+ 可选 **Bing 每日壁纸**(每日自动抓取缓存)+ 毛玻璃光晕水滴 logo;登录前调好的明暗 / 主题色 / 透明度,登录成功后一键应用。
|
||||
- **悬浮内容框(tooltip)**:磨砂玻璃底、置顶显示(不被相邻卡片遮挡)、边缘自动避让、互斥防残留。
|
||||
- **SVG 图标**:网络 / 接口状态图标取自 [xylz0928/luci-mod][luci-mod] `immortalwrt-24.10` 分支的 SVG 图标集;UI 元素图标(sun / moon / auto / refresh / lock / search / close / chevron)为内置 SVG。
|
||||
|
||||
|
||||
## 更新日志
|
||||
|
||||
- **2026-09-28 · v1.0(主版本升级)**:透明度调节 + 在线更新 + 登录体验 + 宽表格自适应
|
||||
- **玻璃透明度滑杆**:顶栏颜色区拖动 0–100 即时生效、点刻度回默认;菜单、按钮、主题色背景同步变化,亮 / 暗各有默认;登录页同样可调,设置存在路由器上、换设备保留
|
||||
- **在线检查更新**:点页脚版本号即可检查新版本、一键更新;检查中 / 已是最新 / 有新版本 / 失败 四种状态一目了然,失败会明确提示;手机页脚也显示版本、按钮加大
|
||||
- **登录页**:登录前调好的明暗 / 主题色 / 透明度,登录后弹提示一键应用(30 秒可忽略);logo 换上毛玻璃光晕;修复明暗切换闪动与误触提交
|
||||
- **下拉菜单**:玻璃外观重做,宽度随最长选项伸缩、贴边自动上弹、点内容不闪烁;暗色下选项更清楚;无线设置等页面异常的下拉恢复正常
|
||||
- **提示弹窗**:成功提示(如“密码已更改”)改为屏幕居中玻璃弹窗、6 秒自动关闭;手机上按钮自动换行不溢出
|
||||
- **宽表格自适应**:表格超出屏幕时先折叠操作按钮(一行一个)把宽度让给文字,文字不再被挤窄或裁掉;手机上表格收回屏内、无需左右拖动
|
||||
- **其他修复**:菜单滑块切分类不再停在原处;OpenClash 打开不再先闪黑;选中标签改高对比配色,暗色下更清楚
|
||||
|
||||
> 📜 完整更新日志(v0.1 起全部版本)见 **[ChangeLogs.md](ChangeLogs.md)**。
|
||||
|
||||
## 兼容性
|
||||
|
||||
支持基于 [OpenWrt 官方][official] 与 [ImmortalWrt][immortalwrt] 的现代 LuCI 环境(LuCI ≥ 23,OpenWrt 23.05 / 24.10 / master)。
|
||||
|
||||
## 编译安装
|
||||
|
||||
本包使用 LuCI feed 的 `luci.mk` 打包规则(`include $(TOPDIR)/feeds/luci/luci.mk`),因此编译环境需先 `./scripts/feeds update -a && ./scripts/feeds install -a`(含 luci feed)。
|
||||
|
||||
把本目录放入 OpenWrt 源码树的 `package/luci-theme-liquid/`(或 `feeds/luci/themes/luci-theme-liquid/`),在 `.config` 中启用该包后编译:
|
||||
|
||||
```bash
|
||||
cd openwrt/package
|
||||
git clone https://github.com/xylz0928/luci-theme-liquid.git
|
||||
make menuconfig # 选择 LUCI → Themes → luci-theme-liquid
|
||||
make -j1 V=s
|
||||
```
|
||||
|
||||
或直接编译单个包:
|
||||
|
||||
```sh
|
||||
# 在 .config 中启用(任选其一)
|
||||
make menuconfig # LuCI → Themes → luci-theme-liquid
|
||||
# 或
|
||||
echo 'CONFIG_PACKAGE_luci-theme-liquid=y' >> .config && make defconfig
|
||||
|
||||
make package/luci-theme-liquid/compile -j4 V=s
|
||||
```
|
||||
|
||||
> 注意:`make package/<name>/compile` 只对已在 `.config` 中启用(`=y`/`=m`)的包真正执行构建,未启用时 make 会空转(`Entering/Leaving` 无任何动作),不要误判为成功。
|
||||
|
||||
生成的 `bin/packages/<arch>/base/luci-theme-liquid-0.3-r<rel>.apk`(或 `.ipk`)可通过 `apk` / `opkg` 安装:
|
||||
|
||||
```sh
|
||||
apk add --allow-untrusted luci-theme-liquid-0.3-r1.apk
|
||||
```
|
||||
|
||||
首次安装会自动注册主题(`luci.themes.Liquid=/luci-static/liquid`);若 `luci.main.mediaurlbase` 尚未配置则自动设为该主题,否则请在 **System → Advanced → Theme** 中手动选择 **Liquid**。
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
luci-theme-liquid/
|
||||
├── Makefile # OpenWrt 包(luci feed 内/独立 package 目录均可编译)
|
||||
├── logo.svg # 主题 logo(水滴 + Liquid)
|
||||
├── htdocs/luci-static/liquid/ # 主题媒体资源(/luci-static/liquid/)
|
||||
│ ├── cascade.css # 全部样式(变量 / 菜单 / tab / cbi / dashboard / 锁屏)
|
||||
│ ├── main.js # 模式开关注入、下拉避让、tooltip portal 等
|
||||
│ ├── logo.svg / logo.png # 主题 logo
|
||||
│ ├── img/ # 锁屏壁纸(MontereyDark / MontereyLight)
|
||||
│ ├── icons/ # 网络状态 SVG 图标(来自 luci-mod immortalwrt-24.10)
|
||||
│ └── svg/ # UI 元素 SVG + dashboard 图标
|
||||
├── htdocs/luci-static/resources/ # 共享资源(/luci-static/resources/)
|
||||
│ ├── menu-liquid.js # 左侧菜单 / tab 渲染(L.require('menu-liquid'))
|
||||
│ └── view/liquid/sysauth.js # 锁屏登录视图(ui.showModal 'login')
|
||||
├── ucode/template/themes/liquid/ # 主题 ucode 模板
|
||||
│ ├── header.ut / footer.ut # 页面骨架(uci 配置读取 / 防闪烁 / Bing 壁纸缓存)
|
||||
│ └── sysauth.ut # 登录页模板(blank_page + 居中登录框)
|
||||
└── root/
|
||||
├── etc/uci-defaults/ # 安装时注册 luci.themes.Liquid
|
||||
└── usr/share/ucode/luci/controller/liquid.uc # 主题配置保存端点(/admin/system/liquid/save_config)
|
||||
```
|
||||
|
||||
## 界面展示
|
||||
|
||||
- 桌面端
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
- 移动端
|
||||
|
||||

|
||||

|
||||
|
||||
## 致谢
|
||||
|
||||
- 壁纸:macOS Monterey(Bright/Dark),来自 [xylz0928/luci-mod][luci-mod] `Background/`。
|
||||
- 网络状态 SVG 图标:来自 [xylz0928/luci-mod][luci-mod] `immortalwrt-24.10` 分支 `feeds/luci/modules/luci-base/htdocs/luci-static/resources/icons/`。
|
||||
- dashboard 模块图标(router / internet / wireless / devices):来自 OpenWrt 官方 [luci-mod-dashboard](https://github.com/openwrt/luci/tree/master/modules/luci-mod-dashboard)。
|
||||
- 菜单渲染逻辑参考 [luci-theme-openwrt-2020](https://github.com/openwrt/luci/tree/master/themes/luci-theme-openwrt-2020),锁屏视图参考 [luci-theme-bootstrap](https://github.com/openwrt/luci/tree/master/themes/luci-theme-bootstrap)(Apache-2.0)。
|
||||
|
||||
## 🍡 赏我一把 Token
|
||||
**制作不易,感谢支持**
|
||||

|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,178 @@
|
||||
<!-- markdownlint-configure-file {
|
||||
"MD013": {
|
||||
"code_blocks": false,
|
||||
"tables": false,
|
||||
"line_length":200
|
||||
},
|
||||
"MD033": false,
|
||||
"MD041": false
|
||||
} -->
|
||||
|
||||
[license]: /LICENSE
|
||||
[license-badge]: https://img.shields.io/github/license/zzsj0928/luci-theme-liquid?style=flat-square&a=1
|
||||
[prs]: https://github.com/zzsj0928/luci-theme-liquid/pulls
|
||||
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
||||
[issues]: https://github.com/zzsj0928/luci-theme-liquid/issues/new
|
||||
[issues-badge]: https://img.shields.io/badge/Issues-welcome-brightgreen.svg?style=flat-square
|
||||
[release]: https://github.com/zzsj0928/luci-theme-liquid/releases
|
||||
[release-badge]: https://img.shields.io/github/v/release/zzsj0928/luci-theme-liquid?style=flat-square
|
||||
[download]: https://github.com/zzsj0928/luci-theme-liquid/releases
|
||||
[download-badge]: https://img.shields.io/github/downloads/zzsj0928/luci-theme-liquid/total?style=flat-square
|
||||
[en-us-link]: /README_EN.md
|
||||
[zh-cn-link]: /README.md
|
||||
[official]: https://github.com/openwrt/openwrt
|
||||
[immortalwrt]: https://github.com/immortalwrt/immortalwrt
|
||||
[luci-mod]: https://github.com/xylz0928/luci-mod
|
||||
|
||||
<div align="center">
|
||||
<p align="center"><img src="logo.svg" width="300"></p>
|
||||
|
||||
# 💧 luci-theme-liquid
|
||||
|
||||
**macOS-style Liquid Glass OpenWrt LuCI theme**, for **LuCI ≥ 23** (OpenWrt 23.05 / 24.10 / master).
|
||||
|
||||
Supports **light / dark / auto** modes, **5 accent colors + a custom color picker** and adjustable blur & transparency; frosted glass design across the login page, sidebar, content cards, dropdowns and tooltips.
|
||||
|
||||
[![license][license-badge]][license]
|
||||
[![prs][prs-badge]][prs]
|
||||
[![issues][issues-badge]][issues]
|
||||
[![release][release-badge]][release]
|
||||
[![download][download-badge]][download]
|
||||
|
||||
**English** | [简体中文][zh-cn-link]
|
||||
|
||||
[Features](#features) •
|
||||
[Changelog](#changelog) •
|
||||
[Compatibility](#compatibility) •
|
||||
[Building & Installation](#building--installation) •
|
||||
[Screenshots](#screenshots) •
|
||||
[Credits](#credits)
|
||||
|
||||
<img src="https://raw.githubusercontent.com/zzsj0928/ReadmeContents/master/liquid/luci-theme-liquid_pc.gif">
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- **Liquid glass design language**: sidebar, content cards, login card and footer share a frosted-glass look (blur + highlight + accent glow); the dark mode glass is more solid for readable text.
|
||||
- **Light / dark / system**: one tap in the top bar; settings are stored on your router so they survive new browsers and devices; applied before paint with no flash — the lock screen has the switch too.
|
||||
- **Accent colors**: **Distant Blue**, **Burgundy Red**, **Sunset Gold**, **Dusk Purple**, **Peridot Essence**, plus a custom hex color (`#RRGGBB`) — menus, hover slider, buttons, tabs and the logo all follow.
|
||||
- **Glass opacity slider**: drag 0–100 in the top-bar color area to tune the glass live, click the default tick to reset; separate light / dark defaults; menus, buttons and accent backgrounds follow; also on the lock screen.
|
||||
- **Menu search**: the top-bar search button pushes down a drawer-style search box that filters menu items as you type, matching both Chinese names and English titles; click outside or the button again to close.
|
||||
- **Sidebar menu**: all top-level menus collapsed by default — click a level-1 menu to expand its submenu; hover-tracking slider + selected glass capsule; multi-instance entries (e.g. Dropbear) split into their own cards; the mobile slide-out menu avoids the top bar and closes on outside taps.
|
||||
- **Dropdown controls**: glass capsule look, width follows the longest option, the opened list flips upward near the window edge and never flashes when clicking the content area; clearer highlights in dark mode.
|
||||
- **Adaptive tables**: equal-height cells per row; when a table no longer fits the screen, action buttons stack one per line so text keeps its width — no squeezed or clipped columns; on phones the table stays inside the screen with no sideways scrolling.
|
||||
- **Interfaces / Devices pages**: uniform 24px interface icons, forced opaque (link state is told by the icon itself); rows keep equal heights, buttons stay on one line and stack only when space runs short; interface boxes keep a 4px gap from their row card on mobile.
|
||||
- **Mobile adaptation**: modals at 95% width with nested cards stepping in per layer; the drawer menu closes on tapping outside and starts collapsed with no first-load flash; toast buttons wrap instead of overflowing.
|
||||
- **Online update check**: click the footer version to check for a new release and install it in one click, with four clear states (checking / up to date / update available / failed); mobile footers show the theme version too.
|
||||
- **Notifications**: success messages (e.g. "password changed") appear as a centered glass dialog that closes after 6 seconds.
|
||||
- **Lock screen (login)**: macOS-style frosted login card + Monterey wallpaper (light/dark) + optional **Bing daily wallpaper** (auto-fetched and cached) + a glowing waterdrop logo; mode, accent and opacity picked before signing in can be applied with one click after login.
|
||||
- **Tooltips**: frosted glass background, shown at the page top level (never hidden behind a neighbouring card), auto-avoid viewport edges, mutual exclusion against stale popups.
|
||||
- **SVG icons**: network / interface status icons taken from [xylz0928/luci-mod][luci-mod] `immortalwrt-24.10`; UI element icons (sun / moon / auto / refresh / lock / search / close / chevron) are built-in SVGs.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
- **2026-09-28 · v1.0 (major release)**: opacity slider + online update + lock screen polish + wide-table adaptivity
|
||||
- **Glass opacity slider**: drag 0–100 in the top-bar color area for an instant preview, click the tick to reset; menus, buttons and accent backgrounds follow along, with separate light / dark defaults; also on the lock screen, and the setting stays on your router across devices
|
||||
- **Online update check**: click the footer version to check and install a new release; checking / up to date / update available / failed are all clearly shown, and failures report an error instead of hanging; mobile footers show the version too, with bigger buttons
|
||||
- **Lock screen**: mode, accent and opacity picked before signing in are offered with one click after login (30-second countdown, dismissible); the logo gets a frosted glass glow; fixed mode-switch flicker and accidental submits
|
||||
- **Dropdowns**: refreshed glass look — width follows the longest option, menus flip up near the edge, no flash on click; clearer highlights in dark mode; previously broken dropdowns (e.g. wireless settings) work again
|
||||
- **Notifications**: success messages (e.g. "password changed") now show as a centered glass dialog that closes after 6 seconds; buttons wrap on phones instead of overflowing
|
||||
- **Wide tables**: when a table no longer fits the screen, action buttons stack one per line so text keeps its width — no more squeezed or clipped columns; on phones the table stays on screen with no sideways scrolling
|
||||
- **Fixes**: the sidebar slider no longer sticks to the previous category; OpenClash no longer flashes dark on open; the selected tab uses a high-contrast color for dark mode
|
||||
|
||||
> 📜 Full changelog (all versions since v0.1) lives in **[ChangeLogs_EN.md](ChangeLogs_EN.md)**.
|
||||
|
||||
## Compatibility
|
||||
|
||||
Targets modern LuCI environments based on [OpenWrt][official] and [ImmortalWrt][immortalwrt] (LuCI ≥ 23, OpenWrt 23.05 / 24.10 / master).
|
||||
|
||||
## Building & Installation
|
||||
|
||||
This package uses LuCI's `luci.mk` packaging (`include $(TOPDIR)/feeds/luci/luci.mk`), so the build tree needs `./scripts/feeds update -a && ./scripts/feeds install -a` (includes the luci feed).
|
||||
|
||||
Put this directory into `package/luci-theme-liquid/` (or `feeds/luci/themes/luci-theme-liquid/`) of the OpenWrt source tree, enable the package in `.config`, then build:
|
||||
|
||||
```bash
|
||||
cd openwrt/package
|
||||
git clone https://github.com/xylz0928/luci-theme-liquid.git
|
||||
make menuconfig # choose LUCI → Themes → luci-theme-liquid
|
||||
make -j1 V=s
|
||||
```
|
||||
|
||||
Or build only this package:
|
||||
|
||||
```sh
|
||||
# enable it in .config (either way)
|
||||
make menuconfig # LuCI → Themes → luci-theme-liquid
|
||||
# or
|
||||
echo 'CONFIG_PACKAGE_luci-theme-liquid=y' >> .config && make defconfig
|
||||
|
||||
make package/luci-theme-liquid/compile -j4 V=s
|
||||
```
|
||||
|
||||
> Note: `make package/<name>/compile` only really builds packages enabled (`=y`/`=m`) in `.config`; otherwise make no-ops (just prints `Entering/Leaving`), which is not a successful build.
|
||||
|
||||
The produced `bin/packages/<arch>/base/luci-theme-liquid-0.3-r<rel>.apk` (or `.ipk`) can be installed with `apk` / `opkg`:
|
||||
|
||||
```sh
|
||||
apk add --allow-untrusted luci-theme-liquid-0.3-r1.apk
|
||||
```
|
||||
|
||||
On first install the theme is registered automatically (`luci.themes.Liquid=/luci-static/liquid`); if `luci.main.mediaurlbase` is not set it is set to the theme, otherwise pick **Liquid** manually at **System → Advanced → Theme**.
|
||||
|
||||
### Directory layout
|
||||
|
||||
```
|
||||
luci-theme-liquid/
|
||||
├── Makefile # OpenWrt package (works inside luci feed or a standalone package dir)
|
||||
├── logo.svg # theme logo (waterdrop + Liquid)
|
||||
├── htdocs/luci-static/liquid/ # theme assets (/luci-static/liquid/)
|
||||
│ ├── cascade.css # all styles (vars / menu / tab / cbi / dashboard / lock screen)
|
||||
│ ├── main.js # mode switch, dropdown flip, tooltip portal, config saving
|
||||
│ ├── logo.svg / logo.png # theme logo
|
||||
│ ├── img/ # lock screen wallpapers (MontereyDark / MontereyLight)
|
||||
│ ├── icons/ # network status SVG icons (from luci-mod immortalwrt-24.10)
|
||||
│ └── svg/ # UI element SVGs + dashboard icons
|
||||
├── htdocs/luci-static/resources/ # shared resources (/luci-static/resources/)
|
||||
│ ├── menu-liquid.js # sidebar menu / tab rendering (L.require('menu-liquid'))
|
||||
│ └── view/liquid/sysauth.js # lock screen login view (ui.showModal 'login')
|
||||
├── root/usr/share/ucode/luci/ # ucode controller (config save endpoint)
|
||||
│ └── controller/liquid.uc
|
||||
├── root/usr/share/luci/menu.d/ # dispatcher route registration
|
||||
│ └── liquid.json
|
||||
├── ucode/template/themes/liquid/ # theme ucode templates
|
||||
│ ├── header.ut / footer.ut # page skeleton (uci config / anti-flash / Bing wallpaper cache)
|
||||
│ └── sysauth.ut # login template (blank_page + centered login box)
|
||||
└── root/etc/uci-defaults/ # registers luci.themes.Liquid on install
|
||||
```
|
||||
|
||||
## Screenshots
|
||||
|
||||
- 桌面端
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
- 移动端
|
||||
|
||||

|
||||

|
||||
|
||||
## Credits
|
||||
|
||||
- Wallpapers: macOS Monterey (Bright/Dark), from [xylz0928/luci-mod][luci-mod] `Background/`.
|
||||
- Network status SVG icons: from [xylz0928/luci-mod][luci-mod] `immortalwrt-24.10` branch `feeds/luci/modules/luci-base/htdocs/luci-static/resources/icons/`.
|
||||
- dashboard module icons (router / internet / wireless / devices): from official OpenWrt [luci-mod-dashboard](https://github.com/openwrt/luci/tree/master/modules/luci-mod-dashboard).
|
||||
- Menu rendering logic references [luci-theme-openwrt-2020](https://github.com/openwrt/luci/tree/master/themes/luci-theme-openwrt-2020), lock screen view references [luci-theme-bootstrap](https://github.com/openwrt/luci/tree/master/themes/luci-theme-bootstrap) (Apache-2.0).
|
||||
|
||||
## 🍡 Buy me a cup of TOKEN 😜
|
||||
**Appreciate Your Like!**
|
||||

|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 21.25 25.648438 L 15 25.648438 L 15 33.148438 L 25 33.148438 L 25 25.648438 Z M 22.5 30.648438 L 17.5 30.648438 L 17.5 28.148438 L 22.5 28.148438 Z M 22.5 30.648438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.901963%,54.901963%,54.901963%);fill-opacity:1;" d="M 1.25 28.148438 L 15 28.148438 L 15 30.648438 L 1.25 30.648438 Z M 18.75 25.648438 L 21.25 25.648438 L 21.25 21.855469 L 18.75 21.855469 Z M 25 28.148438 L 25 30.648438 L 38.75 30.648438 L 38.75 28.148438 Z M 25 28.148438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 38.75 19.976562 C 38.75 21.011719 37.910156 21.851562 36.875 21.851562 L 3.125 21.851562 C 2.089844 21.851562 1.25 21.011719 1.25 19.976562 L 1.25 8.726562 C 1.25 7.691406 2.089844 6.851562 3.125 6.851562 L 36.875 6.851562 C 37.910156 6.851562 38.75 7.691406 38.75 8.726562 Z M 36.25 10.601562 C 36.25 9.914062 35.691406 9.351562 35 9.351562 L 5 9.351562 C 4.308594 9.351562 3.75 9.914062 3.75 10.601562 L 3.75 18.101562 C 3.75 18.792969 4.308594 19.351562 5 19.351562 L 35 19.351562 C 35.691406 19.351562 36.25 18.792969 36.25 18.101562 Z M 36.25 10.601562 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 5.453125 15.1875 L 6.5625 15.1875 L 6.5625 16.296875 L 7.117188 16.296875 L 7.117188 16.851562 L 9.894531 16.851562 L 9.894531 16.296875 L 10.453125 16.296875 L 10.453125 15.1875 L 11.5625 15.1875 L 11.5625 11.855469 L 5.453125 11.855469 Z M 13.113281 15.1875 L 14.226562 15.1875 L 14.226562 16.296875 L 14.78125 16.296875 L 14.78125 16.851562 L 17.558594 16.851562 L 17.558594 16.296875 L 18.113281 16.296875 L 18.113281 15.1875 L 19.226562 15.1875 L 19.226562 11.855469 L 13.113281 11.855469 Z M 20.773438 15.1875 L 21.886719 15.1875 L 21.886719 16.296875 L 22.441406 16.296875 L 22.441406 16.851562 L 25.222656 16.851562 L 25.222656 16.296875 L 25.773438 16.296875 L 25.773438 15.1875 L 26.886719 15.1875 L 26.886719 11.855469 L 20.773438 11.855469 Z M 28.4375 15.1875 L 29.546875 15.1875 L 29.546875 16.296875 L 30.105469 16.296875 L 30.105469 16.851562 L 32.882812 16.851562 L 32.882812 16.296875 L 33.4375 16.296875 L 33.4375 15.1875 L 34.546875 15.1875 L 34.546875 11.855469 L 28.4375 11.855469 Z M 28.4375 15.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 21.25 25.648438 L 15 25.648438 L 15 33.148438 L 25 33.148438 L 25 25.648438 Z M 22.5 30.648438 L 17.5 30.648438 L 17.5 28.148438 L 22.5 28.148438 Z M 22.5 30.648438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.901963%,54.901963%,54.901963%);fill-opacity:1;" d="M 1.25 28.148438 L 15 28.148438 L 15 30.648438 L 1.25 30.648438 Z M 18.75 25.648438 L 21.25 25.648438 L 21.25 21.855469 L 18.75 21.855469 Z M 25 28.148438 L 25 30.648438 L 38.75 30.648438 L 38.75 28.148438 Z M 25 28.148438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 38.75 19.976562 C 38.75 21.011719 37.910156 21.851562 36.875 21.851562 L 3.125 21.851562 C 2.089844 21.851562 1.25 21.011719 1.25 19.976562 L 1.25 8.726562 C 1.25 7.691406 2.089844 6.851562 3.125 6.851562 L 36.875 6.851562 C 37.910156 6.851562 38.75 7.691406 38.75 8.726562 Z M 36.25 10.601562 C 36.25 9.914062 35.691406 9.351562 35 9.351562 L 5 9.351562 C 4.308594 9.351562 3.75 9.914062 3.75 10.601562 L 3.75 18.101562 C 3.75 18.792969 4.308594 19.351562 5 19.351562 L 35 19.351562 C 35.691406 19.351562 36.25 18.792969 36.25 18.101562 Z M 36.25 10.601562 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 5.453125 15.1875 L 6.5625 15.1875 L 6.5625 16.296875 L 7.117188 16.296875 L 7.117188 16.851562 L 9.894531 16.851562 L 9.894531 16.296875 L 10.453125 16.296875 L 10.453125 15.1875 L 11.5625 15.1875 L 11.5625 11.855469 L 5.453125 11.855469 Z M 13.113281 15.1875 L 14.226562 15.1875 L 14.226562 16.296875 L 14.78125 16.296875 L 14.78125 16.851562 L 17.558594 16.851562 L 17.558594 16.296875 L 18.113281 16.296875 L 18.113281 15.1875 L 19.226562 15.1875 L 19.226562 11.855469 L 13.113281 11.855469 Z M 20.773438 15.1875 L 21.886719 15.1875 L 21.886719 16.296875 L 22.441406 16.296875 L 22.441406 16.851562 L 25.222656 16.851562 L 25.222656 16.296875 L 25.773438 16.296875 L 25.773438 15.1875 L 26.886719 15.1875 L 26.886719 11.855469 L 20.773438 11.855469 Z M 28.4375 15.1875 L 29.546875 15.1875 L 29.546875 16.296875 L 30.105469 16.296875 L 30.105469 16.851562 L 32.882812 16.851562 L 32.882812 16.296875 L 33.4375 16.296875 L 33.4375 15.1875 L 34.546875 15.1875 L 34.546875 11.855469 L 28.4375 11.855469 Z M 28.4375 15.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 21.25 25.648438 L 15 25.648438 L 15 33.148438 L 25 33.148438 L 25 25.648438 Z M 22.5 30.648438 L 17.5 30.648438 L 17.5 28.148438 L 22.5 28.148438 Z M 22.5 30.648438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.901963%,54.901963%,54.901963%);fill-opacity:1;" d="M 1.25 28.148438 L 15 28.148438 L 15 30.648438 L 1.25 30.648438 Z M 18.75 25.648438 L 21.25 25.648438 L 21.25 21.855469 L 18.75 21.855469 Z M 25 28.148438 L 25 30.648438 L 38.75 30.648438 L 38.75 28.148438 Z M 25 28.148438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 38.75 19.976562 C 38.75 21.011719 37.910156 21.851562 36.875 21.851562 L 3.125 21.851562 C 2.089844 21.851562 1.25 21.011719 1.25 19.976562 L 1.25 8.726562 C 1.25 7.691406 2.089844 6.851562 3.125 6.851562 L 36.875 6.851562 C 37.910156 6.851562 38.75 7.691406 38.75 8.726562 Z M 36.25 10.601562 C 36.25 9.914062 35.691406 9.351562 35 9.351562 L 5 9.351562 C 4.308594 9.351562 3.75 9.914062 3.75 10.601562 L 3.75 18.101562 C 3.75 18.792969 4.308594 19.351562 5 19.351562 L 35 19.351562 C 35.691406 19.351562 36.25 18.792969 36.25 18.101562 Z M 36.25 10.601562 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 5.453125 15.1875 L 6.5625 15.1875 L 6.5625 16.296875 L 7.117188 16.296875 L 7.117188 16.851562 L 9.894531 16.851562 L 9.894531 16.296875 L 10.453125 16.296875 L 10.453125 15.1875 L 11.5625 15.1875 L 11.5625 11.855469 L 5.453125 11.855469 Z M 13.113281 15.1875 L 14.226562 15.1875 L 14.226562 16.296875 L 14.78125 16.296875 L 14.78125 16.851562 L 17.558594 16.851562 L 17.558594 16.296875 L 18.113281 16.296875 L 18.113281 15.1875 L 19.226562 15.1875 L 19.226562 11.855469 L 13.113281 11.855469 Z M 20.773438 15.1875 L 21.886719 15.1875 L 21.886719 16.296875 L 22.441406 16.296875 L 22.441406 16.851562 L 25.222656 16.851562 L 25.222656 16.296875 L 25.773438 16.296875 L 25.773438 15.1875 L 26.886719 15.1875 L 26.886719 11.855469 L 20.773438 11.855469 Z M 28.4375 15.1875 L 29.546875 15.1875 L 29.546875 16.296875 L 30.105469 16.296875 L 30.105469 16.851562 L 32.882812 16.851562 L 32.882812 16.296875 L 33.4375 16.296875 L 33.4375 15.1875 L 34.546875 15.1875 L 34.546875 11.855469 L 28.4375 11.855469 Z M 28.4375 15.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 21.25 25.648438 L 15 25.648438 L 15 33.148438 L 25 33.148438 L 25 25.648438 Z M 22.5 30.648438 L 17.5 30.648438 L 17.5 28.148438 L 22.5 28.148438 Z M 22.5 30.648438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.901963%,54.901963%,54.901963%);fill-opacity:1;" d="M 1.25 28.148438 L 15 28.148438 L 15 30.648438 L 1.25 30.648438 Z M 18.75 25.648438 L 21.25 25.648438 L 21.25 21.855469 L 18.75 21.855469 Z M 25 28.148438 L 25 30.648438 L 38.75 30.648438 L 38.75 28.148438 Z M 25 28.148438 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 38.75 19.976562 C 38.75 21.011719 37.910156 21.851562 36.875 21.851562 L 3.125 21.851562 C 2.089844 21.851562 1.25 21.011719 1.25 19.976562 L 1.25 8.726562 C 1.25 7.691406 2.089844 6.851562 3.125 6.851562 L 36.875 6.851562 C 37.910156 6.851562 38.75 7.691406 38.75 8.726562 Z M 36.25 10.601562 C 36.25 9.914062 35.691406 9.351562 35 9.351562 L 5 9.351562 C 4.308594 9.351562 3.75 9.914062 3.75 10.601562 L 3.75 18.101562 C 3.75 18.792969 4.308594 19.351562 5 19.351562 L 35 19.351562 C 35.691406 19.351562 36.25 18.792969 36.25 18.101562 Z M 36.25 10.601562 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 5.453125 15.1875 L 6.5625 15.1875 L 6.5625 16.296875 L 7.117188 16.296875 L 7.117188 16.851562 L 9.894531 16.851562 L 9.894531 16.296875 L 10.453125 16.296875 L 10.453125 15.1875 L 11.5625 15.1875 L 11.5625 11.855469 L 5.453125 11.855469 Z M 13.113281 15.1875 L 14.226562 15.1875 L 14.226562 16.296875 L 14.78125 16.296875 L 14.78125 16.851562 L 17.558594 16.851562 L 17.558594 16.296875 L 18.113281 16.296875 L 18.113281 15.1875 L 19.226562 15.1875 L 19.226562 11.855469 L 13.113281 11.855469 Z M 20.773438 15.1875 L 21.886719 15.1875 L 21.886719 16.296875 L 22.441406 16.296875 L 22.441406 16.851562 L 25.222656 16.851562 L 25.222656 16.296875 L 25.773438 16.296875 L 25.773438 15.1875 L 26.886719 15.1875 L 26.886719 11.855469 L 20.773438 11.855469 Z M 28.4375 15.1875 L 29.546875 15.1875 L 29.546875 16.296875 L 30.105469 16.296875 L 30.105469 16.851562 L 32.882812 16.851562 L 32.882812 16.296875 L 33.4375 16.296875 L 33.4375 15.1875 L 34.546875 15.1875 L 34.546875 11.855469 L 28.4375 11.855469 Z M 28.4375 15.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 30.761719 38.960938 L 8.480469 38.960938 C 5.519531 38.960938 3.121094 36.558594 3.121094 33.601562 L 3.121094 16.800781 C 3.121094 13.839844 5.519531 11.441406 8.480469 11.441406 L 30.800781 11.441406 C 33.761719 11.441406 36.160156 13.839844 36.160156 16.800781 L 36.160156 33.601562 C 36.121094 36.558594 33.71875 38.960938 30.761719 38.960938 Z M 8.480469 14.199219 C 7.039062 14.199219 5.878906 15.359375 5.878906 16.800781 L 5.878906 33.601562 C 5.878906 35.039062 7.039062 36.199219 8.480469 36.199219 L 30.800781 36.199219 C 32.238281 36.199219 33.398438 35.039062 33.398438 33.601562 L 33.398438 16.800781 C 33.398438 15.359375 32.238281 14.199219 30.800781 14.199219 Z M 29.238281 11.441406 L 26.480469 11.441406 C 26.480469 7.640625 23.398438 4.558594 19.601562 4.558594 C 15.800781 4.558594 12.71875 7.640625 12.71875 11.441406 L 9.960938 11.441406 C 9.960938 6.121094 14.320312 1.800781 19.601562 1.800781 C 24.921875 1.800781 29.238281 6.121094 29.238281 11.441406 Z M 29.238281 11.441406 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 19.601562 31.398438 C 18.441406 31.398438 17.519531 30.480469 17.519531 29.320312 L 17.519531 21.078125 C 17.519531 19.921875 18.441406 19 19.601562 19 C 20.761719 19 21.679688 19.921875 21.679688 21.078125 L 21.679688 29.320312 C 21.679688 30.480469 20.761719 31.398438 19.601562 31.398438 Z M 19.601562 31.398438 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 31.503906 40 L 8.457031 40 C 5.394531 40 2.910156 37.765625 2.910156 35.007812 L 2.910156 19.359375 C 2.910156 16.601562 5.394531 14.367188 8.457031 14.367188 L 31.542969 14.367188 C 34.605469 14.367188 37.089844 16.601562 37.089844 19.359375 L 37.089844 35.007812 C 37.046875 37.765625 34.566406 40 31.503906 40 Z M 8.449219 17.214844 C 6.960938 17.214844 5.757812 18.265625 5.757812 19.570312 L 5.757812 34.796875 C 5.757812 36.101562 6.960938 37.152344 8.449219 37.152344 L 31.550781 37.152344 C 33.039062 37.152344 34.242188 36.101562 34.242188 34.796875 L 34.242188 19.574219 C 34.242188 18.269531 33.039062 17.21875 31.550781 17.21875 Z M 29.464844 5.839844 L 26.621094 7.429688 C 24.429688 3.507812 19.476562 2.101562 15.554688 4.292969 C 11.636719 6.484375 10.230469 11.4375 12.421875 15.359375 L 9.574219 16.949219 C 6.507812 11.460938 8.519531 4.488281 13.964844 1.445312 C 19.457031 -1.621094 26.402344 0.351562 29.46875 5.839844 Z M 31.390625 14.363281 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 20 31.453125 C 18.808594 31.453125 17.863281 30.820312 17.863281 30.019531 L 17.863281 24.34375 C 17.863281 23.542969 18.808594 22.910156 20 22.910156 C 21.191406 22.910156 22.136719 23.546875 22.136719 24.34375 L 22.136719 30.023438 C 22.136719 30.820312 21.191406 31.453125 20 31.453125 Z M 20 31.453125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 28.050781 13.054688 C 28.050781 13.820312 27.429688 14.433594 26.667969 14.433594 L 13.332031 14.433594 C 12.5625 14.433594 11.949219 13.8125 11.949219 13.054688 L 11.949219 3.476562 C 11.949219 2.710938 12.570312 2.097656 13.332031 2.097656 L 26.667969 2.097656 C 27.4375 2.097656 28.050781 2.71875 28.050781 3.476562 Z M 28.050781 13.054688 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 26.667969 15.175781 C 27.835938 15.175781 28.792969 14.21875 28.792969 13.054688 L 28.792969 3.476562 C 28.792969 2.308594 27.835938 1.355469 26.667969 1.355469 L 13.332031 1.355469 C 12.164062 1.355469 11.207031 2.308594 11.207031 3.476562 L 11.207031 13.054688 C 11.207031 14.21875 12.164062 15.175781 13.332031 15.175781 L 19.257812 15.175781 L 19.257812 17.152344 L 17.3125 17.152344 C 16.90625 17.152344 16.570312 17.484375 16.570312 17.894531 C 16.570312 18.300781 16.90625 18.636719 17.3125 18.636719 L 22.675781 18.636719 C 23.085938 18.636719 23.421875 18.300781 23.421875 17.894531 C 23.421875 17.484375 23.085938 17.152344 22.675781 17.152344 L 20.734375 17.152344 L 20.734375 15.175781 Z M 12.6875 13.054688 L 12.6875 3.476562 C 12.6875 3.125 12.972656 2.832031 13.332031 2.832031 L 26.667969 2.832031 C 27.019531 2.832031 27.3125 3.117188 27.3125 3.476562 L 27.3125 13.054688 C 27.3125 13.402344 27.027344 13.699219 26.667969 13.699219 L 13.332031 13.699219 C 12.980469 13.699219 12.6875 13.414062 12.6875 13.054688 Z M 12.6875 13.054688 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 16.839844 33.070312 C 16.839844 33.835938 16.21875 34.449219 15.460938 34.449219 L 2.121094 34.449219 C 1.355469 34.449219 0.742188 33.828125 0.742188 33.070312 L 0.742188 23.492188 C 0.742188 22.726562 1.363281 22.113281 2.121094 22.113281 L 15.460938 22.113281 C 16.230469 22.113281 16.839844 22.734375 16.839844 23.492188 Z M 39.265625 33.070312 C 39.265625 33.835938 38.644531 34.449219 37.886719 34.449219 L 24.546875 34.449219 C 23.78125 34.449219 23.167969 33.828125 23.167969 33.070312 L 23.167969 23.492188 C 23.167969 22.726562 23.789062 22.113281 24.546875 22.113281 L 37.878906 22.113281 C 38.644531 22.113281 39.257812 22.734375 39.257812 23.492188 L 39.257812 33.070312 Z M 39.265625 33.070312 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 15.453125 21.363281 L 2.121094 21.363281 C 0.957031 21.363281 0 22.316406 0 23.484375 L 0 33.0625 C 0 34.226562 0.957031 35.183594 2.121094 35.183594 L 8.050781 35.183594 L 8.050781 37.160156 L 6.105469 37.160156 C 5.699219 37.160156 5.363281 37.492188 5.363281 37.902344 C 5.363281 38.308594 5.699219 38.644531 6.105469 38.644531 L 11.46875 38.644531 C 11.878906 38.644531 12.210938 38.308594 12.210938 37.902344 C 12.210938 37.492188 11.878906 37.160156 11.46875 37.160156 L 9.527344 37.160156 L 9.527344 35.183594 L 15.453125 35.183594 C 16.621094 35.183594 17.574219 34.226562 17.574219 33.0625 L 17.574219 23.492188 C 17.574219 22.316406 16.628906 21.363281 15.453125 21.363281 Z M 16.097656 33.070312 C 16.097656 33.421875 15.8125 33.714844 15.453125 33.714844 L 2.121094 33.714844 C 1.769531 33.714844 1.476562 33.429688 1.476562 33.070312 L 1.476562 23.492188 C 1.476562 23.144531 1.761719 22.847656 2.121094 22.847656 L 15.460938 22.847656 C 15.8125 22.847656 16.105469 23.132812 16.105469 23.492188 L 16.105469 33.070312 Z M 37.878906 21.363281 L 24.546875 21.363281 C 23.378906 21.363281 22.425781 22.316406 22.425781 23.484375 L 22.425781 33.0625 C 22.425781 34.226562 23.378906 35.183594 24.546875 35.183594 L 30.472656 35.183594 L 30.472656 37.160156 L 28.53125 37.160156 C 28.121094 37.160156 27.789062 37.492188 27.789062 37.902344 C 27.789062 38.308594 28.121094 38.644531 28.53125 38.644531 L 33.894531 38.644531 C 34.300781 38.644531 34.636719 38.308594 34.636719 37.902344 C 34.636719 37.492188 34.300781 37.160156 33.894531 37.160156 L 31.949219 37.160156 L 31.949219 35.183594 L 37.878906 35.183594 C 39.042969 35.183594 40 34.226562 40 33.0625 L 40 23.492188 C 40.007812 22.316406 39.054688 21.363281 37.878906 21.363281 Z M 38.523438 33.070312 C 38.523438 33.421875 38.238281 33.714844 37.878906 33.714844 L 24.546875 33.714844 C 24.195312 33.714844 23.902344 33.429688 23.902344 33.070312 L 23.902344 23.492188 C 23.902344 23.144531 24.1875 22.847656 24.546875 22.847656 L 37.878906 22.847656 C 38.226562 22.847656 38.523438 23.132812 38.523438 23.492188 Z M 3.003906 18.628906 C 3.414062 18.628906 3.746094 18.292969 3.746094 17.886719 L 3.746094 7.722656 L 8.1875 7.722656 C 8.597656 7.722656 8.929688 7.386719 8.929688 6.980469 C 8.929688 6.570312 8.597656 6.238281 8.1875 6.238281 L 3.003906 6.238281 C 2.597656 6.238281 2.261719 6.570312 2.261719 6.980469 L 2.261719 17.894531 C 2.261719 18.300781 2.597656 18.628906 3.003906 18.628906 Z M 36.996094 18.628906 C 37.402344 18.628906 37.738281 18.292969 37.738281 17.886719 L 37.738281 6.980469 C 37.738281 6.570312 37.402344 6.238281 36.996094 6.238281 L 31.8125 6.238281 C 31.402344 6.238281 31.070312 6.570312 31.070312 6.980469 C 31.070312 7.386719 31.402344 7.722656 31.8125 7.722656 L 36.253906 7.722656 L 36.253906 17.894531 C 36.261719 18.300781 36.585938 18.628906 36.996094 18.628906 Z M 36.996094 18.628906 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 28.050781 13.054688 C 28.050781 13.820312 27.429688 14.433594 26.667969 14.433594 L 13.332031 14.433594 C 12.5625 14.433594 11.949219 13.8125 11.949219 13.054688 L 11.949219 3.476562 C 11.949219 2.710938 12.570312 2.097656 13.332031 2.097656 L 26.667969 2.097656 C 27.4375 2.097656 28.050781 2.71875 28.050781 3.476562 Z M 28.050781 13.054688 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 26.667969 15.175781 C 27.835938 15.175781 28.792969 14.21875 28.792969 13.054688 L 28.792969 3.476562 C 28.792969 2.308594 27.835938 1.355469 26.667969 1.355469 L 13.332031 1.355469 C 12.164062 1.355469 11.207031 2.308594 11.207031 3.476562 L 11.207031 13.054688 C 11.207031 14.21875 12.164062 15.175781 13.332031 15.175781 L 19.257812 15.175781 L 19.257812 17.152344 L 17.3125 17.152344 C 16.90625 17.152344 16.570312 17.484375 16.570312 17.894531 C 16.570312 18.300781 16.90625 18.636719 17.3125 18.636719 L 22.675781 18.636719 C 23.085938 18.636719 23.421875 18.300781 23.421875 17.894531 C 23.421875 17.484375 23.085938 17.152344 22.675781 17.152344 L 20.734375 17.152344 L 20.734375 15.175781 Z M 12.6875 13.054688 L 12.6875 3.476562 C 12.6875 3.125 12.972656 2.832031 13.332031 2.832031 L 26.667969 2.832031 C 27.019531 2.832031 27.3125 3.117188 27.3125 3.476562 L 27.3125 13.054688 C 27.3125 13.402344 27.027344 13.699219 26.667969 13.699219 L 13.332031 13.699219 C 12.980469 13.699219 12.6875 13.414062 12.6875 13.054688 Z M 12.6875 13.054688 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 16.839844 33.070312 C 16.839844 33.835938 16.21875 34.449219 15.460938 34.449219 L 2.121094 34.449219 C 1.355469 34.449219 0.742188 33.828125 0.742188 33.070312 L 0.742188 23.492188 C 0.742188 22.726562 1.363281 22.113281 2.121094 22.113281 L 15.460938 22.113281 C 16.230469 22.113281 16.839844 22.734375 16.839844 23.492188 Z M 39.265625 33.070312 C 39.265625 33.835938 38.644531 34.449219 37.886719 34.449219 L 24.546875 34.449219 C 23.78125 34.449219 23.167969 33.828125 23.167969 33.070312 L 23.167969 23.492188 C 23.167969 22.726562 23.789062 22.113281 24.546875 22.113281 L 37.878906 22.113281 C 38.644531 22.113281 39.257812 22.734375 39.257812 23.492188 L 39.257812 33.070312 Z M 39.265625 33.070312 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 15.453125 21.363281 L 2.121094 21.363281 C 0.957031 21.363281 0 22.316406 0 23.484375 L 0 33.0625 C 0 34.226562 0.957031 35.183594 2.121094 35.183594 L 8.050781 35.183594 L 8.050781 37.160156 L 6.105469 37.160156 C 5.699219 37.160156 5.363281 37.492188 5.363281 37.902344 C 5.363281 38.308594 5.699219 38.644531 6.105469 38.644531 L 11.46875 38.644531 C 11.878906 38.644531 12.210938 38.308594 12.210938 37.902344 C 12.210938 37.492188 11.878906 37.160156 11.46875 37.160156 L 9.527344 37.160156 L 9.527344 35.183594 L 15.453125 35.183594 C 16.621094 35.183594 17.574219 34.226562 17.574219 33.0625 L 17.574219 23.492188 C 17.574219 22.316406 16.628906 21.363281 15.453125 21.363281 Z M 16.097656 33.070312 C 16.097656 33.421875 15.8125 33.714844 15.453125 33.714844 L 2.121094 33.714844 C 1.769531 33.714844 1.476562 33.429688 1.476562 33.070312 L 1.476562 23.492188 C 1.476562 23.144531 1.761719 22.847656 2.121094 22.847656 L 15.460938 22.847656 C 15.8125 22.847656 16.105469 23.132812 16.105469 23.492188 L 16.105469 33.070312 Z M 37.878906 21.363281 L 24.546875 21.363281 C 23.378906 21.363281 22.425781 22.316406 22.425781 23.484375 L 22.425781 33.0625 C 22.425781 34.226562 23.378906 35.183594 24.546875 35.183594 L 30.472656 35.183594 L 30.472656 37.160156 L 28.53125 37.160156 C 28.121094 37.160156 27.789062 37.492188 27.789062 37.902344 C 27.789062 38.308594 28.121094 38.644531 28.53125 38.644531 L 33.894531 38.644531 C 34.300781 38.644531 34.636719 38.308594 34.636719 37.902344 C 34.636719 37.492188 34.300781 37.160156 33.894531 37.160156 L 31.949219 37.160156 L 31.949219 35.183594 L 37.878906 35.183594 C 39.042969 35.183594 40 34.226562 40 33.0625 L 40 23.492188 C 40.007812 22.316406 39.054688 21.363281 37.878906 21.363281 Z M 38.523438 33.070312 C 38.523438 33.421875 38.238281 33.714844 37.878906 33.714844 L 24.546875 33.714844 C 24.195312 33.714844 23.902344 33.429688 23.902344 33.070312 L 23.902344 23.492188 C 23.902344 23.144531 24.1875 22.847656 24.546875 22.847656 L 37.878906 22.847656 C 38.226562 22.847656 38.523438 23.132812 38.523438 23.492188 Z M 3.003906 18.628906 C 3.414062 18.628906 3.746094 18.292969 3.746094 17.886719 L 3.746094 7.722656 L 8.1875 7.722656 C 8.597656 7.722656 8.929688 7.386719 8.929688 6.980469 C 8.929688 6.570312 8.597656 6.238281 8.1875 6.238281 L 3.003906 6.238281 C 2.597656 6.238281 2.261719 6.570312 2.261719 6.980469 L 2.261719 17.894531 C 2.261719 18.300781 2.597656 18.628906 3.003906 18.628906 Z M 36.996094 18.628906 C 37.402344 18.628906 37.738281 18.292969 37.738281 17.886719 L 37.738281 6.980469 C 37.738281 6.570312 37.402344 6.238281 36.996094 6.238281 L 31.8125 6.238281 C 31.402344 6.238281 31.070312 6.570312 31.070312 6.980469 C 31.070312 7.386719 31.402344 7.722656 31.8125 7.722656 L 36.253906 7.722656 L 36.253906 17.894531 C 36.261719 18.300781 36.585938 18.628906 36.996094 18.628906 Z M 36.996094 18.628906 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,2 @@
|
||||
<svg width="48" height="48" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><rect x="11" y="1" width="2" height="5" opacity=".14"/><rect x="11" y="1" width="2" height="5" transform="rotate(30 12 12)" opacity=".29"/><rect x="11" y="1" width="2" height="5" transform="rotate(60 12 12)" opacity=".43"/><rect x="11" y="1" width="2" height="5" transform="rotate(90 12 12)" opacity=".57"/><rect x="11" y="1" width="2" height="5" transform="rotate(120 12 12)" opacity=".71"/><rect x="11" y="1" width="2" height="5" transform="rotate(150 12 12)" opacity=".86"/><rect x="11" y="1" width="2" height="5" transform="rotate(180 12 12)"/><animateTransform attributeName="transform" type="rotate" calcMode="discrete" dur="0.75s" values="0 12 12;30 12 12;60 12 12;90 12 12;120 12 12;150 12 12;180 12 12;210 12 12;240 12 12;270 12 12;300 12 12;330 12 12;360 12 12" repeatCount="indefinite"/></g></svg>
|
||||
<!-- https://github.com/n3r4zzurr0/svg-spinners MIT License -->
|
||||
|
After Width: | Height: | Size: 958 B |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 21.25 31.292969 L 18.75 31.292969 L 18.75 26.875 L 21.25 26.875 Z M 38.75 33.792969 L 25 33.792969 L 25 36.292969 L 38.75 36.292969 Z M 1.25 33.792969 L 1.25 36.292969 L 15 36.292969 L 15 33.792969 Z M 1.25 33.792969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 21.25 31.292969 L 15 31.292969 L 15 38.792969 L 25 38.792969 L 25 31.292969 Z M 22.5 36.292969 L 17.5 36.292969 L 17.5 33.792969 L 22.5 33.792969 Z M 22.5 36.292969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 4.375 1.457031 L 4.375 28.542969 L 35.625 28.542969 L 35.625 1.457031 Z M 33.542969 26.457031 L 6.457031 26.457031 L 6.457031 3.542969 L 33.542969 3.542969 Z M 33.542969 26.457031 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 12.707031 22.289062 L 14.792969 22.289062 L 14.792969 24.375 L 25.207031 24.375 L 25.207031 22.289062 L 27.292969 22.289062 L 27.292969 18.125 L 31.457031 18.125 L 31.457031 5.625 L 8.542969 5.625 L 8.542969 18.125 L 12.707031 18.125 Z M 12.707031 22.289062 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 25.207031 9.792969 L 27.292969 9.792969 L 27.292969 13.957031 L 25.207031 13.957031 Z M 21.042969 9.792969 L 23.125 9.792969 L 23.125 13.957031 L 21.042969 13.957031 Z M 16.875 9.792969 L 18.957031 9.792969 L 18.957031 13.957031 L 16.875 13.957031 Z M 12.707031 9.792969 L 14.792969 9.792969 L 14.792969 13.957031 L 12.707031 13.957031 Z M 12.707031 9.792969 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 21.25 31.292969 L 18.75 31.292969 L 18.75 26.875 L 21.25 26.875 Z M 38.75 33.792969 L 25 33.792969 L 25 36.292969 L 38.75 36.292969 Z M 1.25 33.792969 L 1.25 36.292969 L 15 36.292969 L 15 33.792969 Z M 1.25 33.792969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 21.25 31.292969 L 15 31.292969 L 15 38.792969 L 25 38.792969 L 25 31.292969 Z M 22.5 36.292969 L 17.5 36.292969 L 17.5 33.792969 L 22.5 33.792969 Z M 22.5 36.292969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(80.000001%,80.000001%,80.000001%);fill-opacity:1;" d="M 4.375 1.457031 L 4.375 28.542969 L 35.625 28.542969 L 35.625 1.457031 Z M 33.542969 26.457031 L 6.457031 26.457031 L 6.457031 3.542969 L 33.542969 3.542969 Z M 33.542969 26.457031 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 12.707031 22.289062 L 14.792969 22.289062 L 14.792969 24.375 L 25.207031 24.375 L 25.207031 22.289062 L 27.292969 22.289062 L 27.292969 18.125 L 31.457031 18.125 L 31.457031 5.625 L 8.542969 5.625 L 8.542969 18.125 L 12.707031 18.125 Z M 12.707031 22.289062 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 25.207031 9.792969 L 27.292969 9.792969 L 27.292969 13.957031 L 25.207031 13.957031 Z M 21.042969 9.792969 L 23.125 9.792969 L 23.125 13.957031 L 21.042969 13.957031 Z M 16.875 9.792969 L 18.957031 9.792969 L 18.957031 13.957031 L 16.875 13.957031 Z M 12.707031 9.792969 L 14.792969 9.792969 L 14.792969 13.957031 L 12.707031 13.957031 Z M 12.707031 9.792969 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 42.273438 14.421875 C 41.640625 15.179688 40.535156 15.300781 39.761719 14.71875 C 34.921875 11.101562 29.769531 8.539062 23.980469 8.539062 C 18.191406 8.539062 13.058594 11.101562 8.21875 14.71875 C 7.425781 15.300781 6.339844 15.179688 5.707031 14.441406 C 5.351562 14.019531 5.214844 13.539062 5.273438 13 C 5.332031 12.460938 5.589844 12.019531 6.003906 11.699219 C 11.496094 7.601562 17.441406 4.800781 23.980469 4.800781 C 30.519531 4.800781 36.464844 7.601562 41.957031 11.699219 C 42.390625 12.019531 42.628906 12.460938 42.6875 13 C 42.746094 13.539062 42.628906 14.019531 42.273438 14.421875 Z M 42.273438 14.421875 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 24 17.199219 C 27.929688 17.199219 31.328125 18.398438 34.6875 20.820312 C 35.476562 21.378906 36.542969 21.261719 37.15625 20.519531 C 37.511719 20.101562 37.648438 19.621094 37.589844 19.078125 C 37.53125 18.539062 37.253906 18.101562 36.820312 17.78125 C 32.828125 14.921875 28.679688 13.480469 24 13.480469 C 19.320312 13.480469 15.152344 14.921875 11.179688 17.78125 C 10.746094 18.101562 10.488281 18.539062 10.410156 19.078125 C 10.351562 19.621094 10.488281 20.121094 10.84375 20.519531 C 11.476562 21.261719 12.542969 21.398438 13.3125 20.820312 C 16.652344 18.421875 20.050781 17.199219 24 17.199219 Z M 24 25.621094 L 23.921875 25.621094 C 22.042969 25.621094 20.226562 26.179688 18.6875 27.21875 C 17.894531 27.738281 16.867188 27.601562 16.257812 26.878906 C 15.902344 26.460938 15.742188 25.960938 15.820312 25.398438 C 15.902344 24.839844 16.179688 24.398438 16.632812 24.101562 C 18.785156 22.660156 21.3125 21.878906 23.921875 21.878906 L 24.058594 21.878906 C 26.667969 21.878906 29.214844 22.660156 31.347656 24.101562 C 31.800781 24.398438 32.078125 24.859375 32.15625 25.398438 C 32.238281 25.960938 32.078125 26.460938 31.722656 26.878906 C 31.109375 27.601562 30.0625 27.738281 29.292969 27.21875 C 27.753906 26.179688 25.9375 25.621094 24.058594 25.621094 Z M 24 25.621094 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 21.214844 33.078125 C 21.175781 34.121094 21.707031 35.078125 22.578125 35.601562 C 23.445312 36.121094 24.554688 36.121094 25.421875 35.601562 C 26.292969 35.078125 26.824219 34.101562 26.785156 33.078125 C 26.726562 31.558594 25.5 30.359375 24 30.359375 C 22.5 30.359375 21.253906 31.558594 21.214844 33.078125 Z M 21.214844 33.078125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 42.273438 14.421875 C 41.640625 15.179688 40.535156 15.300781 39.761719 14.71875 C 34.921875 11.101562 29.769531 8.539062 23.980469 8.539062 C 18.191406 8.539062 13.058594 11.101562 8.21875 14.71875 C 7.425781 15.300781 6.339844 15.179688 5.707031 14.441406 C 5.351562 14.019531 5.214844 13.539062 5.273438 13 C 5.332031 12.460938 5.589844 12.019531 6.003906 11.699219 C 11.496094 7.601562 17.441406 4.800781 23.980469 4.800781 C 30.519531 4.800781 36.464844 7.601562 41.957031 11.699219 C 42.390625 12.019531 42.628906 12.460938 42.6875 13 C 42.746094 13.539062 42.628906 14.019531 42.273438 14.421875 Z M 42.273438 14.421875 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 24 17.199219 C 27.929688 17.199219 31.328125 18.398438 34.6875 20.820312 C 35.476562 21.378906 36.542969 21.261719 37.15625 20.519531 C 37.511719 20.101562 37.648438 19.621094 37.589844 19.078125 C 37.53125 18.539062 37.253906 18.101562 36.820312 17.78125 C 32.828125 14.921875 28.679688 13.480469 24 13.480469 C 19.320312 13.480469 15.152344 14.921875 11.179688 17.78125 C 10.746094 18.101562 10.488281 18.539062 10.410156 19.078125 C 10.351562 19.621094 10.488281 20.121094 10.84375 20.519531 C 11.476562 21.261719 12.542969 21.398438 13.3125 20.820312 C 16.652344 18.421875 20.050781 17.199219 24 17.199219 Z M 24 25.621094 L 23.921875 25.621094 C 22.042969 25.621094 20.226562 26.179688 18.6875 27.21875 C 17.894531 27.738281 16.867188 27.601562 16.257812 26.878906 C 15.902344 26.460938 15.742188 25.960938 15.820312 25.398438 C 15.902344 24.839844 16.179688 24.398438 16.632812 24.101562 C 18.785156 22.660156 21.3125 21.878906 23.921875 21.878906 L 24.058594 21.878906 C 26.667969 21.878906 29.214844 22.660156 31.347656 24.101562 C 31.800781 24.398438 32.078125 24.859375 32.15625 25.398438 C 32.238281 25.960938 32.078125 26.460938 31.722656 26.878906 C 31.109375 27.601562 30.0625 27.738281 29.292969 27.21875 C 27.753906 26.179688 25.9375 25.621094 24.058594 25.621094 Z M 24 25.621094 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(90.980393%,35.686275%,35.686275%);fill-opacity:1;" d="M 21.214844 33.078125 C 21.175781 34.121094 21.707031 35.078125 22.578125 35.601562 C 23.445312 36.121094 24.554688 36.121094 25.421875 35.601562 C 26.292969 35.078125 26.824219 34.101562 26.785156 33.078125 C 26.726562 31.558594 25.5 30.359375 24 30.359375 C 22.5 30.359375 21.253906 31.558594 21.214844 33.078125 Z M 21.214844 33.078125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 42.273438 18.421875 C 41.640625 19.179688 40.535156 19.300781 39.761719 18.71875 C 34.921875 15.101562 29.769531 12.539062 23.980469 12.539062 C 18.191406 12.539062 13.058594 15.101562 8.21875 18.71875 C 7.425781 19.300781 6.339844 19.179688 5.707031 18.441406 C 5.351562 18.019531 5.214844 17.539062 5.273438 17 C 5.332031 16.460938 5.589844 16.019531 6.003906 15.699219 C 11.496094 11.601562 17.441406 8.800781 23.980469 8.800781 C 30.519531 8.800781 36.464844 11.601562 41.957031 15.699219 C 42.390625 16.019531 42.628906 16.460938 42.6875 17 C 42.746094 17.539062 42.628906 18.019531 42.273438 18.421875 Z M 42.273438 18.421875 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 24 21.199219 C 27.929688 21.199219 31.328125 22.398438 34.6875 24.820312 C 35.476562 25.378906 36.542969 25.261719 37.15625 24.519531 C 37.511719 24.101562 37.648438 23.621094 37.589844 23.078125 C 37.53125 22.539062 37.253906 22.101562 36.820312 21.78125 C 32.828125 18.921875 28.679688 17.480469 24 17.480469 C 19.320312 17.480469 15.152344 18.921875 11.179688 21.78125 C 10.746094 22.101562 10.488281 22.539062 10.410156 23.078125 C 10.351562 23.621094 10.488281 24.121094 10.84375 24.519531 C 11.476562 25.261719 12.542969 25.398438 13.3125 24.820312 C 16.652344 22.421875 20.050781 21.199219 24 21.199219 Z M 24 21.199219 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 24 29.621094 L 23.921875 29.621094 C 22.042969 29.621094 20.226562 30.179688 18.6875 31.21875 C 17.894531 31.738281 16.867188 31.601562 16.257812 30.878906 C 15.902344 30.460938 15.742188 29.960938 15.820312 29.398438 C 15.902344 28.839844 16.179688 28.398438 16.632812 28.101562 C 18.785156 26.660156 21.3125 25.878906 23.921875 25.878906 L 24.058594 25.878906 C 26.667969 25.878906 29.214844 26.660156 31.347656 28.101562 C 31.800781 28.398438 32.078125 28.859375 32.15625 29.398438 C 32.238281 29.960938 32.078125 30.460938 31.722656 30.878906 C 31.109375 31.601562 30.0625 31.738281 29.292969 31.21875 C 27.753906 30.179688 25.9375 29.621094 24.058594 29.621094 Z M 21.214844 37.078125 C 21.175781 38.121094 21.707031 39.078125 22.578125 39.601562 C 23.445312 40.121094 24.554688 40.121094 25.421875 39.601562 C 26.292969 39.078125 26.824219 38.101562 26.785156 37.078125 C 26.726562 35.558594 25.5 34.359375 24 34.359375 C 22.5 34.359375 21.253906 35.558594 21.214844 37.078125 Z M 21.214844 37.078125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 42.292969 18.441406 C 41.640625 19.199219 40.554688 19.320312 39.761719 18.738281 C 34.921875 15.121094 29.75 12.578125 24 12.578125 C 18.25 12.578125 13.058594 15.121094 8.21875 18.738281 C 7.445312 19.320312 6.339844 19.199219 5.707031 18.441406 L 5.6875 18.421875 C 5.332031 18.019531 5.195312 17.539062 5.253906 16.980469 C 5.3125 16.441406 5.570312 16 5.984375 15.679688 C 11.515625 11.578125 17.441406 8.800781 23.980469 8.800781 C 30.519531 8.800781 36.464844 11.601562 41.957031 15.699219 C 42.390625 16.019531 42.628906 16.460938 42.6875 17 C 42.746094 17.539062 42.605469 18.019531 42.25 18.441406 Z M 42.292969 18.441406 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(90.196079%,63.529414%,23.529412%);fill-opacity:1;" d="M 24 21.21875 C 27.929688 21.21875 31.328125 22.421875 34.6875 24.839844 C 35.457031 25.398438 36.542969 25.28125 37.175781 24.539062 L 37.195312 24.519531 C 37.550781 24.101562 37.6875 23.621094 37.628906 23.078125 C 37.570312 22.539062 37.292969 22.101562 36.859375 21.78125 C 32.867188 18.921875 28.703125 17.480469 24.039062 17.480469 C 19.359375 17.480469 15.210938 18.921875 11.21875 21.78125 C 10.785156 22.101562 10.507812 22.539062 10.449219 23.078125 C 10.390625 23.621094 10.527344 24.101562 10.882812 24.519531 L 10.902344 24.539062 C 11.535156 25.28125 12.601562 25.421875 13.394531 24.839844 C 16.730469 22.441406 20.128906 21.21875 24.078125 21.21875 Z M 24 29.621094 L 23.921875 29.621094 C 22.042969 29.621094 20.226562 30.179688 18.6875 31.21875 C 17.894531 31.761719 16.867188 31.601562 16.257812 30.878906 C 15.902344 30.460938 15.761719 29.960938 15.820312 29.398438 C 15.902344 28.839844 16.179688 28.398438 16.632812 28.101562 C 18.785156 26.660156 21.3125 25.878906 23.921875 25.878906 L 24.078125 25.878906 C 26.6875 25.878906 29.234375 26.660156 31.367188 28.101562 C 31.820312 28.398438 32.097656 28.839844 32.179688 29.398438 C 32.257812 29.960938 32.097656 30.460938 31.742188 30.878906 C 31.132812 31.601562 30.082031 31.761719 29.3125 31.21875 C 27.773438 30.179688 25.957031 29.621094 24.078125 29.621094 Z M 21.214844 37.078125 C 21.175781 38.101562 21.707031 39.078125 22.578125 39.601562 C 23.445312 40.121094 24.554688 40.121094 25.421875 39.601562 C 26.292969 39.078125 26.824219 38.101562 26.785156 37.078125 C 26.726562 35.558594 25.5 34.359375 24 34.359375 C 22.5 34.359375 21.273438 35.558594 21.214844 37.078125 Z M 21.214844 37.078125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 42.265625 18.4375 C 41.632812 19.175781 40.527344 19.316406 39.777344 18.738281 C 34.9375 15.117188 29.765625 12.558594 24.015625 12.558594 C 18.230469 12.558594 13.09375 15.117188 8.253906 18.738281 C 7.464844 19.316406 6.398438 19.199219 5.765625 18.4375 C 5.429688 18.039062 5.273438 17.539062 5.351562 16.996094 C 5.410156 16.457031 5.667969 16.019531 6.082031 15.699219 C 11.574219 11.597656 17.5 8.777344 24.054688 8.777344 C 30.613281 8.777344 36.539062 11.578125 42.03125 15.699219 C 42.445312 16.019531 42.71875 16.476562 42.761719 16.996094 C 42.820312 17.539062 42.679688 18.019531 42.34375 18.4375 Z M 42.265625 18.4375 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 23.976562 21.199219 C 27.90625 21.199219 31.304688 22.398438 34.664062 24.816406 C 35.453125 25.375 36.519531 25.238281 37.132812 24.496094 C 37.46875 24.078125 37.625 23.597656 37.546875 23.058594 C 37.488281 22.515625 37.230469 22.078125 36.777344 21.757812 C 32.785156 18.878906 28.636719 17.457031 23.957031 17.457031 C 19.277344 17.457031 15.109375 18.898438 11.140625 21.757812 C 10.683594 22.078125 10.429688 22.496094 10.367188 23.058594 C 10.289062 23.597656 10.449219 24.097656 10.785156 24.496094 C 11.414062 25.238281 12.460938 25.375 13.253906 24.816406 C 16.628906 22.417969 20.046875 21.199219 23.976562 21.199219 Z M 23.976562 29.617188 L 23.898438 29.617188 C 22.042969 29.617188 20.183594 30.175781 18.644531 31.214844 C 17.855469 31.757812 16.828125 31.597656 16.195312 30.875 C 15.820312 30.457031 15.703125 29.9375 15.78125 29.394531 C 15.859375 28.835938 16.117188 28.375 16.589844 28.097656 C 18.742188 26.65625 21.269531 25.855469 23.898438 25.855469 L 24.054688 25.855469 C 26.664062 25.855469 29.210938 26.636719 31.363281 28.097656 C 31.816406 28.417969 32.09375 28.835938 32.171875 29.394531 C 32.253906 29.957031 32.09375 30.457031 31.757812 30.875 C 31.148438 31.597656 30.101562 31.757812 29.308594 31.214844 C 27.769531 30.175781 25.953125 29.617188 24.054688 29.617188 Z M 21.191406 37.074219 C 21.171875 38.117188 21.6875 39.074219 22.554688 39.59375 C 23.425781 40.136719 24.53125 40.136719 25.398438 39.59375 C 26.269531 39.054688 26.78125 38.117188 26.761719 37.074219 C 26.703125 35.554688 25.476562 34.355469 23.976562 34.355469 C 22.476562 34.355469 21.25 35.554688 21.191406 37.074219 Z M 21.191406 37.074219 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 48 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 42.273438 14.421875 C 41.640625 15.179688 40.535156 15.300781 39.761719 14.71875 C 34.921875 11.101562 29.769531 8.539062 23.980469 8.539062 C 18.191406 8.539062 13.058594 11.101562 8.21875 14.71875 C 7.425781 15.300781 6.339844 15.179688 5.707031 14.441406 C 5.351562 14.019531 5.214844 13.539062 5.273438 13 C 5.332031 12.460938 5.589844 12.019531 6.003906 11.699219 C 11.496094 7.601562 17.441406 4.800781 23.980469 4.800781 C 30.519531 4.800781 36.464844 7.601562 41.957031 11.699219 C 42.390625 12.019531 42.628906 12.460938 42.6875 13 C 42.746094 13.539062 42.628906 14.019531 42.273438 14.421875 Z M 42.273438 14.421875 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 24 17.199219 C 27.929688 17.199219 31.328125 18.398438 34.6875 20.820312 C 35.476562 21.378906 36.542969 21.261719 37.15625 20.519531 C 37.511719 20.101562 37.648438 19.621094 37.589844 19.078125 C 37.53125 18.539062 37.253906 18.101562 36.820312 17.78125 C 32.828125 14.921875 28.679688 13.480469 24 13.480469 C 19.320312 13.480469 15.152344 14.921875 11.179688 17.78125 C 10.746094 18.101562 10.488281 18.539062 10.410156 19.078125 C 10.351562 19.621094 10.488281 20.121094 10.84375 20.519531 C 11.476562 21.261719 12.542969 21.398438 13.3125 20.820312 C 16.652344 18.421875 20.050781 17.199219 24 17.199219 Z M 24 25.621094 L 23.921875 25.621094 C 22.042969 25.621094 20.226562 26.179688 18.6875 27.21875 C 17.894531 27.738281 16.867188 27.601562 16.257812 26.878906 C 15.902344 26.460938 15.742188 25.960938 15.820312 25.398438 C 15.902344 24.839844 16.179688 24.398438 16.632812 24.101562 C 18.785156 22.660156 21.3125 21.878906 23.921875 21.878906 L 24.058594 21.878906 C 26.667969 21.878906 29.214844 22.660156 31.347656 24.101562 C 31.800781 24.398438 32.078125 24.859375 32.15625 25.398438 C 32.238281 25.960938 32.078125 26.460938 31.722656 26.878906 C 31.109375 27.601562 30.0625 27.738281 29.292969 27.21875 C 27.753906 26.179688 25.9375 25.621094 24.058594 25.621094 Z M 21.214844 33.078125 C 21.175781 34.121094 21.707031 35.078125 22.578125 35.601562 C 23.445312 36.121094 24.554688 36.121094 25.421875 35.601562 C 26.292969 35.078125 26.824219 34.101562 26.785156 33.078125 C 26.726562 31.558594 25.5 30.359375 24 30.359375 C 22.5 30.359375 21.253906 31.558594 21.214844 33.078125 Z M 21.214844 33.078125 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 33.085938 26.078125 C 29.945312 26.078125 27.398438 28.660156 27.398438 31.839844 C 27.398438 35.019531 29.945312 37.601562 33.085938 37.601562 C 36.226562 37.601562 38.773438 35.019531 38.773438 31.839844 C 38.773438 28.660156 36.226562 26.078125 33.085938 26.078125 Z M 35.515625 33.558594 C 35.714844 33.761719 35.714844 34.101562 35.515625 34.300781 C 35.320312 34.5 34.984375 34.5 34.785156 34.300781 L 33.085938 32.578125 L 31.386719 34.300781 C 31.191406 34.5 30.855469 34.5 30.65625 34.300781 C 30.460938 34.101562 30.460938 33.761719 30.65625 33.558594 L 32.355469 31.839844 L 30.65625 30.121094 C 30.460938 29.921875 30.460938 29.578125 30.65625 29.378906 C 30.855469 29.179688 31.191406 29.179688 31.386719 29.378906 L 33.085938 31.101562 L 34.785156 29.378906 C 34.984375 29.179688 35.320312 29.179688 35.515625 29.378906 C 35.714844 29.578125 35.714844 29.921875 35.515625 30.121094 L 33.816406 31.839844 Z M 35.515625 33.558594 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 40 18.75 L 35 18.75 L 35 12.5 L 32.5 12.5 L 32.5 18.75 L 21.25 18.75 L 21.25 12.5 L 18.75 12.5 L 18.75 18.75 L 7.5 18.75 L 7.5 12.5 L 5 12.5 L 5 18.75 L 0 18.75 L 0 21.25 L 11.25 21.25 L 11.25 27.5 L 13.75 27.5 L 13.75 21.25 L 25 21.25 L 25 27.5 L 27.5 27.5 L 27.5 21.25 L 40 21.25 Z M 40 18.75 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 22.5 13.75 L 17.5 13.75 C 16.125 13.75 15 12.625 15 11.25 L 15 6.25 C 15 4.875 16.125 3.75 17.5 3.75 L 22.5 3.75 C 23.875 3.75 25 4.875 25 6.25 L 25 11.25 C 25 12.625 23.875 13.75 22.5 13.75 Z M 36.25 13.75 L 31.25 13.75 C 29.875 13.75 28.75 12.625 28.75 11.25 L 28.75 6.25 C 28.75 4.875 29.875 3.75 31.25 3.75 L 36.25 3.75 C 37.625 3.75 38.75 4.875 38.75 6.25 L 38.75 11.25 C 38.75 12.625 37.625 13.75 36.25 13.75 Z M 8.75 13.75 L 3.75 13.75 C 2.375 13.75 1.25 12.625 1.25 11.25 L 1.25 6.25 C 1.25 4.875 2.375 3.75 3.75 3.75 L 8.75 3.75 C 10.125 3.75 11.25 4.875 11.25 6.25 L 11.25 11.25 C 11.25 12.625 10.125 13.75 8.75 13.75 Z M 15 36.25 L 10 36.25 C 8.625 36.25 7.5 35.125 7.5 33.75 L 7.5 28.75 C 7.5 27.375 8.625 26.25 10 26.25 L 15 26.25 C 16.375 26.25 17.5 27.375 17.5 28.75 L 17.5 33.75 C 17.5 35.125 16.375 36.25 15 36.25 Z M 28.75 36.25 L 23.75 36.25 C 22.375 36.25 21.25 35.125 21.25 33.75 L 21.25 28.75 C 21.25 27.375 22.375 26.25 23.75 26.25 L 28.75 26.25 C 30.125 26.25 31.25 27.375 31.25 28.75 L 31.25 33.75 C 31.25 35.125 30.125 36.25 28.75 36.25 Z M 28.75 36.25 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 40 18.75 L 35 18.75 L 35 12.5 L 32.5 12.5 L 32.5 18.75 L 21.25 18.75 L 21.25 12.5 L 18.75 12.5 L 18.75 18.75 L 7.5 18.75 L 7.5 12.5 L 5 12.5 L 5 18.75 L 0 18.75 L 0 21.25 L 11.25 21.25 L 11.25 27.5 L 13.75 27.5 L 13.75 21.25 L 25 21.25 L 25 27.5 L 27.5 27.5 L 27.5 21.25 L 40 21.25 Z M 40 18.75 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882354%,85.882354%,85.882354%);fill-opacity:1;" d="M 22.5 13.75 L 17.5 13.75 C 16.125 13.75 15 12.625 15 11.25 L 15 6.25 C 15 4.875 16.125 3.75 17.5 3.75 L 22.5 3.75 C 23.875 3.75 25 4.875 25 6.25 L 25 11.25 C 25 12.625 23.875 13.75 22.5 13.75 Z M 36.25 13.75 L 31.25 13.75 C 29.875 13.75 28.75 12.625 28.75 11.25 L 28.75 6.25 C 28.75 4.875 29.875 3.75 31.25 3.75 L 36.25 3.75 C 37.625 3.75 38.75 4.875 38.75 6.25 L 38.75 11.25 C 38.75 12.625 37.625 13.75 36.25 13.75 Z M 8.75 13.75 L 3.75 13.75 C 2.375 13.75 1.25 12.625 1.25 11.25 L 1.25 6.25 C 1.25 4.875 2.375 3.75 3.75 3.75 L 8.75 3.75 C 10.125 3.75 11.25 4.875 11.25 6.25 L 11.25 11.25 C 11.25 12.625 10.125 13.75 8.75 13.75 Z M 15 36.25 L 10 36.25 C 8.625 36.25 7.5 35.125 7.5 33.75 L 7.5 28.75 C 7.5 27.375 8.625 26.25 10 26.25 L 15 26.25 C 16.375 26.25 17.5 27.375 17.5 28.75 L 17.5 33.75 C 17.5 35.125 16.375 36.25 15 36.25 Z M 28.75 36.25 L 23.75 36.25 C 22.375 36.25 21.25 35.125 21.25 33.75 L 21.25 28.75 C 21.25 27.375 22.375 26.25 23.75 26.25 L 28.75 26.25 C 30.125 26.25 31.25 27.375 31.25 28.75 L 31.25 33.75 C 31.25 35.125 30.125 36.25 28.75 36.25 Z M 28.75 36.25 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 23.5625 0.0546875 C 18.582031 0.0507812 13.882812 2.359375 10.84375 6.300781 C 12.640625 5.710938 14.523438 5.410156 16.417969 5.414062 C 26.296875 5.414062 34.300781 13.417969 34.300781 23.296875 C 34.304688 25.167969 34.011719 27.027344 33.4375 28.808594 C 37.351562 25.765625 39.636719 21.085938 39.632812 16.128906 C 39.636719 7.25 32.441406 0.0546875 23.5625 0.0546875 Z M 23.5625 0.0546875 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(25.490198%,25.490198%,25.490198%);fill-opacity:1;" d="M 16.4375 7.175781 C 7.554688 7.175781 0.285156 14.445312 0.285156 23.328125 C 0.285156 32.210938 7.554688 39.476562 16.4375 39.476562 C 25.316406 39.476562 32.585938 32.207031 32.585938 23.328125 C 32.585938 14.445312 25.316406 7.175781 16.4375 7.175781 Z M 11.5 9.871094 C 10.695312 10.855469 9.976562 12.113281 9.347656 13.550781 C 8.636719 13.183594 7.976562 12.730469 7.378906 12.203125 C 8.632812 11.214844 9.976562 10.40625 11.503906 9.871094 Z M 6.027344 13.457031 C 6.746094 14.175781 7.644531 14.714844 8.628906 15.253906 C 7.910156 17.40625 7.554688 19.828125 7.464844 22.429688 L 2.082031 22.429688 C 2.351562 18.929688 3.785156 15.789062 6.027344 13.457031 Z M 2.171875 24.222656 L 7.554688 24.222656 C 7.640625 26.65625 8.035156 29.066406 8.71875 31.402344 C 7.734375 31.941406 6.835938 32.476562 6.121094 33.195312 C 3.785156 30.863281 2.351562 27.722656 2.171875 24.222656 Z M 7.378906 34.453125 C 7.914062 34.003906 8.632812 33.554688 9.351562 33.105469 C 9.980469 34.542969 10.695312 35.796875 11.503906 36.789062 C 9.976562 36.246094 8.628906 35.4375 7.378906 34.453125 Z M 15.539062 37.503906 C 13.65625 37.054688 12.039062 35.082031 10.871094 32.300781 C 12.308594 31.761719 13.832031 31.496094 15.539062 31.40625 Z M 15.539062 29.609375 C 13.65625 29.699219 11.855469 30.058594 10.335938 30.6875 C 9.796875 28.800781 9.4375 26.558594 9.347656 24.226562 L 15.628906 24.226562 L 15.628906 29.609375 Z M 15.539062 22.433594 L 9.257812 22.433594 C 9.347656 20.101562 9.707031 17.855469 10.246094 15.972656 C 11.910156 16.613281 13.667969 16.976562 15.449219 17.050781 L 15.449219 22.433594 Z M 15.539062 15.253906 C 13.832031 15.164062 12.308594 14.804688 10.871094 14.359375 C 12.039062 11.578125 13.65625 9.691406 15.539062 9.152344 Z M 25.5 12.203125 C 24.960938 12.652344 24.242188 13.101562 23.527344 13.550781 C 22.898438 12.113281 22.179688 10.859375 21.371094 9.871094 C 22.898438 10.40625 24.242188 11.214844 25.5 12.203125 Z M 17.332031 9.152344 C 19.21875 9.601562 20.832031 11.574219 21.996094 14.355469 C 20.5625 14.894531 19.039062 15.164062 17.332031 15.253906 Z M 17.332031 17.046875 C 19.21875 16.957031 21.015625 16.597656 22.535156 15.96875 C 23.074219 17.855469 23.433594 20.097656 23.523438 22.429688 L 17.246094 22.429688 L 17.246094 17.046875 Z M 17.332031 24.222656 L 23.613281 24.222656 C 23.523438 26.554688 23.164062 28.800781 22.625 30.683594 C 20.960938 30.042969 19.203125 29.679688 17.421875 29.609375 L 17.421875 24.222656 Z M 17.332031 37.503906 L 17.332031 31.402344 C 19.039062 31.492188 20.5625 31.851562 21.996094 32.300781 C 20.832031 35.167969 19.214844 37.054688 17.332031 37.503906 Z M 21.371094 36.785156 C 22.175781 35.796875 22.894531 34.539062 23.523438 33.101562 C 24.234375 33.46875 24.894531 33.921875 25.496094 34.453125 C 24.242188 35.4375 22.894531 36.246094 21.371094 36.785156 Z M 26.84375 33.195312 C 26.125 32.476562 25.226562 31.9375 24.242188 31.402344 C 24.957031 29.246094 25.316406 26.824219 25.40625 24.222656 L 30.789062 24.222656 C 30.523438 27.722656 29.085938 30.863281 26.84375 33.195312 Z M 25.40625 22.429688 C 25.320312 20 24.925781 17.585938 24.242188 15.253906 C 25.226562 14.714844 26.125 14.175781 26.84375 13.457031 C 29.085938 15.789062 30.609375 18.929688 30.789062 22.429688 Z M 23.613281 0 C 18.410156 0 13.832031 2.421875 10.871094 6.28125 C 12.238281 5.832031 13.65625 5.558594 15.089844 5.472656 C 14.910156 5.382812 14.730469 5.203125 14.550781 5.113281 C 15.808594 4.125 17.148438 3.316406 18.679688 2.777344 C 18.050781 3.496094 17.511719 4.484375 16.972656 5.46875 C 17.601562 5.46875 18.230469 5.558594 18.859375 5.648438 C 19.9375 3.679688 21.28125 2.425781 22.804688 2.066406 L 22.804688 6.640625 C 23.433594 6.910156 24.0625 7.089844 24.601562 7.449219 L 24.601562 2.066406 C 26.484375 2.511719 28.097656 4.488281 29.265625 7.269531 C 28.152344 7.726562 26.96875 8 25.765625 8.078125 C 26.488281 8.523438 27.203125 8.972656 27.832031 9.511719 C 28.546875 9.332031 29.265625 9.148438 29.894531 8.882812 C 30.253906 9.960938 30.433594 11.125 30.609375 12.292969 C 31.738281 13.71875 32.621094 15.328125 33.214844 17.046875 L 37.878906 17.046875 C 37.699219 20.457031 36.261719 23.417969 34.109375 25.75 C 33.929688 26.828125 33.75 27.902344 33.394531 28.890625 C 37.25 25.929688 39.671875 21.355469 39.671875 16.152344 C 39.761719 7.269531 32.496094 0 23.613281 0 Z M 28.546875 2.691406 C 30.074219 3.230469 31.417969 4.035156 32.675781 5.023438 C 32.136719 5.472656 31.417969 5.921875 30.703125 6.371094 C 30.164062 4.933594 29.445312 3.679688 28.546875 2.6875 Z M 32.585938 15.25 C 32.496094 12.820312 32.105469 10.40625 31.417969 8.074219 C 32.40625 7.535156 33.304688 6.996094 34.015625 6.277344 C 36.261719 8.609375 37.785156 11.75 37.964844 15.25 Z M 32.585938 15.25 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,394 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 39" version="1.1">
|
||||
<defs>
|
||||
<filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
|
||||
<feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="mask0">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip1">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface5" clip-path="url(#clip1)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176472%,81.568629%,81.960785%);fill-opacity:1;" d="M 5.824219 24.257812 C 5.824219 31.980469 12.171875 38.238281 19.996094 38.238281 C 27.824219 38.238281 34.171875 31.980469 34.171875 24.257812 C 34.171875 16.535156 27.824219 10.273438 19.996094 10.273438 C 12.171875 10.273438 5.824219 16.535156 5.824219 24.257812 Z M 5.824219 24.257812 "/>
|
||||
</g>
|
||||
<mask id="mask1">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip2">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface8" clip-path="url(#clip2)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 21.226562 13.519531 C 21.78125 13.910156 22.480469 13.996094 23.070312 13.746094 C 23.65625 13.496094 24.039062 12.945312 24.074219 12.304688 C 24.105469 11.664062 23.785156 11.03125 23.234375 10.640625 C 22.679688 10.25 21.980469 10.164062 21.390625 10.414062 C 20.804688 10.667969 20.421875 11.214844 20.386719 11.855469 C 20.355469 12.496094 20.675781 13.132812 21.226562 13.519531 Z M 21.226562 13.519531 "/>
|
||||
</g>
|
||||
<mask id="mask2">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip3">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface11" clip-path="url(#clip3)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 21.542969 13.1875 C 22.3125 13.703125 23.332031 13.582031 23.816406 12.917969 C 24.304688 12.253906 24.078125 11.296875 23.308594 10.78125 C 22.539062 10.265625 21.519531 10.390625 21.03125 11.054688 C 20.542969 11.71875 20.769531 12.671875 21.542969 13.1875 Z M 21.542969 13.1875 "/>
|
||||
</g>
|
||||
<mask id="mask3">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip4">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface14" clip-path="url(#clip4)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 6.035156 26.320312 C 6.367188 26.578125 6.976562 26.417969 7.398438 25.960938 C 7.816406 25.503906 7.890625 24.921875 7.554688 24.664062 C 7.222656 24.40625 6.613281 24.566406 6.191406 25.023438 C 5.773438 25.480469 5.703125 26.0625 6.035156 26.320312 Z M 6.035156 26.320312 "/>
|
||||
</g>
|
||||
<mask id="mask4">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip5">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface17" clip-path="url(#clip5)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 6.007812 26.515625 C 6.199219 26.679688 6.507812 26.671875 6.816406 26.496094 C 7.125 26.320312 7.390625 26.003906 7.507812 25.664062 C 7.625 25.324219 7.578125 25.015625 7.390625 24.851562 C 7.199219 24.6875 6.890625 24.691406 6.582031 24.867188 C 6.269531 25.042969 6.007812 25.359375 5.890625 25.699219 C 5.769531 26.039062 5.816406 26.351562 6.007812 26.515625 Z M 6.007812 26.515625 "/>
|
||||
</g>
|
||||
<mask id="mask5">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip6">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface20" clip-path="url(#clip6)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 13.257812 36.859375 C 14.191406 37.515625 15.375 37.660156 16.363281 37.238281 C 17.351562 36.816406 17.996094 35.890625 18.050781 34.8125 C 18.109375 33.734375 17.570312 32.664062 16.640625 32.007812 C 15.707031 31.351562 14.527344 31.207031 13.539062 31.628906 C 12.550781 32.050781 11.90625 32.976562 11.847656 34.054688 C 11.789062 35.136719 12.328125 36.203125 13.257812 36.859375 Z M 13.257812 36.859375 "/>
|
||||
</g>
|
||||
<mask id="mask6">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip7">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface23" clip-path="url(#clip7)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 13.644531 36.320312 C 14.554688 36.9375 15.703125 37.078125 16.652344 36.6875 C 17.601562 36.296875 18.210938 35.433594 18.25 34.421875 C 18.285156 33.414062 17.75 32.40625 16.839844 31.789062 C 15.925781 31.167969 14.78125 31.027344 13.832031 31.417969 C 12.878906 31.808594 12.273438 32.671875 12.234375 33.683594 C 12.195312 34.695312 12.734375 35.699219 13.644531 36.320312 Z M 13.644531 36.320312 "/>
|
||||
</g>
|
||||
<mask id="mask7">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip8">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface26" clip-path="url(#clip8)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 32.34375 23.308594 C 32.867188 23.992188 33.496094 24.515625 33.992188 24.679688 C 34.488281 24.84375 34.777344 24.625 34.75 24.105469 C 34.726562 23.585938 34.386719 22.84375 33.863281 22.160156 C 33.339844 21.476562 32.710938 20.953125 32.214844 20.789062 C 31.71875 20.625 31.425781 20.84375 31.453125 21.363281 C 31.480469 21.882812 31.820312 22.625 32.34375 23.308594 Z M 32.34375 23.308594 "/>
|
||||
</g>
|
||||
<mask id="mask8">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip9">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface29" clip-path="url(#clip9)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 32.472656 23.769531 C 32.960938 24.417969 33.554688 24.910156 34.023438 25.0625 C 34.492188 25.214844 34.773438 25.003906 34.753906 24.503906 C 34.734375 24.007812 34.417969 23.300781 33.929688 22.652344 C 33.4375 22 32.847656 21.507812 32.375 21.355469 C 31.90625 21.203125 31.628906 21.417969 31.648438 21.914062 C 31.667969 22.410156 31.980469 23.117188 32.472656 23.769531 Z M 32.472656 23.769531 "/>
|
||||
</g>
|
||||
<mask id="mask9">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip10">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface32" clip-path="url(#clip10)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 28.503906 32.734375 C 28.777344 33.101562 29.371094 33.203125 30.058594 33 C 30.75 32.796875 31.429688 32.320312 31.84375 31.75 C 32.257812 31.183594 32.34375 30.605469 32.070312 30.238281 C 31.796875 29.871094 31.203125 29.769531 30.515625 29.972656 C 29.828125 30.171875 29.148438 30.648438 28.730469 31.21875 C 28.316406 31.789062 28.230469 32.367188 28.503906 32.734375 Z M 28.503906 32.734375 "/>
|
||||
</g>
|
||||
<mask id="mask10">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip11">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface35" clip-path="url(#clip11)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 28.683594 32.765625 C 29.078125 33.292969 30.160156 33.191406 31.097656 32.535156 C 32.039062 31.878906 32.480469 30.921875 32.085938 30.394531 C 31.828125 30.054688 31.269531 29.964844 30.617188 30.160156 C 29.960938 30.355469 29.316406 30.808594 28.914062 31.347656 C 28.515625 31.882812 28.429688 32.425781 28.683594 32.765625 Z M 28.683594 32.765625 "/>
|
||||
</g>
|
||||
<mask id="mask11">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip12">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface38" clip-path="url(#clip12)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 31.542969 28.15625 C 31.785156 28.15625 32.011719 28.03125 32.132812 27.828125 C 32.257812 27.625 32.261719 27.371094 32.140625 27.160156 C 32.023438 26.953125 31.796875 26.828125 31.554688 26.824219 C 31.3125 26.824219 31.089844 26.949219 30.964844 27.152344 C 30.839844 27.355469 30.839844 27.609375 30.957031 27.820312 C 31.078125 28.027344 31.300781 28.152344 31.542969 28.15625 Z M 31.542969 28.15625 "/>
|
||||
</g>
|
||||
<mask id="mask12">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip13">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface41" clip-path="url(#clip13)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 31.640625 28.15625 C 31.960938 28.160156 32.226562 27.863281 32.230469 27.496094 C 32.230469 27.128906 31.972656 26.828125 31.652344 26.824219 C 31.332031 26.820312 31.066406 27.117188 31.0625 27.484375 C 31.0625 27.851562 31.320312 28.152344 31.640625 28.15625 Z M 31.640625 28.15625 "/>
|
||||
</g>
|
||||
<mask id="mask13">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip14">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface44" clip-path="url(#clip14)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 15.738281 23.429688 C 15.789062 23.800781 16.039062 24.117188 16.390625 24.265625 C 16.746094 24.414062 17.148438 24.367188 17.449219 24.144531 C 17.75 23.917969 17.90625 23.550781 17.851562 23.179688 C 17.796875 22.808594 17.550781 22.492188 17.195312 22.34375 C 16.84375 22.195312 16.4375 22.242188 16.136719 22.46875 C 15.835938 22.691406 15.683594 23.058594 15.738281 23.429688 Z M 15.738281 23.429688 "/>
|
||||
</g>
|
||||
<mask id="mask14">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip15">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface47" clip-path="url(#clip15)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 15.929688 23.425781 C 15.980469 23.796875 16.207031 24.117188 16.527344 24.265625 C 16.84375 24.414062 17.222656 24.367188 17.488281 24.144531 C 17.761719 23.921875 17.902344 23.554688 17.851562 23.183594 C 17.804688 22.8125 17.574219 22.492188 17.253906 22.34375 C 16.9375 22.195312 16.558594 22.242188 16.292969 22.464844 C 16.019531 22.6875 15.882812 23.054688 15.929688 23.425781 Z M 15.929688 23.425781 "/>
|
||||
</g>
|
||||
<mask id="mask15">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip16">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface50" clip-path="url(#clip16)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 10.40625 19.292969 C 10.84375 19.71875 11.582031 19.691406 12.054688 19.226562 C 12.523438 18.765625 12.550781 18.042969 12.113281 17.613281 C 11.832031 17.339844 11.40625 17.242188 11.003906 17.363281 C 10.59375 17.488281 10.273438 17.800781 10.148438 18.203125 C 10.023438 18.601562 10.125 19.015625 10.40625 19.292969 Z M 10.40625 19.292969 "/>
|
||||
</g>
|
||||
<mask id="mask16">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip17">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface53" clip-path="url(#clip17)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 10.566406 19.324219 C 10.824219 19.574219 11.210938 19.660156 11.582031 19.542969 C 11.960938 19.425781 12.253906 19.136719 12.375 18.765625 C 12.492188 18.402344 12.40625 18.023438 12.148438 17.773438 C 11.894531 17.519531 11.503906 17.4375 11.132812 17.554688 C 10.757812 17.671875 10.460938 17.960938 10.339844 18.332031 C 10.222656 18.695312 10.308594 19.074219 10.566406 19.324219 Z M 10.566406 19.324219 "/>
|
||||
</g>
|
||||
<mask id="mask17">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip18">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface56" clip-path="url(#clip18)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 25.976562 20.078125 C 26.152344 20.214844 26.453125 20.191406 26.765625 20.019531 C 27.074219 19.851562 27.351562 19.558594 27.484375 19.25 C 27.617188 18.945312 27.59375 18.675781 27.414062 18.542969 C 27.238281 18.40625 26.9375 18.429688 26.625 18.597656 C 26.316406 18.769531 26.042969 19.0625 25.90625 19.367188 C 25.773438 19.671875 25.800781 19.945312 25.976562 20.078125 Z M 25.976562 20.078125 "/>
|
||||
</g>
|
||||
<mask id="mask18">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip19">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface59" clip-path="url(#clip19)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 26.132812 20.082031 C 26.265625 20.214844 26.5 20.1875 26.742188 20.015625 C 26.984375 19.84375 27.199219 19.550781 27.304688 19.246094 C 27.414062 18.9375 27.394531 18.671875 27.261719 18.539062 C 27.125 18.40625 26.890625 18.429688 26.648438 18.601562 C 26.40625 18.777344 26.191406 19.070312 26.085938 19.375 C 25.980469 19.679688 25.996094 19.949219 26.132812 20.082031 Z M 26.132812 20.082031 "/>
|
||||
</g>
|
||||
<mask id="mask19">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip20">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface62" clip-path="url(#clip20)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 17.542969 18.035156 C 17.621094 18.09375 17.753906 18.085938 17.890625 18.007812 C 18.03125 17.933594 18.152344 17.800781 18.210938 17.667969 C 18.273438 17.53125 18.261719 17.410156 18.183594 17.351562 C 18.101562 17.292969 17.96875 17.300781 17.832031 17.375 C 17.691406 17.453125 17.570312 17.582031 17.511719 17.71875 C 17.453125 17.855469 17.464844 17.976562 17.542969 18.035156 Z M 17.542969 18.035156 "/>
|
||||
</g>
|
||||
<mask id="mask20">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip21">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface65" clip-path="url(#clip21)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 17.894531 18.035156 C 17.933594 18.09375 18 18.082031 18.070312 18.007812 C 18.136719 17.929688 18.199219 17.800781 18.230469 17.664062 C 18.261719 17.527344 18.253906 17.410156 18.21875 17.351562 C 18.179688 17.289062 18.113281 17.300781 18.042969 17.378906 C 17.972656 17.457031 17.914062 17.585938 17.882812 17.722656 C 17.851562 17.855469 17.855469 17.976562 17.894531 18.035156 Z M 17.894531 18.035156 "/>
|
||||
</g>
|
||||
<mask id="mask21">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip22">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface68" clip-path="url(#clip22)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 23.097656 36.058594 C 23.621094 36.226562 24.136719 36.144531 24.246094 35.878906 C 24.359375 35.609375 24.023438 35.257812 23.496094 35.089844 C 23.160156 34.984375 22.808594 34.976562 22.574219 35.070312 C 22.34375 35.167969 22.269531 35.351562 22.375 35.554688 C 22.484375 35.761719 22.757812 35.953125 23.097656 36.058594 Z M 23.097656 36.058594 "/>
|
||||
</g>
|
||||
<mask id="mask22">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip23">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface71" clip-path="url(#clip23)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 23.101562 36.054688 C 23.441406 36.167969 23.792969 36.175781 24.023438 36.082031 C 24.253906 35.988281 24.328125 35.804688 24.21875 35.601562 C 24.109375 35.398438 23.832031 35.203125 23.492188 35.09375 C 23.152344 34.984375 22.804688 34.976562 22.574219 35.070312 C 22.34375 35.164062 22.269531 35.347656 22.375 35.550781 C 22.484375 35.753906 22.761719 35.945312 23.101562 36.054688 Z M 23.101562 36.054688 "/>
|
||||
</g>
|
||||
<mask id="mask23">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip24">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface74" clip-path="url(#clip24)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 10.941406 27.355469 C 11.019531 27.417969 11.152344 27.40625 11.292969 27.332031 C 11.429688 27.253906 11.550781 27.125 11.609375 26.988281 C 11.671875 26.851562 11.660156 26.734375 11.582031 26.671875 C 11.460938 26.582031 11.21875 26.660156 11.039062 26.847656 C 10.863281 27.035156 10.820312 27.265625 10.941406 27.355469 Z M 10.941406 27.355469 "/>
|
||||
</g>
|
||||
<mask id="mask24">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip25">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface77" clip-path="url(#clip25)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 11.101562 27.359375 C 11.160156 27.449219 11.28125 27.367188 11.367188 27.179688 C 11.457031 26.988281 11.480469 26.761719 11.421875 26.671875 C 11.382812 26.613281 11.316406 26.625 11.246094 26.699219 C 11.179688 26.777344 11.117188 26.90625 11.085938 27.042969 C 11.054688 27.179688 11.0625 27.300781 11.101562 27.359375 Z M 11.101562 27.359375 "/>
|
||||
</g>
|
||||
<mask id="mask25">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip26">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface80" clip-path="url(#clip26)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(60.000002%,60.000002%,60.000002%);fill-opacity:1;" d="M 20 39 C 11.753906 39 5.046875 32.429688 5.046875 24.351562 C 5.046875 16.273438 11.753906 9.703125 20 9.703125 C 28.242188 9.703125 34.945312 16.273438 34.945312 24.351562 C 34.945312 32.429688 28.242188 39 20 39 Z M 20 11.222656 C 12.609375 11.222656 6.601562 17.113281 6.601562 24.351562 C 6.601562 31.589844 12.609375 37.480469 20 37.480469 C 27.386719 37.480469 33.394531 31.589844 33.394531 24.351562 C 33.394531 17.113281 27.386719 11.222656 20 11.222656 Z M 20 11.222656 "/>
|
||||
</g>
|
||||
<mask id="mask26">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip27">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface83" clip-path="url(#clip27)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.411767%,70.588237%,70.980394%);fill-opacity:1;" d="M 24.816406 30.246094 C 24.921875 30.261719 25.023438 30.101562 25.042969 29.890625 C 25.0625 29.679688 24.992188 29.5 24.886719 29.488281 C 24.78125 29.476562 24.679688 29.636719 24.660156 29.847656 C 24.640625 30.054688 24.710938 30.234375 24.816406 30.246094 Z M 24.816406 30.246094 "/>
|
||||
</g>
|
||||
<mask id="mask27">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip28">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface86" clip-path="url(#clip28)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(84.705883%,11.764706%,2.352941%);fill-opacity:1;" d="M 8.214844 34.433594 C 4.128906 34.433594 1.039062 33.460938 0.214844 31.1875 C -0.648438 28.8125 1.097656 25.902344 5.125 23.003906 C 5.347656 22.839844 5.640625 22.808594 5.894531 22.917969 C 6.148438 23.027344 6.324219 23.261719 6.355469 23.53125 C 6.382812 23.800781 6.265625 24.066406 6.042969 24.230469 C 2.664062 26.660156 1.074219 29.011719 1.679688 30.679688 C 2.699219 33.492188 11.363281 34 22.164062 30.230469 C 27.171875 28.484375 31.625 26.167969 34.699219 23.707031 C 37.53125 21.445312 38.851562 19.324219 38.332031 17.894531 C 37.847656 16.566406 35.113281 15.84375 30.800781 15.933594 L 30.785156 15.933594 C 30.363281 15.925781 30.023438 15.59375 30.019531 15.179688 C 30.011719 14.765625 30.347656 14.425781 30.769531 14.410156 C 36.003906 14.3125 39.046875 15.308594 39.796875 17.382812 C 40.5625 19.488281 39.101562 22.152344 35.683594 24.886719 C 32.472656 27.453125 27.855469 29.859375 22.683594 31.664062 C 17.734375 33.390625 12.441406 34.433594 8.214844 34.433594 Z M 11.90625 12.59375 C 11.640625 12.59375 11.394531 12.460938 11.25 12.242188 L 10.367188 10.878906 C 10.214844 10.652344 10.199219 10.359375 10.324219 10.117188 C 10.453125 9.871094 10.703125 9.714844 10.984375 9.703125 C 11.261719 9.691406 11.527344 9.828125 11.675781 10.058594 L 12.5625 11.421875 C 12.714844 11.65625 12.722656 11.953125 12.585938 12.195312 C 12.453125 12.441406 12.191406 12.59375 11.90625 12.59375 Z M 11.90625 12.59375 "/>
|
||||
</g>
|
||||
<mask id="mask28">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip29">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface89" clip-path="url(#clip29)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(60.000002%,60.000002%,60.000002%);fill-opacity:1;" d="M 6.398438 29.105469 C 6.050781 29.105469 5.746094 28.882812 5.648438 28.558594 C 5.25 27.214844 5.046875 25.820312 5.046875 24.421875 C 5.046875 16.304688 11.777344 9.703125 20.046875 9.703125 C 27.132812 9.703125 33.3125 14.640625 34.738281 21.441406 C 34.800781 21.710938 34.710938 21.996094 34.5 22.179688 C 34.289062 22.363281 33.996094 22.421875 33.726562 22.335938 C 33.460938 22.246094 33.265625 22.023438 33.214844 21.75 C 31.9375 15.652344 26.398438 11.226562 20.046875 11.226562 C 12.632812 11.226562 6.605469 17.144531 6.605469 24.417969 C 6.601562 25.671875 6.785156 26.921875 7.144531 28.125 C 7.210938 28.359375 7.164062 28.605469 7.019531 28.800781 C 6.871094 28.992188 6.640625 29.105469 6.394531 29.105469 Z M 6.398438 29.105469 "/>
|
||||
</g>
|
||||
<mask id="mask29">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip30">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface92" clip-path="url(#clip30)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(84.705883%,11.764706%,2.352941%);fill-opacity:1;" d="M 8.308594 8.289062 C 7.664062 8.289062 7.082031 7.90625 6.835938 7.316406 C 6.585938 6.726562 6.722656 6.050781 7.179688 5.597656 C 7.632812 5.148438 8.320312 5.011719 8.917969 5.257812 C 9.511719 5.5 9.902344 6.074219 9.902344 6.714844 C 9.898438 7.582031 9.1875 8.289062 8.308594 8.289062 Z M 6.382812 10.652344 C 4.683594 10.652344 3.300781 9.289062 3.300781 7.605469 C 3.292969 7.320312 3.441406 7.054688 3.691406 6.90625 C 3.941406 6.761719 4.25 6.761719 4.5 6.90625 C 4.75 7.054688 4.898438 7.320312 4.890625 7.605469 C 4.894531 8.417969 5.558594 9.078125 6.382812 9.082031 C 6.671875 9.074219 6.945312 9.222656 7.089844 9.46875 C 7.234375 9.714844 7.234375 10.019531 7.089844 10.265625 C 6.945312 10.511719 6.671875 10.660156 6.382812 10.652344 Z M 6.382812 10.652344 "/>
|
||||
</g>
|
||||
<mask id="mask30">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip31">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface95" clip-path="url(#clip31)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(84.705883%,11.764706%,2.352941%);fill-opacity:1;" d="M 6.4375 12.933594 C 3.207031 12.929688 0.585938 10.328125 0.582031 7.109375 C 0.574219 6.835938 0.71875 6.578125 0.960938 6.4375 C 1.199219 6.296875 1.496094 6.296875 1.734375 6.4375 C 1.976562 6.578125 2.121094 6.835938 2.113281 7.109375 C 2.113281 9.488281 4.050781 11.414062 6.4375 11.414062 C 6.714844 11.410156 6.976562 11.550781 7.113281 11.789062 C 7.253906 12.027344 7.253906 12.324219 7.113281 12.5625 C 6.976562 12.796875 6.714844 12.941406 6.4375 12.9375 Z M 11.992188 7.003906 C 11.933594 7.003906 11.875 6.996094 11.820312 6.984375 C 11.410156 6.886719 11.152344 6.480469 11.246094 6.070312 C 11.425781 5.300781 10.945312 4.535156 10.175781 4.359375 C 9.902344 4.300781 9.683594 4.101562 9.605469 3.839844 C 9.519531 3.578125 9.585938 3.292969 9.777344 3.089844 C 9.964844 2.890625 10.25 2.808594 10.519531 2.875 C 11.285156 3.050781 11.949219 3.523438 12.367188 4.1875 C 12.78125 4.855469 12.914062 5.652344 12.738281 6.414062 C 12.65625 6.757812 12.347656 7.003906 11.992188 7.003906 Z M 11.992188 7.003906 "/>
|
||||
</g>
|
||||
<mask id="mask31">
|
||||
<g filter="url(#alpha)">
|
||||
<rect x="0" y="0" width="40" height="39" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="clip32">
|
||||
<rect x="0" y="0" width="40" height="39"/>
|
||||
</clipPath>
|
||||
<g id="surface98" clip-path="url(#clip32)">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(84.705883%,11.764706%,2.352941%);fill-opacity:1;" d="M 14.609375 7.609375 C 14.550781 7.609375 14.488281 7.601562 14.429688 7.589844 C 14.226562 7.542969 14.050781 7.421875 13.9375 7.25 C 13.828125 7.078125 13.792969 6.871094 13.839844 6.671875 C 14.109375 5.5625 13.90625 4.390625 13.28125 3.421875 C 12.65625 2.453125 11.660156 1.761719 10.507812 1.503906 C 10.085938 1.40625 9.824219 1 9.921875 0.589844 C 10.019531 0.183594 10.441406 -0.0742188 10.863281 0.0195312 C 12.421875 0.367188 13.773438 1.300781 14.621094 2.613281 C 15.464844 3.921875 15.738281 5.511719 15.375 7.019531 C 15.292969 7.363281 14.976562 7.609375 14.609375 7.609375 Z M 14.609375 7.609375 "/>
|
||||
</g>
|
||||
</defs>
|
||||
<g id="surface1">
|
||||
<use xlink:href="#surface5" mask="url(#mask0)"/>
|
||||
<use xlink:href="#surface8" mask="url(#mask1)"/>
|
||||
<use xlink:href="#surface11" mask="url(#mask2)"/>
|
||||
<use xlink:href="#surface14" mask="url(#mask3)"/>
|
||||
<use xlink:href="#surface17" mask="url(#mask4)"/>
|
||||
<use xlink:href="#surface20" mask="url(#mask5)"/>
|
||||
<use xlink:href="#surface23" mask="url(#mask6)"/>
|
||||
<use xlink:href="#surface26" mask="url(#mask7)"/>
|
||||
<use xlink:href="#surface29" mask="url(#mask8)"/>
|
||||
<use xlink:href="#surface32" mask="url(#mask9)"/>
|
||||
<use xlink:href="#surface35" mask="url(#mask10)"/>
|
||||
<use xlink:href="#surface38" mask="url(#mask11)"/>
|
||||
<use xlink:href="#surface41" mask="url(#mask12)"/>
|
||||
<use xlink:href="#surface44" mask="url(#mask13)"/>
|
||||
<use xlink:href="#surface47" mask="url(#mask14)"/>
|
||||
<use xlink:href="#surface50" mask="url(#mask15)"/>
|
||||
<use xlink:href="#surface53" mask="url(#mask16)"/>
|
||||
<use xlink:href="#surface56" mask="url(#mask17)"/>
|
||||
<use xlink:href="#surface59" mask="url(#mask18)"/>
|
||||
<use xlink:href="#surface62" mask="url(#mask19)"/>
|
||||
<use xlink:href="#surface65" mask="url(#mask20)"/>
|
||||
<use xlink:href="#surface68" mask="url(#mask21)"/>
|
||||
<use xlink:href="#surface71" mask="url(#mask22)"/>
|
||||
<use xlink:href="#surface74" mask="url(#mask23)"/>
|
||||
<use xlink:href="#surface77" mask="url(#mask24)"/>
|
||||
<use xlink:href="#surface80" mask="url(#mask25)"/>
|
||||
<use xlink:href="#surface83" mask="url(#mask26)"/>
|
||||
<use xlink:href="#surface86" mask="url(#mask27)"/>
|
||||
<use xlink:href="#surface89" mask="url(#mask28)"/>
|
||||
<use xlink:href="#surface92" mask="url(#mask29)"/>
|
||||
<use xlink:href="#surface95" mask="url(#mask30)"/>
|
||||
<use xlink:href="#surface98" mask="url(#mask31)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 29.746094 8.769531 C 29.359375 8.410156 28.847656 8.207031 28.316406 8.199219 L 17.160156 8.199219 L 17.160156 10.757812 L 27.675781 10.757812 L 27.675781 20 L 30.375 20 L 30.375 10.15625 C 30.371094 9.625 30.144531 9.121094 29.746094 8.769531 Z M 29.746094 8.769531 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 17.570312 2.484375 L 4.230469 2.484375 C 3.867188 2.492188 3.519531 2.632812 3.257812 2.886719 C 3.003906 3.148438 2.863281 3.496094 2.855469 3.855469 L 2.855469 14.355469 C 2.855469 14.539062 2.890625 14.71875 2.957031 14.886719 C 3.027344 15.046875 3.128906 15.195312 3.257812 15.3125 C 3.386719 15.441406 3.535156 15.542969 3.699219 15.613281 C 3.863281 15.675781 4.039062 15.707031 4.214844 15.714844 L 17.570312 15.714844 C 17.742188 15.710938 17.914062 15.675781 18.070312 15.613281 C 18.40625 15.476562 18.679688 15.214844 18.828125 14.886719 C 18.890625 14.714844 18.921875 14.539062 18.929688 14.355469 L 18.929688 3.855469 C 18.917969 3.5 18.777344 3.15625 18.527344 2.898438 C 18.273438 2.644531 17.929688 2.5 17.570312 2.484375 Z M 16.355469 5.070312 L 16.355469 13.171875 L 5.441406 13.171875 L 5.441406 5.070312 Z M 17.644531 18.199219 L 4.144531 18.199219 C 3.773438 18.214844 3.429688 18.398438 3.214844 18.699219 C 2.738281 19.367188 2.738281 20.261719 3.214844 20.929688 C 3.429688 21.230469 3.773438 21.414062 4.144531 21.429688 L 17.644531 21.429688 C 18.007812 21.417969 18.347656 21.230469 18.558594 20.929688 C 19.050781 20.269531 19.050781 19.359375 18.558594 18.699219 C 18.347656 18.398438 18.007812 18.210938 17.644531 18.199219 Z M 37.070312 18.644531 C 36.796875 18.355469 36.414062 18.195312 36.015625 18.199219 L 21.472656 18.199219 C 21.078125 18.199219 20.699219 18.359375 20.429688 18.644531 C 20.15625 18.929688 20.003906 19.308594 20 19.699219 L 20 31.355469 C 20.003906 31.75 20.15625 32.128906 20.429688 32.414062 C 20.699219 32.699219 21.078125 32.859375 21.472656 32.855469 L 35.972656 32.855469 C 36.371094 32.863281 36.753906 32.703125 37.027344 32.414062 C 37.300781 32.128906 37.453125 31.75 37.457031 31.355469 L 37.457031 19.699219 C 37.464844 19.3125 37.328125 18.933594 37.070312 18.644531 Z M 34.699219 21.027344 L 34.699219 30.058594 L 22.785156 30.058594 L 22.785156 21.027344 Z M 36.113281 33.914062 L 21.386719 33.914062 C 21.003906 33.925781 20.640625 34.101562 20.398438 34.398438 C 20.136719 34.71875 19.996094 35.117188 20 35.527344 C 19.996094 35.941406 20.136719 36.339844 20.398438 36.65625 C 20.640625 36.957031 21 37.132812 21.386719 37.144531 L 36.113281 37.144531 C 36.496094 37.132812 36.859375 36.957031 37.101562 36.65625 C 37.363281 36.339844 37.503906 35.941406 37.5 35.527344 C 37.503906 35.117188 37.363281 34.71875 37.101562 34.398438 C 36.859375 34.101562 36.496094 33.925781 36.113281 33.914062 Z M 36.113281 33.914062 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 29.746094 8.769531 C 29.359375 8.410156 28.847656 8.207031 28.316406 8.199219 L 17.160156 8.199219 L 17.160156 10.757812 L 27.675781 10.757812 L 27.675781 20 L 30.375 20 L 30.375 10.15625 C 30.371094 9.625 30.144531 9.121094 29.746094 8.769531 Z M 29.746094 8.769531 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 17.570312 2.484375 L 4.230469 2.484375 C 3.867188 2.492188 3.519531 2.632812 3.257812 2.886719 C 3.003906 3.148438 2.863281 3.496094 2.855469 3.855469 L 2.855469 14.355469 C 2.855469 14.539062 2.890625 14.71875 2.957031 14.886719 C 3.027344 15.046875 3.128906 15.195312 3.257812 15.3125 C 3.386719 15.441406 3.535156 15.542969 3.699219 15.613281 C 3.863281 15.675781 4.039062 15.707031 4.214844 15.714844 L 17.570312 15.714844 C 17.742188 15.710938 17.914062 15.675781 18.070312 15.613281 C 18.40625 15.476562 18.679688 15.214844 18.828125 14.886719 C 18.890625 14.714844 18.921875 14.539062 18.929688 14.355469 L 18.929688 3.855469 C 18.917969 3.5 18.777344 3.15625 18.527344 2.898438 C 18.273438 2.644531 17.929688 2.5 17.570312 2.484375 Z M 16.355469 5.070312 L 16.355469 13.171875 L 5.441406 13.171875 L 5.441406 5.070312 Z M 17.644531 18.199219 L 4.144531 18.199219 C 3.773438 18.214844 3.429688 18.398438 3.214844 18.699219 C 2.738281 19.367188 2.738281 20.261719 3.214844 20.929688 C 3.429688 21.230469 3.773438 21.414062 4.144531 21.429688 L 17.644531 21.429688 C 18.007812 21.417969 18.347656 21.230469 18.558594 20.929688 C 19.050781 20.269531 19.050781 19.359375 18.558594 18.699219 C 18.347656 18.398438 18.007812 18.210938 17.644531 18.199219 Z M 37.070312 18.644531 C 36.796875 18.355469 36.414062 18.195312 36.015625 18.199219 L 21.472656 18.199219 C 21.078125 18.199219 20.699219 18.359375 20.429688 18.644531 C 20.15625 18.929688 20.003906 19.308594 20 19.699219 L 20 31.355469 C 20.003906 31.75 20.15625 32.128906 20.429688 32.414062 C 20.699219 32.699219 21.078125 32.859375 21.472656 32.855469 L 35.972656 32.855469 C 36.371094 32.863281 36.753906 32.703125 37.027344 32.414062 C 37.300781 32.128906 37.453125 31.75 37.457031 31.355469 L 37.457031 19.699219 C 37.464844 19.3125 37.328125 18.933594 37.070312 18.644531 Z M 34.699219 21.027344 L 34.699219 30.058594 L 22.785156 30.058594 L 22.785156 21.027344 Z M 36.113281 33.914062 L 21.386719 33.914062 C 21.003906 33.925781 20.640625 34.101562 20.398438 34.398438 C 20.136719 34.71875 19.996094 35.117188 20 35.527344 C 19.996094 35.941406 20.136719 36.339844 20.398438 36.65625 C 20.640625 36.957031 21 37.132812 21.386719 37.144531 L 36.113281 37.144531 C 36.496094 37.132812 36.859375 36.957031 37.101562 36.65625 C 37.363281 36.339844 37.503906 35.941406 37.5 35.527344 C 37.503906 35.117188 37.363281 34.71875 37.101562 34.398438 C 36.859375 34.101562 36.496094 33.925781 36.113281 33.914062 Z M 36.113281 33.914062 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 6.253906 7.738281 C 6.542969 7.734375 6.816406 7.625 7.027344 7.425781 C 7.4375 6.996094 7.4375 6.3125 7.027344 5.882812 C 6.589844 5.453125 5.890625 5.453125 5.453125 5.882812 C 5.253906 6.089844 5.140625 6.367188 5.140625 6.65625 C 5.140625 7.253906 5.625 7.738281 6.226562 7.738281 Z M 6.253906 7.738281 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 30.5 3 C 27.347656 1.03125 23.707031 -0.0078125 19.992188 0 C 16.964844 -0.00390625 13.976562 0.679688 11.253906 2 C 10.714844 2.277344 10.488281 2.929688 10.738281 3.484375 C 11.007812 4.035156 11.671875 4.265625 12.222656 4 C 13.371094 3.429688 14.578125 2.988281 15.820312 2.683594 C 13.105469 4.617188 11.101562 7.386719 10.109375 10.566406 C 7.273438 11.507812 4.757812 13.230469 2.855469 15.535156 C 3.285156 13.8125 3.957031 12.15625 4.855469 10.625 C 5.171875 10.113281 5.011719 9.441406 4.5 9.125 C 3.984375 8.808594 3.3125 8.96875 3 9.480469 C -2.816406 18.871094 0.0859375 31.195312 9.476562 37.007812 C 18.867188 42.820312 31.191406 39.914062 37 30.519531 C 42.808594 21.125 39.898438 8.804688 30.5 3 Z M 19.992188 3.628906 C 22.847656 3.628906 25.332031 6.027344 27.046875 9.738281 C 22.402344 8.683594 17.582031 8.683594 12.9375 9.738281 C 14.652344 6.027344 17.136719 3.628906 19.992188 3.628906 Z M 24.445312 20.761719 C 24.882812 20.332031 25.582031 20.332031 26.019531 20.761719 C 26.222656 20.964844 26.339844 21.246094 26.339844 21.535156 C 26.339844 21.824219 26.222656 22.101562 26.019531 22.304688 L 22.476562 26.246094 C 22.25 26.457031 21.957031 26.578125 21.648438 26.589844 C 21.355469 26.589844 21.074219 26.472656 20.871094 26.261719 C 20.667969 26.050781 20.554688 25.769531 20.5625 25.476562 L 20.5625 15.222656 C 20.492188 14.789062 20.683594 14.351562 21.054688 14.109375 C 21.425781 13.871094 21.902344 13.871094 22.269531 14.109375 C 22.640625 14.351562 22.832031 14.789062 22.761719 15.222656 L 22.761719 22.847656 Z M 13.023438 18.191406 L 16.648438 14.453125 C 16.964844 14.125 17.445312 14.023438 17.867188 14.195312 C 18.285156 14.363281 18.5625 14.769531 18.5625 15.222656 L 18.5625 25.476562 C 18.546875 26.085938 18.058594 26.574219 17.449219 26.589844 C 16.847656 26.574219 16.363281 26.078125 16.363281 25.476562 L 16.363281 17.992188 L 14.652344 19.792969 C 14.242188 20.234375 13.550781 20.257812 13.109375 19.847656 C 12.667969 19.4375 12.640625 18.75 13.050781 18.308594 Z M 9.394531 13.308594 C 8.339844 17.941406 8.339844 22.753906 9.394531 27.390625 C 5.710938 25.703125 3.253906 23.132812 3.253906 20.335938 C 3.253906 17.535156 5.710938 14.992188 9.394531 13.308594 Z M 3.113281 25.703125 C 5.027344 27.824219 7.472656 29.402344 10.195312 30.273438 C 11.03125 32.75 12.429688 34.996094 14.28125 36.84375 C 9.03125 35.0625 4.902344 30.949219 3.113281 25.703125 Z M 19.992188 37.128906 C 17.136719 37.128906 14.652344 34.730469 12.9375 31.015625 C 17.582031 32.074219 22.402344 32.074219 27.046875 31.015625 C 25.332031 34.671875 22.847656 37.128906 19.992188 37.128906 Z M 25.703125 36.898438 C 27.59375 35.019531 29.011719 32.71875 29.84375 30.1875 C 32.539062 29.332031 34.960938 27.785156 36.871094 25.703125 C 35.078125 30.949219 30.953125 35.0625 25.703125 36.84375 Z M 30.644531 13.367188 C 34.355469 15.050781 36.785156 17.621094 36.785156 20.390625 C 36.785156 23.160156 34.273438 25.703125 30.585938 27.390625 C 31.644531 22.753906 31.644531 17.941406 30.585938 13.308594 Z M 29.84375 10.511719 C 28.828125 7.417969 26.84375 4.738281 24.191406 2.855469 C 30.503906 4.40625 35.464844 9.28125 37.128906 15.566406 C 35.21875 13.21875 32.667969 11.484375 29.789062 10.566406 Z M 29.84375 10.511719 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 6.253906 7.738281 C 6.542969 7.734375 6.816406 7.625 7.027344 7.425781 C 7.4375 6.996094 7.4375 6.3125 7.027344 5.882812 C 6.589844 5.453125 5.890625 5.453125 5.453125 5.882812 C 5.253906 6.089844 5.140625 6.367188 5.140625 6.65625 C 5.140625 7.253906 5.625 7.738281 6.226562 7.738281 Z M 6.253906 7.738281 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 30.5 3 C 27.347656 1.03125 23.707031 -0.0078125 19.992188 0 C 16.964844 -0.00390625 13.976562 0.679688 11.253906 2 C 10.714844 2.277344 10.488281 2.929688 10.738281 3.484375 C 11.007812 4.035156 11.671875 4.265625 12.222656 4 C 13.371094 3.429688 14.578125 2.988281 15.820312 2.683594 C 13.105469 4.617188 11.101562 7.386719 10.109375 10.566406 C 7.273438 11.507812 4.757812 13.230469 2.855469 15.535156 C 3.285156 13.8125 3.957031 12.15625 4.855469 10.625 C 5.171875 10.113281 5.011719 9.441406 4.5 9.125 C 3.984375 8.808594 3.3125 8.96875 3 9.480469 C -2.816406 18.871094 0.0859375 31.195312 9.476562 37.007812 C 18.867188 42.820312 31.191406 39.914062 37 30.519531 C 42.808594 21.125 39.898438 8.804688 30.5 3 Z M 19.992188 3.628906 C 22.847656 3.628906 25.332031 6.027344 27.046875 9.738281 C 22.402344 8.683594 17.582031 8.683594 12.9375 9.738281 C 14.652344 6.027344 17.136719 3.628906 19.992188 3.628906 Z M 24.445312 20.761719 C 24.882812 20.332031 25.582031 20.332031 26.019531 20.761719 C 26.222656 20.964844 26.339844 21.246094 26.339844 21.535156 C 26.339844 21.824219 26.222656 22.101562 26.019531 22.304688 L 22.476562 26.246094 C 22.25 26.457031 21.957031 26.578125 21.648438 26.589844 C 21.355469 26.589844 21.074219 26.472656 20.871094 26.261719 C 20.667969 26.050781 20.554688 25.769531 20.5625 25.476562 L 20.5625 15.222656 C 20.492188 14.789062 20.683594 14.351562 21.054688 14.109375 C 21.425781 13.871094 21.902344 13.871094 22.269531 14.109375 C 22.640625 14.351562 22.832031 14.789062 22.761719 15.222656 L 22.761719 22.847656 Z M 13.023438 18.191406 L 16.648438 14.453125 C 16.964844 14.125 17.445312 14.023438 17.867188 14.195312 C 18.285156 14.363281 18.5625 14.769531 18.5625 15.222656 L 18.5625 25.476562 C 18.546875 26.085938 18.058594 26.574219 17.449219 26.589844 C 16.847656 26.574219 16.363281 26.078125 16.363281 25.476562 L 16.363281 17.992188 L 14.652344 19.792969 C 14.242188 20.234375 13.550781 20.257812 13.109375 19.847656 C 12.667969 19.4375 12.640625 18.75 13.050781 18.308594 Z M 9.394531 13.308594 C 8.339844 17.941406 8.339844 22.753906 9.394531 27.390625 C 5.710938 25.703125 3.253906 23.132812 3.253906 20.335938 C 3.253906 17.535156 5.710938 14.992188 9.394531 13.308594 Z M 3.113281 25.703125 C 5.027344 27.824219 7.472656 29.402344 10.195312 30.273438 C 11.03125 32.75 12.429688 34.996094 14.28125 36.84375 C 9.03125 35.0625 4.902344 30.949219 3.113281 25.703125 Z M 19.992188 37.128906 C 17.136719 37.128906 14.652344 34.730469 12.9375 31.015625 C 17.582031 32.074219 22.402344 32.074219 27.046875 31.015625 C 25.332031 34.671875 22.847656 37.128906 19.992188 37.128906 Z M 25.703125 36.898438 C 27.59375 35.019531 29.011719 32.71875 29.84375 30.1875 C 32.539062 29.332031 34.960938 27.785156 36.871094 25.703125 C 35.078125 30.949219 30.953125 35.0625 25.703125 36.84375 Z M 30.644531 13.367188 C 34.355469 15.050781 36.785156 17.621094 36.785156 20.390625 C 36.785156 23.160156 34.273438 25.703125 30.585938 27.390625 C 31.644531 22.753906 31.644531 17.941406 30.585938 13.308594 Z M 29.84375 10.511719 C 28.828125 7.417969 26.84375 4.738281 24.191406 2.855469 C 30.503906 4.40625 35.464844 9.28125 37.128906 15.566406 C 35.21875 13.21875 32.667969 11.484375 29.789062 10.566406 Z M 29.84375 10.511719 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(90.588236%,90.588236%,92.54902%);fill-opacity:1;" d="M 20 0 C 33.332031 0 40 6.667969 40 20 C 40 33.332031 33.332031 40 20 40 C 6.667969 40 0 33.332031 0 20 C 0 6.667969 6.667969 0 20 0 Z M 20 0 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 18.582031 29.328125 C 18.582031 28.53125 19.226562 27.882812 20.027344 27.882812 C 20.824219 27.882812 21.46875 28.53125 21.46875 29.328125 C 21.46875 30.125 20.824219 30.769531 20.027344 30.769531 C 19.230469 30.769531 18.582031 30.125 18.582031 29.328125 Z M 32.34375 15.113281 C 32.855469 15.625 32.855469 16.449219 32.347656 16.960938 C 31.835938 17.472656 31.011719 17.472656 30.496094 16.960938 C 24.699219 11.164062 15.300781 11.164062 9.503906 16.960938 C 8.996094 17.472656 8.167969 17.472656 7.65625 16.960938 C 7.410156 16.71875 7.273438 16.382812 7.273438 16.039062 C 7.273438 15.691406 7.410156 15.359375 7.65625 15.113281 C 14.472656 8.296875 25.527344 8.296875 32.34375 15.113281 Z M 11.285156 19.25 C 16.097656 14.441406 23.898438 14.441406 28.710938 19.25 C 29.222656 19.761719 29.222656 20.589844 28.710938 21.097656 C 28.46875 21.34375 28.136719 21.484375 27.789062 21.484375 C 27.441406 21.484375 27.109375 21.34375 26.863281 21.097656 C 23.074219 17.308594 16.921875 17.308594 13.132812 21.097656 C 12.625 21.613281 11.796875 21.613281 11.285156 21.101562 C 11.039062 20.855469 10.902344 20.523438 10.902344 20.175781 C 10.902344 19.828125 11.039062 19.496094 11.285156 19.25 Z M 25.183594 25.558594 C 24.738281 26.007812 24.035156 26.070312 23.515625 25.710938 L 23.5 25.730469 L 23.257812 25.484375 C 21.46875 23.699219 18.574219 23.695312 16.785156 25.484375 C 16.277344 25.996094 15.449219 25.996094 14.9375 25.488281 C 14.691406 25.242188 14.554688 24.910156 14.554688 24.5625 C 14.554688 24.214844 14.691406 23.882812 14.9375 23.636719 C 17.746094 20.828125 22.296875 20.828125 25.105469 23.636719 L 25.160156 23.695312 L 25.179688 23.710938 L 25.234375 23.765625 L 25.347656 23.882812 L 25.335938 23.894531 C 25.6875 24.402344 25.636719 25.105469 25.183594 25.558594 Z M 25.183594 25.558594 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 49 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(68.627453%,80.392158%,31.37255%);fill-opacity:1;" d="M 20.429688 34.667969 L 20.003906 34.660156 C 11.925781 34.441406 5.445312 27.960938 5.445312 20 C 5.445312 11.898438 12.15625 5.332031 20.429688 5.332031 L 28.601562 5.332031 C 36.875 5.332031 43.582031 11.898438 43.582031 20 C 43.582031 28.101562 36.875 34.667969 28.601562 34.667969 Z M 20.429688 34.667969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 25.472656 29.703125 C 25.472656 29.957031 25.371094 30.199219 25.195312 30.375 C 24.816406 30.746094 24.210938 30.746094 23.832031 30.375 C 23.652344 30.199219 23.550781 29.957031 23.554688 29.703125 L 23.554688 20.542969 C 22.628906 20.167969 22.027344 19.269531 22.019531 18.273438 C 22.019531 16.914062 23.140625 15.8125 24.515625 15.8125 C 25.890625 15.8125 27.007812 16.914062 27.007812 18.273438 C 27.007812 19.277344 26.394531 20.164062 25.476562 20.542969 L 25.476562 29.703125 Z M 31.429688 18.269531 C 31.429688 20.378906 30.324219 22.328125 28.519531 23.40625 C 28.066406 23.679688 27.480469 23.542969 27.199219 23.09375 C 27.066406 22.878906 27.023438 22.621094 27.082031 22.375 C 27.140625 22.128906 27.296875 21.921875 27.511719 21.789062 C 28.75 21.054688 29.507812 19.714844 29.507812 18.269531 C 29.507812 16.824219 28.75 15.488281 27.511719 14.75 C 27.296875 14.621094 27.140625 14.410156 27.082031 14.167969 C 27.023438 13.921875 27.066406 13.664062 27.199219 13.449219 C 27.480469 13.003906 28.066406 12.863281 28.519531 13.136719 C 30.324219 14.210938 31.433594 16.164062 31.433594 18.269531 Z M 31.738281 25.699219 C 31.3125 26.015625 30.714844 25.929688 30.394531 25.507812 C 30.242188 25.308594 30.175781 25.054688 30.210938 24.804688 C 30.25 24.554688 30.382812 24.332031 30.585938 24.183594 C 32.472656 22.808594 33.585938 20.609375 33.578125 18.269531 C 33.585938 15.933594 32.472656 13.730469 30.585938 12.359375 C 30.382812 12.210938 30.25 11.984375 30.210938 11.734375 C 30.175781 11.488281 30.242188 11.234375 30.394531 11.03125 C 30.71875 10.617188 31.3125 10.53125 31.738281 10.839844 C 34.121094 12.601562 35.519531 15.355469 35.503906 18.273438 C 35.507812 21.210938 34.109375 23.972656 31.738281 25.699219 Z M 19.515625 18.269531 C 19.515625 19.71875 20.261719 21.035156 21.511719 21.789062 C 21.726562 21.917969 21.882812 22.128906 21.941406 22.375 C 22.003906 22.621094 21.960938 22.878906 21.828125 23.09375 C 21.542969 23.539062 20.957031 23.675781 20.503906 23.40625 C 18.699219 22.328125 17.59375 20.378906 17.59375 18.269531 C 17.59375 16.164062 18.699219 14.210938 20.503906 13.136719 C 20.957031 12.867188 21.542969 13.003906 21.828125 13.449219 C 21.960938 13.664062 22.003906 13.921875 21.941406 14.167969 C 21.882812 14.410156 21.726562 14.621094 21.511719 14.75 C 20.273438 15.488281 19.515625 16.824219 19.515625 18.269531 Z M 18.429688 24.1875 C 18.632812 24.335938 18.765625 24.5625 18.800781 24.808594 C 18.839844 25.058594 18.773438 25.3125 18.621094 25.515625 C 18.296875 25.933594 17.699219 26.019531 17.273438 25.703125 C 14.90625 23.976562 13.503906 21.214844 13.511719 18.273438 C 13.503906 15.335938 14.90625 12.574219 17.273438 10.847656 C 17.480469 10.699219 17.734375 10.632812 17.988281 10.667969 C 18.238281 10.703125 18.464844 10.835938 18.621094 11.039062 C 18.773438 11.242188 18.839844 11.492188 18.800781 11.742188 C 18.765625 11.992188 18.632812 12.21875 18.429688 12.367188 C 16.542969 13.738281 15.429688 15.9375 15.433594 18.273438 C 15.429688 20.613281 16.542969 22.8125 18.429688 24.1875 Z M 18.429688 24.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 49 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 20.429688 34.667969 L 20.003906 34.660156 C 11.925781 34.441406 5.445312 27.960938 5.445312 20 C 5.445312 11.898438 12.15625 5.332031 20.429688 5.332031 L 28.601562 5.332031 C 36.875 5.332031 43.582031 11.898438 43.582031 20 C 43.582031 28.101562 36.875 34.667969 28.601562 34.667969 Z M 20.429688 34.667969 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 25.472656 29.703125 C 25.472656 29.957031 25.371094 30.199219 25.195312 30.375 C 24.816406 30.746094 24.210938 30.746094 23.832031 30.375 C 23.652344 30.199219 23.550781 29.957031 23.554688 29.703125 L 23.554688 20.542969 C 22.628906 20.167969 22.027344 19.269531 22.019531 18.273438 C 22.019531 16.914062 23.140625 15.8125 24.515625 15.8125 C 25.890625 15.8125 27.007812 16.914062 27.007812 18.273438 C 27.007812 19.277344 26.394531 20.164062 25.476562 20.542969 L 25.476562 29.703125 Z M 31.429688 18.269531 C 31.429688 20.378906 30.324219 22.328125 28.519531 23.40625 C 28.066406 23.679688 27.480469 23.542969 27.199219 23.09375 C 27.066406 22.878906 27.023438 22.621094 27.082031 22.375 C 27.140625 22.128906 27.296875 21.921875 27.511719 21.789062 C 28.75 21.054688 29.507812 19.714844 29.507812 18.269531 C 29.507812 16.824219 28.75 15.488281 27.511719 14.75 C 27.296875 14.621094 27.140625 14.410156 27.082031 14.167969 C 27.023438 13.921875 27.066406 13.664062 27.199219 13.449219 C 27.480469 13.003906 28.066406 12.863281 28.519531 13.136719 C 30.324219 14.210938 31.433594 16.164062 31.433594 18.269531 Z M 31.738281 25.699219 C 31.3125 26.015625 30.714844 25.929688 30.394531 25.507812 C 30.242188 25.308594 30.175781 25.054688 30.210938 24.804688 C 30.25 24.554688 30.382812 24.332031 30.585938 24.183594 C 32.472656 22.808594 33.585938 20.609375 33.578125 18.269531 C 33.585938 15.933594 32.472656 13.730469 30.585938 12.359375 C 30.382812 12.210938 30.25 11.984375 30.210938 11.734375 C 30.175781 11.488281 30.242188 11.234375 30.394531 11.03125 C 30.71875 10.617188 31.3125 10.53125 31.738281 10.839844 C 34.121094 12.601562 35.519531 15.355469 35.503906 18.273438 C 35.507812 21.210938 34.109375 23.972656 31.738281 25.699219 Z M 19.515625 18.269531 C 19.515625 19.71875 20.261719 21.035156 21.511719 21.789062 C 21.726562 21.917969 21.882812 22.128906 21.941406 22.375 C 22.003906 22.621094 21.960938 22.878906 21.828125 23.09375 C 21.542969 23.539062 20.957031 23.675781 20.503906 23.40625 C 18.699219 22.328125 17.59375 20.378906 17.59375 18.269531 C 17.59375 16.164062 18.699219 14.210938 20.503906 13.136719 C 20.957031 12.867188 21.542969 13.003906 21.828125 13.449219 C 21.960938 13.664062 22.003906 13.921875 21.941406 14.167969 C 21.882812 14.410156 21.726562 14.621094 21.511719 14.75 C 20.273438 15.488281 19.515625 16.824219 19.515625 18.269531 Z M 18.429688 24.1875 C 18.632812 24.335938 18.765625 24.5625 18.800781 24.808594 C 18.839844 25.058594 18.773438 25.3125 18.621094 25.515625 C 18.296875 25.933594 17.699219 26.019531 17.273438 25.703125 C 14.90625 23.976562 13.503906 21.214844 13.511719 18.273438 C 13.503906 15.335938 14.90625 12.574219 17.273438 10.847656 C 17.480469 10.699219 17.734375 10.632812 17.988281 10.667969 C 18.238281 10.703125 18.464844 10.835938 18.621094 11.039062 C 18.773438 11.242188 18.839844 11.492188 18.800781 11.742188 C 18.765625 11.992188 18.632812 12.21875 18.429688 12.367188 C 16.542969 13.738281 15.429688 15.9375 15.433594 18.273438 C 15.429688 20.613281 16.542969 22.8125 18.429688 24.1875 Z M 18.429688 24.1875 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(90.588236%,90.588236%,92.54902%);fill-opacity:1;" d="M 20 0 C 33.332031 0 40 6.667969 40 20 C 40 33.332031 33.332031 40 20 40 C 6.667969 40 0 33.332031 0 20 C 0 6.667969 6.667969 0 20 0 Z M 20 0 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(96.078432%,42.352942%,42.352942%);fill-opacity:1;" d="M 18.582031 29.328125 C 18.582031 28.53125 19.226562 27.882812 20.027344 27.882812 C 20.824219 27.882812 21.46875 28.53125 21.46875 29.328125 C 21.46875 30.125 20.824219 30.769531 20.027344 30.769531 C 19.230469 30.769531 18.582031 30.125 18.582031 29.328125 Z M 32.34375 15.113281 C 32.855469 15.625 32.855469 16.449219 32.347656 16.960938 C 31.835938 17.472656 31.011719 17.472656 30.496094 16.960938 C 24.699219 11.164062 15.300781 11.164062 9.503906 16.960938 C 8.996094 17.472656 8.167969 17.472656 7.65625 16.960938 C 7.410156 16.71875 7.273438 16.382812 7.273438 16.039062 C 7.273438 15.691406 7.410156 15.359375 7.65625 15.113281 C 14.472656 8.296875 25.527344 8.296875 32.34375 15.113281 Z M 11.285156 19.25 C 16.097656 14.441406 23.898438 14.441406 28.710938 19.25 C 29.222656 19.761719 29.222656 20.589844 28.710938 21.097656 C 28.46875 21.34375 28.136719 21.484375 27.789062 21.484375 C 27.441406 21.484375 27.109375 21.34375 26.863281 21.097656 C 23.074219 17.308594 16.921875 17.308594 13.132812 21.097656 C 12.625 21.613281 11.796875 21.613281 11.285156 21.101562 C 11.039062 20.855469 10.902344 20.523438 10.902344 20.175781 C 10.902344 19.828125 11.039062 19.496094 11.285156 19.25 Z M 25.183594 25.558594 C 24.738281 26.007812 24.035156 26.070312 23.515625 25.710938 L 23.5 25.730469 L 23.257812 25.484375 C 21.46875 23.699219 18.574219 23.695312 16.785156 25.484375 C 16.277344 25.996094 15.449219 25.996094 14.9375 25.488281 C 14.691406 25.242188 14.554688 24.910156 14.554688 24.5625 C 14.554688 24.214844 14.691406 23.882812 14.9375 23.636719 C 17.746094 20.828125 22.296875 20.828125 25.105469 23.636719 L 25.160156 23.695312 L 25.179688 23.710938 L 25.234375 23.765625 L 25.347656 23.882812 L 25.335938 23.894531 C 25.6875 24.402344 25.636719 25.105469 25.183594 25.558594 Z M 25.183594 25.558594 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(53.333336%,9.019608%,10.196079%);fill-opacity:1;" d="M 39.964844 19.410156 C 39.964844 19.410156 40.886719 0 19.558594 0 C 0.695312 0 0.105469 18.617188 0.105469 18.617188 C 0.105469 18.617188 -2.667969 40 19.996094 40 C 41.734375 40 39.964844 19.410156 39.964844 19.410156 Z M 13.589844 12.625 C 17.589844 10.175781 22.707031 11.675781 24.621094 15.355469 C 24.984375 16.054688 25.03125 17.128906 24.800781 17.859375 C 24.007812 20.386719 22.132812 21.804688 19.558594 22.40625 C 20.320312 21.757812 20.921875 21.019531 21.113281 20.003906 C 21.320312 19.023438 21.097656 18.003906 20.503906 17.199219 L 20.507812 17.210938 C 19.566406 15.914062 17.875 15.40625 16.375 15.96875 L 16.398438 15.960938 C 14.816406 16.558594 13.949219 18.007812 14.105469 19.785156 C 14.25 21.433594 15.503906 22.503906 17.847656 22.910156 C 17.496094 23.09375 17.226562 23.230469 16.960938 23.378906 C 15.898438 23.964844 14.96875 24.769531 14.238281 25.738281 L 14.222656 25.761719 C 13.984375 26.082031 13.824219 26.109375 13.457031 25.886719 C 8.746094 23.007812 8.445312 15.777344 13.589844 12.628906 Z M 10.066406 30.429688 C 9.308594 30.625 8.574219 30.90625 7.800781 31.160156 C 8.179688 28.605469 11.171875 26.253906 13.699219 26.523438 C 12.96875 27.527344 12.539062 28.71875 12.46875 29.957031 L 12.464844 29.976562 C 11.625 30.132812 10.832031 30.234375 10.066406 30.429688 Z M 26.171875 5.5 C 26.917969 5.527344 27.667969 5.515625 28.417969 5.535156 C 28.621094 5.546875 28.8125 5.578125 29 5.617188 L 28.972656 5.609375 C 28.804688 5.871094 28.613281 6.113281 28.402344 6.335938 L 28.40625 6.332031 C 28.140625 6.582031 27.835938 6.828125 27.449219 6.449219 C 27.359375 6.359375 27.140625 6.378906 26.980469 6.375 C 26.234375 6.367188 25.488281 6.339844 24.746094 6.371094 C 24.070312 6.390625 23.402344 6.460938 22.738281 6.578125 L 22.820312 6.566406 C 22.703125 6.585938 22.523438 6.984375 22.578125 7.128906 C 22.707031 7.476562 22.894531 7.855469 23.175781 8.074219 C 24.207031 8.890625 25.304688 9.621094 26.34375 10.429688 C 27.347656 11.214844 28.289062 12.078125 28.859375 13.265625 C 29.601562 14.808594 29.625 16.429688 29.304688 18.058594 C 28.765625 20.773438 27.390625 23.023438 25.164062 24.664062 C 24.269531 25.320312 23.15625 25.695312 22.128906 26.167969 C 21.226562 26.582031 20.296875 26.941406 19.390625 27.355469 C 17.757812 28.097656 16.839844 29.871094 17.109375 31.710938 C 17.359375 33.402344 18.84375 34.816406 20.539062 35.109375 C 22.578125 35.457031 24.683594 34.132812 25.179688 32.058594 C 25.742188 29.730469 24.476562 27.648438 22.105469 27.015625 L 21.679688 26.90625 C 22.3125 26.625 22.859375 26.421875 23.367188 26.144531 C 24.246094 25.65625 25.113281 25.144531 25.960938 24.601562 C 26.210938 24.441406 26.347656 24.441406 26.5625 24.625 C 28.191406 26.035156 29.164062 27.789062 29.4375 29.9375 C 29.886719 33.496094 28.203125 36.765625 25.027344 38.4375 C 20.113281 41.03125 14.097656 38.078125 13.011719 32.632812 C 12.082031 27.964844 15.375 23.734375 19.339844 22.917969 C 21.046875 22.566406 22.605469 21.855469 23.816406 20.542969 C 24.601562 19.695312 24.976562 18.96875 25.109375 18.640625 C 25.335938 18.070312 25.46875 17.410156 25.46875 16.71875 L 25.46875 16.707031 C 25.441406 16.128906 25.304688 15.554688 25.0625 15.027344 L 25.074219 15.054688 C 24.660156 14.109375 23.074219 12.609375 22.683594 12.296875 L 18.949219 9.371094 C 18.816406 9.261719 18.667969 9.269531 18.347656 9.292969 C 17.964844 9.320312 16.988281 9.371094 16.570312 9.261719 C 16.910156 9.003906 17.835938 8.628906 18.234375 8.328125 C 17.027344 7.511719 15.644531 7.804688 14.378906 7.5625 C 14.671875 7.015625 16.121094 6.175781 16.945312 6.082031 C 16.894531 5.59375 16.816406 5.109375 16.703125 4.628906 L 16.722656 4.710938 C 16.671875 4.527344 16.464844 4.347656 16.28125 4.242188 C 15.847656 3.984375 15.382812 3.773438 14.878906 3.515625 C 15.328125 3.226562 15.847656 3.0625 16.382812 3.050781 L 16.386719 3.050781 C 16.910156 3.035156 17.433594 3.085938 17.941406 3.207031 L 17.902344 3.199219 C 18.800781 3.402344 19.515625 3.269531 20.234375 2.660156 C 19.667969 2.433594 19.105469 2.226562 18.5625 1.980469 C 17.929688 1.691406 17.414062 1.417969 16.917969 1.117188 L 16.992188 1.160156 C 18.40625 1.355469 19.777344 1.886719 21.226562 1.691406 L 21.261719 1.496094 L 17.898438 0.710938 C 19.902344 0.527344 21.769531 0.5 23.539062 1.359375 C 24.035156 1.601562 24.554688 1.800781 25.03125 2.078125 C 25.265625 2.210938 25.421875 2.480469 25.613281 2.6875 C 25.761719 2.851562 25.886719 3.070312 26.074219 3.171875 C 26.777344 3.546875 27.554688 3.5625 28.347656 3.542969 L 28.363281 3.277344 C 29.164062 3.527344 30.058594 4.445312 30.058594 5.117188 C 28.765625 5.117188 27.476562 5.113281 26.183594 5.125 C 26.046875 5.125 25.910156 5.226562 25.773438 5.28125 C 25.902344 5.355469 26.03125 5.492188 26.164062 5.5 Z M 24.503906 3.589844 C 24.453125 3.621094 24.417969 3.675781 24.410156 3.738281 C 24.40625 3Line truncated
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="px" height="40px" viewBox="0 0 40 40" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.11765%,54.11765%,54.11765%);fill-opacity:1;" d="M 39.964844 19.410156 C 39.964844 19.410156 40.886719 0 19.558594 0 C 0.695312 0 0.105469 18.617188 0.105469 18.617188 C 0.105469 18.617188 -2.667969 40 19.996094 40 C 41.734375 40 39.964844 19.410156 39.964844 19.410156 Z M 13.589844 12.625 C 17.589844 10.175781 22.707031 11.675781 24.621094 15.355469 C 24.984375 16.054688 25.03125 17.128906 24.800781 17.863281 C 24.007812 20.386719 22.132812 21.804688 19.558594 22.410156 C 20.316406 21.757812 20.921875 21.023438 21.113281 20.003906 C 21.316406 19.03125 21.097656 18.015625 20.507812 17.210938 C 19.570312 15.921875 17.894531 15.414062 16.398438 15.960938 C 14.816406 16.558594 13.949219 18.007812 14.105469 19.785156 C 14.25 21.433594 15.503906 22.503906 17.847656 22.910156 C 17.496094 23.09375 17.226562 23.230469 16.964844 23.378906 C 15.890625 23.964844 14.953125 24.78125 14.222656 25.761719 C 13.984375 26.082031 13.824219 26.109375 13.460938 25.886719 C 8.75 23.003906 8.445312 15.773438 13.589844 12.625 Z M 10.066406 30.429688 C 9.308594 30.625 8.574219 30.90625 7.800781 31.160156 C 8.179688 28.605469 11.171875 26.253906 13.699219 26.523438 C 12.96875 27.53125 12.539062 28.730469 12.464844 29.976562 C 11.625 30.132812 10.832031 30.234375 10.066406 30.429688 Z M 26.171875 5.5 C 26.917969 5.527344 27.667969 5.515625 28.417969 5.535156 C 28.605469 5.546875 28.789062 5.570312 28.972656 5.613281 C 28.804688 5.867188 28.617188 6.109375 28.40625 6.335938 C 28.140625 6.585938 27.839844 6.828125 27.453125 6.449219 C 27.359375 6.359375 27.140625 6.378906 26.980469 6.375 C 26.234375 6.367188 25.488281 6.34375 24.746094 6.371094 C 24.101562 6.390625 23.460938 6.457031 22.824219 6.566406 C 22.703125 6.589844 22.527344 6.984375 22.578125 7.132812 C 22.710938 7.476562 22.898438 7.855469 23.179688 8.078125 C 24.210938 8.894531 25.308594 9.625 26.34375 10.433594 C 27.351562 11.21875 28.289062 12.082031 28.863281 13.265625 C 29.605469 14.8125 29.628906 16.433594 29.308594 18.058594 C 28.769531 20.777344 27.394531 23.027344 25.167969 24.664062 C 24.273438 25.320312 23.160156 25.695312 22.132812 26.167969 C 21.226562 26.585938 20.300781 26.941406 19.394531 27.355469 C 17.761719 28.097656 16.84375 29.871094 17.113281 31.714844 C 17.359375 33.40625 18.84375 34.816406 20.542969 35.109375 C 22.582031 35.457031 24.6875 34.132812 25.183594 32.058594 C 25.746094 29.730469 24.480469 27.648438 22.109375 27.019531 L 21.683594 26.910156 C 22.316406 26.625 22.863281 26.421875 23.371094 26.144531 C 24.25 25.660156 25.117188 25.144531 25.964844 24.601562 C 26.214844 24.441406 26.351562 24.441406 26.566406 24.625 C 28.195312 26.035156 29.167969 27.789062 29.441406 29.9375 C 29.890625 33.496094 28.207031 36.765625 25.03125 38.441406 C 20.117188 41.03125 14.101562 38.082031 13.015625 32.632812 C 12.085938 27.964844 15.378906 23.734375 19.34375 22.917969 C 21.050781 22.566406 22.609375 21.855469 23.820312 20.542969 C 24.601562 19.695312 24.980469 18.96875 25.113281 18.640625 C 25.351562 18.023438 25.476562 17.371094 25.472656 16.710938 C 25.449219 16.140625 25.3125 15.578125 25.078125 15.058594 C 24.664062 14.113281 23.078125 12.613281 22.6875 12.296875 L 18.953125 9.375 C 18.820312 9.265625 18.671875 9.273438 18.351562 9.296875 C 17.96875 9.320312 16.996094 9.375 16.574219 9.265625 C 16.914062 9.007812 17.839844 8.632812 18.242188 8.332031 C 17.03125 7.515625 15.652344 7.808594 14.382812 7.566406 C 14.675781 7.019531 16.125 6.179688 16.953125 6.085938 C 16.902344 5.625 16.828125 5.167969 16.726562 4.714844 C 16.675781 4.53125 16.46875 4.347656 16.289062 4.242188 C 15.851562 3.988281 15.386719 3.773438 14.882812 3.519531 C 15.335938 3.230469 15.855469 3.066406 16.394531 3.054688 C 16.902344 3.035156 17.410156 3.082031 17.90625 3.199219 C 18.808594 3.40625 19.523438 3.269531 20.238281 2.660156 C 19.675781 2.433594 19.113281 2.226562 18.566406 1.980469 C 18.027344 1.734375 17.503906 1.460938 16.996094 1.160156 C 18.414062 1.355469 19.78125 1.886719 21.230469 1.691406 L 21.265625 1.496094 L 17.902344 0.714844 C 19.910156 0.53125 21.773438 0.5 23.542969 1.359375 C 24.042969 1.601562 24.558594 1.804688 25.039062 2.078125 C 25.273438 2.214844 25.425781 2.480469 25.617188 2.6875 C 25.769531 2.851562 25.890625 3.070312 26.078125 3.171875 C 26.785156 3.546875 27.5625 3.5625 28.355469 3.542969 L 28.371094 3.277344 C 29.171875 3.527344 30.066406 4.445312 30.066406 5.117188 C 28.773438 5.117188 27.484375 5.113281 26.191406 5.125 C 26.054688 5.125 25.917969 5.226562 25.78125 5.28125 C 25.910156 5.359375 26.039062 5.496094 26.171875 5.5 Z M 24.503906 3.589844 C 24.453125 3.621094 24.417969 3.675781 24.410156 3.738281 C 24.40625 3.800781 24.429688 3.863281 24.476562 3.90625 C 24.519531 3.972656 24.582031 4.023438 24.660156 4.042969 C 24.738281 4.066406 24.820312 4.054688 24.886719 4.011719 C 25.011719 3.949219 25.136719 3.882812 25.285156 3.804688 C 25.164062 3.703125 25.066406 3.613281 24.96875 3.535156 Line truncated
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,11 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 68">
|
||||
<defs>
|
||||
<linearGradient id="lg" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0" stop-color="#ffffff" stop-opacity="0.9"/>
|
||||
<stop offset="0.45" stop-color="#9fd4ff" stop-opacity="0.5"/>
|
||||
<stop offset="1" stop-color="#1273c9" stop-opacity="0.92"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M32 3 C46 20 57 30 57 42 a25 25 0 0 1 -50 0 C7 30 18 20 32 3 Z" fill="url(#lg)" stroke="rgba(255,255,255,0.65)" stroke-width="1.5"/>
|
||||
<ellipse cx="23" cy="39" rx="9.5" ry="6" fill="#ffffff" opacity="0.55"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 584 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3a9 9 0 0 0 0 18 7 7 0 0 1 0-18z"/><path d="M19 4.5v4M17 6.5h4M20 15h.01M18.5 18.5l.01.01"/></svg>
|
||||
|
After Width: | Height: | Size: 270 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
|
||||
|
After Width: | Height: | Size: 191 B |