packages feed

hob (empty) → 0.0.1.0

raw patch · 149 files changed

+14525/−0 lines, 149 filesdep +basedep +bytestringdep +containerssetup-changedbinary-added

Dependencies added: base, bytestring, containers, directory, filepath, glib, gtk-largeTreeStore, gtk3, gtksourceview3, hob, hspec, mtl, pango, system-filepath, text, transformers, vector

Files

+ LICENSE view
@@ -0,0 +1,674 @@+                    GNU GENERAL PUBLIC LICENSE+                       Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://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 <http://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+<http://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+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
+ app-data/themes/gtk/default/app-specific.css view
@@ -0,0 +1,10 @@+.entry.error, .entry.error:focus {+  color: #FF7777;+  background-color: mix(@theme_bg_color, red, 0.1);+  border-color: red;+}++.entry.error:selected {+  color: #FFEE99;+  background-color: mix(@theme_bg_color, yellow, 0.2);+}
+ app-data/themes/gtk/default/assets/check-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-61.001 -787)">+  <path id="path8913-6-7-1-5" style="block-progression:tb;text-indent:0;color:#eeeeec;text-transform:none;fill:#eeeeec" d="m72.938 790.94-4.938 4.94l-1.9375-1.9375-2.125 2.125 3 3 1.0625 1.0625 1.0625-1.0625 6-6-2.125-2.125z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/check-insensitive-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-61.001 -787)">+  <path id="path8913-6-7-1-5" style="opacity:0.5;block-progression:tb;text-indent:0;color:#eeeeec;text-transform:none;fill:#eeeeec" d="m72.938 790.94-4.938 4.94l-1.9375-1.9375-2.125 2.125 3 3 1.0625 1.0625 1.0625-1.0625 6-6-2.125-2.125z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/check-insensitive.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-61.001 -787)">+  <path id="path8913-6-7-1-5" style="opacity:0.5;block-progression:tb;text-indent:0;color:#2e3436;text-transform:none;fill:#2e3436" d="m72.938 790.94-4.938 4.94l-1.9375-1.9375-2.125 2.125 3 3 1.0625 1.0625 1.0625-1.0625 6-6-2.125-2.125z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/check-selected.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-61.001 -787)">+  <path id="path8913-6-7-1-5" style="block-progression:tb;text-indent:0;color:#ffffff;text-transform:none;fill:#ffffff" d="m72.938 790.94-4.938 4.94l-1.9375-1.9375-2.125 2.125 3 3 1.0625 1.0625 1.0625-1.0625 6-6-2.125-2.125z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/check.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-61.001 -787)">+  <path id="path8913-6-7-1-5" style="block-progression:tb;text-indent:0;color:#2e3436;text-transform:none;fill:#2e3436" d="m72.938 790.94-4.938 4.94l-1.9375-1.9375-2.125 2.125 3 3 1.0625 1.0625 1.0625-1.0625 6-6-2.125-2.125z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/mix-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-40 -726)">+  <rect id="rect31984" style="color:#eeeeec;fill:#eeeeec" height="2.0002" width="9.9996" y="733" x="43"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/mix-insensitive-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-40 -726)">+  <rect id="rect31984" style="opacity:0.5;color:#eeeeec;fill:#eeeeec" height="2.0002" width="9.9996" y="733" x="43"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/mix-insensitive.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-40 -726)">+  <rect id="rect31984" style="opacity:0.5;color:#2e3436;fill:#2e3436" height="2.0002" width="9.9996" y="733" x="43"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/mix-selected.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-40 -726)">+  <rect id="rect31984" style="color:#ffffff;fill:#ffffff" height="2.0002" width="9.9996" y="733" x="43"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/mix.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="translate(-40 -726)">+  <rect id="rect31984" style="color:#2e3436;fill:#2e3436" height="2.0002" width="9.9996" y="733" x="43"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/noise-texture-dark.png view

binary file changed (absent → 69136 bytes)

+ app-data/themes/gtk/default/assets/noise-texture.png view

binary file changed (absent → 69136 bytes)

+ app-data/themes/gtk/default/assets/pane-separator-grip-active.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="2"+   height="22"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="32.454545"+     inkscape:cx="1"+     inkscape:cy="11"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3836"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,6)">+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3838"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3840"+       sodipodi:cx="1"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,6 A 1,1 0 1 1 0,6 1,1 0 1 1 2,6 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3842"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3844"+       sodipodi:cx="1"+       sodipodi:cy="16"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,16 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3846"+       sodipodi:cx="1"+       sodipodi:cy="21"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,21 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-dark.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="2"+   height="22"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="32.454545"+     inkscape:cx="1"+     inkscape:cy="11"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3836"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,6)">+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3838"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3840"+       sodipodi:cx="1"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,6 A 1,1 0 1 1 0,6 1,1 0 1 1 2,6 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3842"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3844"+       sodipodi:cx="1"+       sodipodi:cy="16"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,16 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3846"+       sodipodi:cx="1"+       sodipodi:cy="21"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,21 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-hover-dark.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="2"+   height="22"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="32.454545"+     inkscape:cx="1"+     inkscape:cy="11"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3836"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,6)">+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3838"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3840"+       sodipodi:cx="1"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,6 A 1,1 0 1 1 0,6 1,1 0 1 1 2,6 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3842"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3844"+       sodipodi:cx="1"+       sodipodi:cy="16"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,16 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3846"+       sodipodi:cx="1"+       sodipodi:cy="21"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,21 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-hover.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="2"+   height="22"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="32.454545"+     inkscape:cx="1"+     inkscape:cy="11"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3836"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,6)">+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3838"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3840"+       sodipodi:cx="1"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,6 A 1,1 0 1 1 0,6 1,1 0 1 1 2,6 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3842"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3844"+       sodipodi:cx="1"+       sodipodi:cy="16"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,16 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3846"+       sodipodi:cx="1"+       sodipodi:cy="21"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,21 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-vertical-active.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="22"+   height="2"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip-vertical.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="60.954545"+     inkscape:cx="11"+     inkscape:cy="1"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3757"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-14)">+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3759"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3761"+       sodipodi:cx="6"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,1 A 1,1 0 1 1 5,1 1,1 0 1 1 7,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3763"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3765"+       sodipodi:cx="16"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 17,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3767"+       sodipodi:cx="21"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 22,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-vertical-dark.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="22"+   height="2"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip-vertical.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="60.954545"+     inkscape:cx="11"+     inkscape:cy="1"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3757"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-14)">+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3759"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3761"+       sodipodi:cx="6"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,1 A 1,1 0 1 1 5,1 1,1 0 1 1 7,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3763"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3765"+       sodipodi:cx="16"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 17,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3767"+       sodipodi:cx="21"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 22,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-vertical-hover-dark.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="22"+   height="2"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip-vertical.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="60.954545"+     inkscape:cx="11"+     inkscape:cy="1"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3757"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-14)">+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3759"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3761"+       sodipodi:cx="6"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,1 A 1,1 0 1 1 5,1 1,1 0 1 1 7,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3763"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3765"+       sodipodi:cx="16"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 17,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3767"+       sodipodi:cx="21"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 22,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-vertical-hover.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="22"+   height="2"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip-vertical.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="60.954545"+     inkscape:cx="11"+     inkscape:cy="1"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3757"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-14)">+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3759"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3761"+       sodipodi:cx="6"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,1 A 1,1 0 1 1 5,1 1,1 0 1 1 7,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3763"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3765"+       sodipodi:cx="16"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 17,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3767"+       sodipodi:cx="21"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 22,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip-vertical.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="22"+   height="2"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip-vertical.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="60.954545"+     inkscape:cx="11"+     inkscape:cy="1"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3757"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-14)">+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3759"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3761"+       sodipodi:cx="6"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,1 A 1,1 0 1 1 5,1 1,1 0 1 1 7,1 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3763"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3765"+       sodipodi:cx="16"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 17,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3767"+       sodipodi:cx="21"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 22,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,14)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/pane-separator-grip.svg view
@@ -0,0 +1,115 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="2"+   height="22"+   id="svg32934"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="pane-separator-grip.svg">+  <defs+     id="defs32936" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="32.454545"+     inkscape:cx="1"+     inkscape:cy="11"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3836"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata32939">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,6)">+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3838"+       sodipodi:cx="1"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,1 A 1,1 0 1 1 0,1 1,1 0 1 1 2,1 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3840"+       sodipodi:cx="1"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 2,6 A 1,1 0 1 1 0,6 1,1 0 1 1 2,6 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3842"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3844"+       sodipodi:cx="1"+       sodipodi:cy="16"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,16 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3846"+       sodipodi:cx="1"+       sodipodi:cy="21"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,21 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,-6)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="color:#eeeeec;text-indent:0pt;text-transform:none;fill:#eeeeec" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-hover-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="color:#babdb6;text-indent:0pt;text-transform:none;fill:#babdb6" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-hover.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="color:#888a85;text-indent:0pt;text-transform:none;fill:#888a85" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-insensitive-dark.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="opacity:0.5;color:#eeeeec;text-indent:0pt;text-transform:none;fill:#eeeeec" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-insensitive.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="opacity:0.5;color:#2e3436;text-indent:0pt;text-transform:none;fill:#2e3436" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-selected-hover.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="opacity:0.5;color:#ffffff;text-indent:0pt;text-transform:none;fill:#ffffff" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio-selected.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="color:#ffffff;text-indent:0pt;text-transform:none;fill:#ffffff" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/radio.svg view
@@ -0,0 +1,17 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->+<svg id="svg7384" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">+ <title id="title9167">Gnome Symbolic Icon Theme</title>+ <metadata id="metadata90">+  <rdf:RDF>+   <cc:Work rdf:about="">+    <dc:format>image/svg+xml</dc:format>+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>+    <dc:title>Gnome Symbolic Icon Theme</dc:title>+   </cc:Work>+  </rdf:RDF>+ </metadata>+ <g id="layer12" transform="matrix(0.88734967,0,0,0.54841228,-578.5098,-131.88177)">+  <path id="path4646-0" style="color:#2e3436;text-indent:0pt;text-transform:none;fill:#2e3436" d="m 665.47588,255.0668 a 4.5078058,7.2937827 0 1 1 -9.01561,0 4.5078058,7.2937827 0 1 1 9.01561,0 z"/>+ </g>+</svg>
+ app-data/themes/gtk/default/assets/resize-grip-active.svg view
@@ -0,0 +1,125 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="12"+   height="12"+   id="svg17653"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="resize-grip.svg">+  <defs+     id="defs17655" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="59.5"+     inkscape:cx="6"+     inkscape:cy="6"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3758"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata17658">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-4)">+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3776"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3778"+       sodipodi:cx="11"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,6 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3780"+       sodipodi:cx="11"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3782"+       sodipodi:cx="6"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 7,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3784"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#4e9a06;fill-opacity:1;stroke:none"+       id="path3786"+       sodipodi:cx="6"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,6 A 1,1 0 1 1 5,6 1,1 0 1 1 7,6 z"+       transform="translate(0,4)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/resize-grip-dark.svg view
@@ -0,0 +1,125 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="12"+   height="12"+   id="svg17653"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="resize-grip.svg">+  <defs+     id="defs17655" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="59.5"+     inkscape:cx="6"+     inkscape:cy="6"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3758"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata17658">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-4)">+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3776"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3778"+       sodipodi:cx="11"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,6 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3780"+       sodipodi:cx="11"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3782"+       sodipodi:cx="6"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 7,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3784"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#babdb6;fill-opacity:1;stroke:none"+       id="path3786"+       sodipodi:cx="6"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,6 A 1,1 0 1 1 5,6 1,1 0 1 1 7,6 z"+       transform="translate(0,4)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/resize-grip-hover-dark.svg view
@@ -0,0 +1,125 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="12"+   height="12"+   id="svg17653"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="resize-grip.svg">+  <defs+     id="defs17655" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="59.5"+     inkscape:cx="6"+     inkscape:cy="6"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3758"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata17658">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-4)">+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3776"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3778"+       sodipodi:cx="11"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,6 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3780"+       sodipodi:cx="11"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3782"+       sodipodi:cx="6"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 7,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3784"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       id="path3786"+       sodipodi:cx="6"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,6 A 1,1 0 1 1 5,6 1,1 0 1 1 7,6 z"+       transform="translate(0,4)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/resize-grip-hover.svg view
@@ -0,0 +1,125 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="12"+   height="12"+   id="svg17653"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="resize-grip.svg">+  <defs+     id="defs17655" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="59.5"+     inkscape:cx="6"+     inkscape:cy="6"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3758"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata17658">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-4)">+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3776"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3778"+       sodipodi:cx="11"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,6 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3780"+       sodipodi:cx="11"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3782"+       sodipodi:cx="6"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 7,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3784"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#2e3436;fill-opacity:1;stroke:none"+       id="path3786"+       sodipodi:cx="6"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,6 A 1,1 0 1 1 5,6 1,1 0 1 1 7,6 z"+       transform="translate(0,4)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/resize-grip.svg view
@@ -0,0 +1,125 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="12"+   height="12"+   id="svg17653"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="resize-grip.svg">+  <defs+     id="defs17655" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="59.5"+     inkscape:cx="6"+     inkscape:cy="6"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:grid-bbox="true"+     inkscape:document-units="px"+     inkscape:window-width="1920"+     inkscape:window-height="917"+     inkscape:window-x="0"+     inkscape:window-y="27"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid3758"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata17658">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     id="layer1"+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     transform="translate(0,-4)">+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3776"+       sodipodi:cx="11"+       sodipodi:cy="1"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,1 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3778"+       sodipodi:cx="11"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,6 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3780"+       sodipodi:cx="11"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 12,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3782"+       sodipodi:cx="6"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 7,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3784"+       sodipodi:cx="1"+       sodipodi:cy="11"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="m 2,11 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"+       transform="translate(0,4)" />+    <path+       sodipodi:type="arc"+       style="fill:#888a85;fill-opacity:1;stroke:none"+       id="path3786"+       sodipodi:cx="6"+       sodipodi:cy="6"+       sodipodi:rx="1"+       sodipodi:ry="1"+       d="M 7,6 A 1,1 0 1 1 5,6 1,1 0 1 1 7,6 z"+       transform="translate(0,4)" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-active-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-active.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#4b4e4c;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#2c2f2f;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-fine-tune-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#536443;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#3B4F32;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-fine-tune.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#DCEBCE;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#C4D5B3;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-hover-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-hover.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-insensitive-dark.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:0.5;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#414544;fill-opacity:1;stroke:none"+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down-insensitive.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:0.5;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-down.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-left.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#f7f7f6;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#d4d6d1;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="1"+       x2="12"+       y2="23"+       gradientUnits="userSpaceOnUse"+       gradientTransform="translate(0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,12 12,-12 z m 0,0 c 0,-6.6274 5.3726,-12 12,-12 6.6274,0 12,5.3726 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,11 11,-11 z m 0,0 c 0,-6.0751 4.9249,-11 11,-11 6.0751,0 11,4.9249 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-active-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-active.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#4b4e4c;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#2c2f2f;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-fine-tune-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#536443;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#3B4F32;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-fine-tune.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#DCEBCE;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#C4D5B3;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-hover-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-hover.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-insensitive-dark.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:0.5;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#414544;fill-opacity:1;stroke:none"+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left-insensitive.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:0.5;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-left.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-right.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#f7f7f6;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#d4d6d1;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,-1,0,24,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 -12,12 12,12 z m 0,0 c 6.6274,0 12,5.3726 12,12 0,6.6274 -5.3726,12 -12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 -11,11 11,11 z m 0,0 c 6.0751,0 11,4.9249 11,11 0,6.0751 -4.9249,11 -11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-active-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-active.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#4b4e4c;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#2c2f2f;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-fine-tune-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#536443;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#3B4F32;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-fine-tune.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#DCEBCE;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#C4D5B3;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-hover-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-hover.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-insensitive-dark.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:0.5;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#414544;fill-opacity:1;stroke:none"+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right-insensitive.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:0.5;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-right.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-up.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#f7f7f6;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#d4d6d1;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="1"+       y1="12"+       x2="23"+       y2="12"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(0,1,1,0,0,1028.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 12,1028.3622 12,12 -12,12 z m 0,0 c -6.6274,0 -12,5.3726 -12,12 0,6.6274 5.3726,12 12,12"+       inkscape:connector-curvature="0" />+    <path+       d="m 12,1029.3622 11,11 -11,11 z m 0,0 c -6.0751,0 -11,4.9249 -11,11 0,6.0751 4.9249,11 11,11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-active-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-active.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#4b4e4c;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#2c2f2f;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-fine-tune-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#536443;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#3B4F32;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#63A129;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-fine-tune.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#DCEBCE;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#C4D5B3;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#59971F;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-hover-dark.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#555753;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#373c3d;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-hover.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#ffffff;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#e1e3de;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-insensitive-dark.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#0B0D0D;fill-opacity:0.5;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#414544;fill-opacity:1;stroke:none"+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up-insensitive.svg view
@@ -0,0 +1,73 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:0.5;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       id="path3765"+       style="fill:#eeeeec;fill-opacity:1;stroke:none"+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/scale-slider-up.svg view
@@ -0,0 +1,97 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:xlink="http://www.w3.org/1999/xlink"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="24"+   height="24"+   id="svg2"+   version="1.1"+   inkscape:version="0.48.4 r9939"+   sodipodi:docname="scale-slider-down.svg">+  <defs+     id="defs4">+    <linearGradient+       id="linearGradient3771">+      <stop+         style="stop-color:#f7f7f6;stop-opacity:1;"+         offset="0"+         id="stop3773" />+      <stop+         style="stop-color:#d4d6d1;stop-opacity:1;"+         offset="1"+         id="stop3775" />+    </linearGradient>+    <linearGradient+       inkscape:collect="always"+       xlink:href="#linearGradient3771"+       id="linearGradient3777"+       x1="12"+       y1="23"+       x2="12"+       y2="1"+       gradientUnits="userSpaceOnUse"+       gradientTransform="matrix(1,0,0,-1,0,1052.3622)" />+  </defs>+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="29.541667"+     inkscape:cx="12"+     inkscape:cy="12"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="true"+     inkscape:window-width="1920"+     inkscape:window-height="912"+     inkscape:window-x="0"+     inkscape:window-y="32"+     inkscape:window-maximized="1">+    <inkscape:grid+       type="xygrid"+       id="grid2985"+       empspacing="5"+       visible="true"+       enabled="true"+       snapvisiblegridlinesonly="true" />+  </sodipodi:namedview>+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title></dc:title>+      </cc:Work>+    </rdf:RDF>+  </metadata>+  <g+     inkscape:label="レイヤー 1"+     inkscape:groupmode="layer"+     id="layer1"+     transform="translate(0,-1028.3622)">+    <path+       id="path2989"+       style="fill:#A1A49E;fill-opacity:1;stroke:none"+       d="m 0,1040.3622 12,-12 12,12 z m 0,0 c 3.0757981e-7,6.6274 5.3725836,12 12.000001,12 6.627416,0 11.999999,-5.3726 11.999999,-12"+       inkscape:connector-curvature="0" />+    <path+       d="m 1,1040.3622 11,-11 11,11 z m 0,0 c 3e-7,6.0751 4.9248683,11 11.000001,11 6.075132,0 10.999999,-4.9249 10.999999,-11"+       style="fill:url(#linearGradient3777);fill-opacity:1;stroke:none"+       id="path3769"+       inkscape:connector-curvature="0" />+  </g>+</svg>
+ app-data/themes/gtk/default/assets/thumbnail-frame.png view

binary file changed (absent → 832 bytes)

+ app-data/themes/gtk/default/gtk-common.css view
@@ -0,0 +1,59 @@+/* common color definitions to the light and dark variations */+@define-color alt_base_color mix(@theme_bg_color, @theme_base_color, 0.5);+@define-color alt_subdued_color mix(@theme_bg_color, @subdued_color, 0.5);++@define-color alt_border_color mix(@theme_tooltip_bg_color, @border_color, 0.5);+@define-color colored_border_color mix(@alt_border_color, shade(@theme_selected_bg_color, 0.5), 0.2);+@define-color focused_border_color mix(@internal_element_color, @theme_selected_bg_color, 0.8);+@define-color suggested_action_border_color mix(@alt_border_color, shade(@theme_selected_bg_color, 0.2), 0.2);+@define-color destructive_action_border_color mix(@alt_border_color, shade(@error_color, 0.2), 0.2);+@define-color insensitive_border_color alpha(@alt_border_color, 0.5);++/* +@define-color insensitive_fg_color alpha(@theme_fg_color, 0.5);+@define-color insensitive_internal_element_color alpha(@internal_element_color, 0.5);+@define-color selected_internal_element_color alpha(@theme_selected_fg_color, 0.6);+ */+@define-color insensitive_fg_color mix(@theme_fg_color, @theme_bg_color, 0.5);+@define-color insensitive_internal_element_color mix(@internal_element_color, @theme_bg_color, 0.5);+@define-color selected_internal_element_color mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.4);++@define-color button_top_color mix(@active_element, @theme_base_color, 0.7);+@define-color button_bottom_color mix(@active_element, @theme_bg_color, 0.7);+@define-color button_top_hover_color mix(@active_element, @theme_base_color, 0.6);+@define-color button_bottom_hover_color mix(@active_element, @theme_bg_color, 0.6);+@define-color button_top_active_color mix(@active_element, @theme_base_color, 0.5);+@define-color button_bottom_active_color  mix(@active_element, @theme_bg_color, 0.5);+@define-color button_top_active_hover_color  mix(@active_element, @theme_base_color, 0.4);+@define-color button_bottom_active_hover_color mix(@active_element, @theme_bg_color, 0.4);++@define-color colored_button_top_color mix(@button_top_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_bottom_color mix(@button_bottom_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_top_hover_color mix(@button_top_hover_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_bottom_hover_color mix(@button_bottom_hover_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_top_active_color mix(@button_top_active_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_bottom_active_color mix(@button_bottom_active_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_top_active_hover_color mix(@button_top_active_hover_color, @theme_selected_bg_color, 0.2);+@define-color colored_button_bottom_active_hover_color mix(@button_bottom_active_hover_color, @theme_selected_bg_color, 0.2);++@define-color suggested_action_button_top_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 1.1), 0.8);+@define-color suggested_action_button_bottom_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 0.9), 0.8);+@define-color suggested_action_button_top_hover_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 1.2), 0.8);+@define-color suggested_action_button_bottom_hover_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 1.0), 0.8);+@define-color suggested_action_button_top_active_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 0.9), 0.8);+@define-color suggested_action_button_bottom_active_color mix(@theme_bg_color, shade(@theme_selected_bg_color, 1.0), 0.8);++@define-color destructive_action_button_top_color mix(@theme_bg_color, shade(@error_color, 1.1), 0.8);+@define-color destructive_action_button_bottom_color mix(@theme_bg_color, shade(@error_color, 0.9), 0.8);+@define-color destructive_action_button_top_hover_color mix(@theme_bg_color, shade(@error_color, 1.2), 0.8);+@define-color destructive_action_button_bottom_hover_color mix(@theme_bg_color, shade(@error_color, 1.0), 0.8);+@define-color destructive_action_button_top_active_color mix(@theme_bg_color, shade(@error_color, 0.9), 0.8);+@define-color destructive_action_button_bottom_active_color mix(@theme_bg_color, shade(@error_color, 1.0), 0.8);++/*****************+ * Fallback Mode *+ *****************/+@define-color os_chrome_bg_color black;+@define-color os_chrome_fg_color #ccc;+@define-color os_chrome_selected_bg_color #333;+@define-color os_chrome_selected_fg_color white;
+ app-data/themes/gtk/default/gtk-dark.css view
@@ -0,0 +1,36 @@+@import url("reset.css");++/* Dark color scheme */+@define-color theme_base_color #2a2f25;+@define-color active_element #caba9a;+@define-color theme_text_color #d0d5d0;+@define-color border_color #304020;+@define-color internal_element_color #cacdc6;++@define-color theme_selected_bg_color #658a60;+@define-color theme_selected_fg_color #ffffff;++@define-color link_color #729fcf;+@define-color info_color #c4a000;+@define-color warning_color #f57900;+@define-color question_color #ad7fa8;+@define-color error_color #ef2929;+@define-color other_color #c17d11;+++@define-color subdued_color shade(@theme_base_color, 0.3);+@define-color theme_bg_color #222320;+@define-color theme_fg_color @theme_text_color;+@define-color theme_tooltip_bg_color mix(@subdued_color, #000000, 0.5);+@define-color theme_tooltip_fg_color @theme_text_color;++@define-color placeholder_text_color @internal_element_color;++@import url("gtk-common.css");+@import url("gtk-widgets-assets-dark.css");+@import url("gtk-widgets-backgrounds-and-texts.css");+@import url("gtk-widgets-borders.css");+@import url("gtk-widgets.css");+@import url("app-specific.css");+@import url("keybindings.css");+
+ app-data/themes/gtk/default/gtk-fallback.css view
@@ -0,0 +1,15 @@+.menu {+    border-image: linear-gradient(to top,+                                  alpha(@border_color, 0.80),+                                  alpha(@border_color, 0.60) 33%,+                                  alpha(@border_color, 0.50) 66%,+                                  alpha(@border_color, 0.15)) 1 1 1 1/ 1px 1px 1px 1px;+}++.menubar .menu {+    border-image: linear-gradient(to top,+                                  alpha(@border_color, 0.80),+                                  alpha(@border_color, 0.60) 33%,+                                  alpha(@border_color, 0.50) 66%,+                                  transparent 99%) 1 1 1 1/ 1px 1px 1px 1px;+}
+ app-data/themes/gtk/default/gtk-widgets-assets-dark.css view
@@ -0,0 +1,339 @@+/****************+ * Content view *+ ****************/+.content-view.view {+    background-image: url("assets/noise-texture-dark.png");+}++/***************+ * Resize grip *+ ***************/+.grip {+    background-image: url("assets/resize-grip-dark.svg");+}++.grip:hover {+    background-image: url("assets/resize-grip-hover-dark.svg");+}++.grip:active {+    background-image: url("assets/resize-grip-active.svg");+}++/*******************+ * Pane separators *+ *******************/+.pane-separator {+    background-position: center;+    background-repeat: no-repeat;+    background-image: url("assets/pane-separator-grip-dark.svg");+}++.pane-separator:hover {+    background-image: url("assets/pane-separator-grip-hover-dark.svg");+}++.pane-separator:active {+    background-image: url("assets/pane-separator-grip-active.svg");+}++.pane-separator.vertical {+    background-image: url("assets/pane-separator-grip-vertical-dark.svg");+}++.pane-separator.vertical:hover {+    background-image: url("assets/pane-separator-grip-vertical-hover-dark.svg");+}++.pane-separator.vertical:active {+    background-image: url("assets/pane-separator-grip-vertical-active.svg");+}++/*************************+ * Check and Radio items *+ *************************/+.check:active,+.check row:active,+.view.cell.check:active {+    background-image: url("assets/check-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      @suggested_action_button_bottom_color+                                      );+    background-color: transparent;+}++.check:active:hover,+.check row:active:hover,+.view.cell.check:active:hover {+    background-image: url("assets/check-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_hover_color,+                                      @suggested_action_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.check:active:insensitive,+.check row:active:insensitive,+.view.cell.check:active:insensitive {+    background-image: url("assets/check-insensitive-dark.svg");+    background-color: @theme_bg_color;+}++.radio:active,+.radio row:active,+.view.cell.radio:active {+    background-image: url("assets/radio-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      @suggested_action_button_bottom_color+                                      );+    background-color: transparent;+}++.radio:active:hover,+.radio row:active:hover,+.view.cell.radio:active:hover {+    background-image: url("assets/radio-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_hover_color,+                                      @suggested_action_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.radio:active:insensitive,+.radio row:active:insensitive,+.view.cell.radio:active:insensitive {+    background-image: url("assets/radio-insensitive-dark.svg");+    background-color: @theme_bg_color;+}++.check:inconsistent,+.check row:inconsistent,+.view.cell.check:inconsistent,+.radio:inconsistent,+.radio row:inconsistent,+.view.cell.radio:inconsistent {+    background-image: url("assets/mix-dark.svg"),+                      linear-gradient(to bottom,+                                      @colored_button_top_color,+                                      @colored_button_bottom_color+                                      );+    background-color: transparent;+}++.check:inconsistent:hover,+.check row:inconsistent:hover,+.view.cell.check:inconsistent:hover,+.radio:inconsistent:hover,+.radio row:inconsistent:hover,+.view.cell.radio:inconsistent:hover {+    background-image: url("assets/mix-dark.svg"),+                      linear-gradient(to bottom,+                                      @colored_button_top_hover_color,+                                      @colored_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.check:inconsistent:insensitive,+.check row:inconsistent:insensitive,+.view.cell.check:inconsistent:insensitive,+.radio:inconsistent:insensitive,+.radio row:inconsistent:insensitive,+.view.cell.radio:inconsistent:insensitive {+    background-image: url("assets/mix-insensitive-dark.svg");+    background-color: @theme_bg_color;+}++.menuitem.check:active {+    background-image: url("assets/check-dark.svg");+    background-color: transparent;+}++.menuitem.check:active:hover {+    background-image: url("assets/check-selected.svg");+    background-color: transparent;+}++.menuitem.check:active:insensitive {+    background-image: url("assets/check-insensitive-dark.svg");+    background-color: transparent;+}++.menuitem.radio:active {+    background-image: url("assets/radio-dark.svg");+    background-color: transparent;+}++.menuitem.radio:active:hover {+    background-image: url("assets/radio-selected.svg");+    background-color: transparent;+}++.menuitem.radio:active:insensitive {+    background-image: url("assets/radio-insensitive-dark.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent,+.menuitem.radio:inconsistent {+    background-image: url("assets/mix-dark.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent:hover,+.menuitem.radio:inconsistent:hover {+    background-image: url("assets/mix-selected.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent:insensitive,+.menuitem.radio:inconsistent:insensitive {+    background-image: url("assets/mix-insensitive-dark.svg");+    background-color: transparent;+}++.sidebar .view.radio:hover,+.sidebar .view.radio:focus {+    background-image: url("assets/radio-hover-dark.svg");+    background-color: transparent;+}++.sidebar .view.radio:active,+.sidebar .view.radio:active:hover,+.sidebar .view.radio:active:focus {+    background-image: url("assets/radio-dark.svg");+    background-color: transparent;+}++.sidebar .view.radio:selected:hover,+.sidebar .view.radio:selected:focus {+    background-image: url("assets/radio-selected-hover.svg");+    background-color: transparent; +}++.sidebar .view.radio:selected:active,+.sidebar .view.radio:selected:active:hover,+.sidebar .view.radio:selected:active:focus {+    background-image: url("assets/radio-selected.svg");+    background-color: transparent;+}++/*********************+ * GtkScale's slider *+ *********************/+.scale.scale-has-marks-above.slider.horizontal {+    background-image: url("assets/scale-slider-up-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:hover {+    background-image: url("assets/scale-slider-up-hover-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:active {+    background-image: url("assets/scale-slider-up-active-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.fine-tune.horizontal:active {+    background-image: url("assets/scale-slider-up-fine-tune-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:insensitive {+    background-image: url("assets/scale-slider-up-insensitive-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical {+    background-image: url("assets/scale-slider-left-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:hover {+    background-image: url("assets/scale-slider-left-hover-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:active {+    background-image: url("assets/scale-slider-left-active-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.fine-tune.vertical:active {+    background-image: url("assets/scale-slider-left-fine-tune-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:insensitive {+    background-image: url("assets/scale-slider-left-insensitive-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal {+    background-image: url("assets/scale-slider-down-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:hover {+    background-image: url("assets/scale-slider-down-hover-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:active {+    background-image: url("assets/scale-slider-down-active-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.fine-tune.horizontal:active {+    background-image: url("assets/scale-slider-down-fine-tune-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:insensitive {+    background-image: url("assets/scale-slider-down-insensitive-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical {+    background-image: url("assets/scale-slider-right-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:hover {+    background-image: url("assets/scale-slider-right-hover-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:active {+    background-image: url("assets/scale-slider-right-active-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.fine-tune.vertical:active {+    background-image: url("assets/scale-slider-right-fine-tune-dark.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:insensitive {+    background-image: url("assets/scale-slider-right-insensitive-dark.svg");+    background-color: transparent;+}++/********************************+ * Touch text selection handles *+ ********************************/+.cursor-handle.bottom {+    background-image: url("assets/scale-slider-up-dark.svg");+    background-color: transparent;+}++.cursor-handle.top {+    background-image: url("assets/scale-slider-down-dark.svg");+    background-color: transparent;+}
+ app-data/themes/gtk/default/gtk-widgets-assets.css view
@@ -0,0 +1,339 @@+/****************+ * Content view *+ ****************/+.content-view.view {+    background-image: url("assets/noise-texture.png");+}++/***************+ * Resize grip *+ ***************/+.grip {+    background-image: url("assets/resize-grip.svg");+}++.grip:hover {+    background-image: url("assets/resize-grip-hover.svg");+}++.grip:active {+    background-image: url("assets/resize-grip-active.svg");+}++/*******************+ * Pane separators *+ *******************/+.pane-separator {+    background-position: center;+    background-repeat: no-repeat;+    background-image: url("assets/pane-separator-grip.svg");+}++.pane-separator:hover {+    background-image: url("assets/pane-separator-grip-hover.svg");+}++.pane-separator:active {+    background-image: url("assets/pane-separator-grip-active.svg");+}++.pane-separator.vertical {+    background-image: url("assets/pane-separator-grip-vertical.svg");+}++.pane-separator.vertical:hover {+    background-image: url("assets/pane-separator-grip-vertical-hover.svg");+}++.pane-separator.vertical:active {+    background-image: url("assets/pane-separator-grip-vertical-active.svg");+}++/*************************+ * Check and Radio items *+ *************************/+.check:active,+.check row:active,+.view.cell.check:active {+    background-image: url("assets/check-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      @suggested_action_button_bottom_color+                                      );+    background-color: transparent;+}++.check:active:hover,+.check row:active:hover,+.view.cell.check:active:hover {+    background-image: url("assets/check-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_hover_color,+                                      @suggested_action_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.check:active:insensitive,+.check row:active:insensitive,+.view.cell.check:active:insensitive {+    background-image: url("assets/check-insensitive.svg");+    background-color: @theme_bg_color;+}++.radio:active,+.radio row:active,+.view.cell.radio:active {+    background-image: url("assets/radio-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      @suggested_action_button_bottom_color+                                      );+    background-color: transparent;+}++.radio:active:hover,+.radio row:active:hover,+.view.cell.radio:active:hover {+    background-image: url("assets/radio-selected.svg"),+                      linear-gradient(to bottom,+                                      @suggested_action_button_top_hover_color,+                                      @suggested_action_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.radio:active:insensitive,+.radio row:active:insensitive,+.view.cell.radio:active:insensitive {+    background-image: url("assets/radio-insensitive.svg");+    background-color: @theme_bg_color;+}++.check:inconsistent,+.check row:inconsistent,+.view.cell.check:inconsistent,+.radio:inconsistent,+.radio row:inconsistent,+.view.cell.radio:inconsistent {+    background-image: url("assets/mix.svg"),+                      linear-gradient(to bottom,+                                      @colored_button_top_color,+                                      @colored_button_bottom_color+                                      );+    background-color: transparent;+}++.check:inconsistent:hover,+.check row:inconsistent:hover,+.view.cell.check:inconsistent:hover,+.radio:inconsistent:hover,+.radio row:inconsistent:hover,+.view.cell.radio:inconsistent:hover {+    background-image: url("assets/mix.svg"),+                      linear-gradient(to bottom,+                                      @colored_button_top_hover_color,+                                      @colored_button_bottom_hover_color+                                      );+    background-color: transparent;+}++.check:inconsistent:insensitive,+.check row:inconsistent:insensitive,+.view.cell.check:inconsistent:insensitive,+.radio:inconsistent:insensitive,+.radio row:inconsistent:insensitive,+.view.cell.radio:inconsistent:insensitive {+    background-image: url("assets/mix-insensitive.svg");+    background-color: @theme_bg_color;+}++.menuitem.check:active {+    background-image: url("assets/check.svg");+    background-color: transparent;+}++.menuitem.check:active:hover {+    background-image: url("assets/check-selected.svg");+    background-color: transparent;+}++.menuitem.check:active:insensitive {+    background-image: url("assets/check-insensitive.svg");+    background-color: transparent;+}++.menuitem.radio:active {+    background-image: url("assets/radio.svg");+    background-color: transparent;+}++.menuitem.radio:active:hover {+    background-image: url("assets/radio-selected.svg");+    background-color: transparent;+}++.menuitem.radio:active:insensitive {+    background-image: url("assets/radio-insensitive.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent,+.menuitem.radio:inconsistent {+    background-image: url("assets/mix.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent:hover,+.menuitem.radio:inconsistent:hover {+    background-image: url("assets/mix-selected.svg");+    background-color: transparent;+}++.menuitem.check:inconsistent:insensitive,+.menuitem.radio:inconsistent:insensitive {+    background-image: url("assets/mix-insensitive.svg");+    background-color: transparent;+}++.sidebar .view.radio:hover,+.sidebar .view.radio:focus {+    background-image: url("assets/radio-hover.svg");+    background-color: transparent;+}++.sidebar .view.radio:active,+.sidebar .view.radio:active:hover,+.sidebar .view.radio:active:focus {+    background-image: url("assets/radio.svg");+    background-color: transparent;+}++.sidebar .view.radio:selected:hover,+.sidebar .view.radio:selected:focus {+    background-image: url("assets/radio-selected-hover.svg");+    background-color: transparent; +}++.sidebar .view.radio:selected:active,+.sidebar .view.radio:selected:active:hover,+.sidebar .view.radio:selected:active:focus {+    background-image: url("assets/radio-selected.svg");+    background-color: transparent;+}++/*********************+ * GtkScale's slider *+ *********************/+.scale.scale-has-marks-above.slider.horizontal {+    background-image: url("assets/scale-slider-up.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:hover {+    background-image: url("assets/scale-slider-up-hover.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:active {+    background-image: url("assets/scale-slider-up-active.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.fine-tune.horizontal:active {+    background-image: url("assets/scale-slider-up-fine-tune.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.horizontal:insensitive {+    background-image: url("assets/scale-slider-up-insensitive.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical {+    background-image: url("assets/scale-slider-left.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:hover {+    background-image: url("assets/scale-slider-left-hover.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:active {+    background-image: url("assets/scale-slider-left-active.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.fine-tune.vertical:active {+    background-image: url("assets/scale-slider-left-fine-tune.svg");+    background-color: transparent;+}++.scale.scale-has-marks-above.slider.vertical:insensitive {+    background-image: url("assets/scale-slider-left-insensitive.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal {+    background-image: url("assets/scale-slider-down.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:hover {+    background-image: url("assets/scale-slider-down-hover.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:active {+    background-image: url("assets/scale-slider-down-active.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.fine-tune.horizontal:active {+    background-image: url("assets/scale-slider-down-fine-tune.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.horizontal:insensitive {+    background-image: url("assets/scale-slider-down-insensitive.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical {+    background-image: url("assets/scale-slider-right.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:hover {+    background-image: url("assets/scale-slider-right-hover.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:active {+    background-image: url("assets/scale-slider-right-active.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.fine-tune.vertical:active {+    background-image: url("assets/scale-slider-right-fine-tune.svg");+    background-color: transparent;+}++.scale.scale-has-marks-below.slider.vertical:insensitive {+    background-image: url("assets/scale-slider-right-insensitive.svg");+    background-color: transparent;+}++/********************************+ * Touch text selection handles *+ ********************************/+.cursor-handle.bottom {+    background-image: url("assets/scale-slider-up.svg");+    background-color: transparent;+}++.cursor-handle.top {+    background-image: url("assets/scale-slider-down.svg");+    background-color: transparent;+}
+ app-data/themes/gtk/default/gtk-widgets-backgrounds-and-texts.css view
@@ -0,0 +1,486 @@+/* Button and slider background and text */+.button,+.toolbar .button.raised,+.toolbar .raised .button,+.primary-toolbar .button:focus,+.primary-toolbar .spinbutton .button,+.primary-toolbar GtkComboBox .button,+.primary-toolbar GtkComboBox.combobox-entry .button,+column-header.button,+column-header .button,+.scale.slider,+GtkSwitch.slider,+.scrollbar.slider,+.check,+.check row,+.view.cell.check,+.radio,+.radio row,+.view.cell.radio,+.notebook tab {+    background-image: linear-gradient(to bottom,+                                      @button_top_color,+                                      @button_bottom_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++.scrollbar.slider.vertical {+    background-image: linear-gradient(to bottom,+                                      @button_top_color,+                                      alpha(@button_top_color, 0) 8px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_color,+                                      alpha(@button_bottom_color, 0) 8px+                                      );+    background-color: mix(@button_top_color, @button_bottom_color, 0.5);+}++/* Prelit button and slider background and text */+.button:hover,+.toolbar .button.raised:hover,+.toolbar .raised .button:hover,+.primary-toolbar .button:hover,+.primary-toolbar .spinbutton .button:hover,+.primary-toolbar GtkComboBox .button:hover,+.primary-toolbar GtkComboBox.combobox-entry .button:hover,+column-header.button:hover,+column-header .button:hover,+.scale.slider:hover,+GtkSwitch.slider:hover,+.scrollbar.slider:hover,+.check:hover,+.check row:hover,+.view.cell.check:hover,+.radio:hover,+.radio row:hover,+.view.cell.radio:hover,+.notebook tab:hover {+    background-image: linear-gradient(to bottom,+                                      @button_top_hover_color,+                                      @button_bottom_hover_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++.scrollbar.slider.vertical:hover {+    background-image: linear-gradient(to bottom,+                                      @button_top_hover_color,+                                      alpha(@button_top_hover_color, 0) 8px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_hover_color,+                                      alpha(@button_bottom_hover_color, 0) 8px+                                      );+    background-color: mix(@button_top_hover_color, @button_bottom_hover_color, 0.5);+}++/* Pushed button and through background and text */+.button:active,+.toolbar .button.raised:active,+.toolbar .raised .button:active,+.primary-toolbar .button:active,+.primary-toolbar .spinbutton .button:active,+.primary-toolbar GtkComboBox .button:active,+.primary-toolbar GtkComboBox.combobox-entry .button:active,+column-header.button:active,+column-header .button:active,+column-header .button.dnd,+.trough,+.trough row,+.scale.trough,+GtkSwitch.trough,+.scrollbar.trough {+    background-image: linear-gradient(to bottom,+                                      @button_top_active_color,+                                      @button_bottom_active_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++.scrollbar.trough.vertical {+    background-image: linear-gradient(to bottom,+                                      @button_top_active_color,+                                      alpha(@button_top_active_color, 0) 8px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_active_color,+                                      alpha(@button_bottom_active_color, 0) 8px+                                      );+    background-color: mix(@button_top_active_color, @button_bottom_active_color, 0.5);+}++.trough.vertical {+    background-image: linear-gradient(to bottom,+                                      @button_top_active_color,+                                      alpha(@button_top_active_color, 0) 9px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_active_color,+                                      alpha(@button_bottom_active_color, 0) 9px+                                      );+    background-color: mix(@button_top_active_color, @button_bottom_active_color, 0.5);+}++.scale.trough.vertical {+    background-image: linear-gradient(to bottom,+                                      @button_top_active_color,+                                      alpha(@button_top_active_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_active_color,+                                      alpha(@button_bottom_active_color, 0) 3px+                                      );+    background-color: mix(@button_top_active_color, @button_bottom_active_color, 0.5);+}++/* Prelit pushed button background and text */+.button:active:hover,+.toolbar .button.raised:active:hover,+.toolbar .raised .button:active:hover,+.primary-toolbar .button:active:hover,+.primary-toolbar .spinbutton .button:active:hover,+.primary-toolbar GtkComboBox .button:active:hover,+.primary-toolbar GtkComboBox.combobox-entry .button:active:hover,+column-header.button:active:hover,+column-header .button:active:hover {+    background-image: linear-gradient(to bottom,+                                      @button_top_active_hover_color,+                                      @button_bottom_active_hover_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++/* Colored button background and text */+.button.default,+.toolbar .button.raised.default,+.toolbar .raised .button.default,+.primary-toolbar .button.default:focus {+    background-image: linear-gradient(to bottom,+                                      @colored_button_top_color,+                                      @colored_button_bottom_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++/* Prelit colored button background and text */+.button.default:hover,+.toolbar .button.raised.default:hover,+.toolbar .raised .button.default:hover,+.primary-toolbar .button.default:hover,+.scale.slider.fine-tune:active,+.scrollbar.slider.fine-tune:active {+    background-image: linear-gradient(to bottom, +                                      @colored_button_top_hover_color, +                                      @colored_button_bottom_hover_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++.scrollbar.slider.fine-tune.vertical:active {+    background-image: linear-gradient(to bottom,+                                      @colored_button_top_hover_color,+                                      alpha(@colored_button_top_hover_color, 0) 8px+                                      ),+                      linear-gradient(to top,+                                      @colored_button_bottom_hover_color,+                                      alpha(@colored_button_bottom_hover_color, 0) 8px+                                      );+    background-color: mix(@colored_button_top_hover_color, @colored_button_bottom_hover_color, 0.5);+}++/* Pushed colored button background and text */+.button.default:active,+.toolbar .button.raised.default:active,+.toolbar .raised .button.default:active,+.primary-toolbar .button.default:active {+    background-image: linear-gradient(to bottom, +                                      @colored_button_top_active_color, +                                      @colored_button_bottom_active_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++/* Prelit pushed colored button background and text */+.button.default:active:hover,+.toolbar .button.raised.default:active:hover,+.toolbar .raised .button.default:active:hover,+.primary-toolbar .button.default:active:hover {+    background-image: linear-gradient(to bottom, +                                      @colored_button_top_active_hover_color, +                                      @colored_button_bottom_active_hover_color+                                      );+    background-color: transparent;+    color: @theme_fg_color;+}++/* Suggested action button and progressbar background and text */+.suggested-action.button,+.primary-toolbar .suggested-action.button,+.selection-mode.toolbar GtkToolButton.suggested-action .button,+.progressbar,+.progressbar row,+.scale.progressbar {+    background-image: linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      @suggested_action_button_bottom_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++.progressbar.vertical {+    background-image: linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      alpha(@suggested_action_button_top_color, 0) 9px+                                      ),+                      linear-gradient(to top,+                                      @suggested_action_button_bottom_color,+                                      alpha(@suggested_action_button_bottom_color, 0) 9px+                                      );+    background-color: mix(@suggested_action_button_top_color, @suggested_action_button_bottom_color, 0.5);+}++.scale.progressbar.vertical {+    background-image: linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      alpha(@suggested_action_button_top_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @suggested_action_button_bottom_color,+                                      alpha(@suggested_action_button_bottom_color, 0) 3px+                                      );+    background-color: mix(@suggested_action_button_top_color, @suggested_action_button_bottom_color, 0.5);+}++/* Prelit suggested action button background and text */+.suggested-action.button:hover,+.primary-toolbar .suggested-action.button:hover,+.selection-mode.toolbar GtkToolButton.suggested-action .button:hover {+    background-image: linear-gradient(to bottom, +                                      @suggested_action_button_top_hover_color, +                                      @suggested_action_button_bottom_hover_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++/* Pushed suggested action button and highlit through background and text */+.suggested-action.button:active,+.primary-toolbar .suggested-action.button:active,+.selection-mode.toolbar GtkToolButton.suggested-action .button:active,+.scale.trough.highlight,+GtkSwitch.trough:active {+    background-image: linear-gradient(to bottom, +                                      @suggested_action_button_top_active_color, +                                      @suggested_action_button_bottom_active_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++.scale.trough.highlight.vertical {+    background-image: linear-gradient(to bottom,+                                      @suggested_action_button_top_active_color,+                                      alpha(@suggested_action_button_top_active_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @suggested_action_button_bottom_active_color,+                                      alpha(@suggested_action_button_bottom_active_color, 0) 3px+                                      );+    background-color: mix(@suggested_action_button_top_active_color, @suggested_action_button_bottom_active_color, 0.5);+}++/* Destructive action button background and text */+.destructive-action.button,+.primary-toolbar .destructive-action.button {+    background-image: linear-gradient(to bottom,+                                      @destructive_action_button_top_color,+                                      @destructive_action_button_bottom_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++/* Prelit destructive action button background and text */+.destructive-action.button:hover,+.primary-toolbar .destructive-action.button:hover {+    background-image: linear-gradient(to bottom, +                                      @destructive_action_button_top_hover_color, +                                      @destructive_action_button_bottom_hover_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++/* Pushed destructive action button background and text */+.destructive-action.button:active,+.primary-toolbar .destructive-action.button:active {+    background-image: linear-gradient(to bottom, +                                      @destructive_action_button_top_active_color, +                                      @destructive_action_button_bottom_active_color+                                      );+    background-color: transparent;+    color: @theme_selected_fg_color;+}++/* Insensitive button and slider background and text */+.button:insensitive,+.toolbar .button.raised:insensitive,+.toolbar .raised .button:insensitive,+.primary-toolbar .spinbutton .button:insensitive,+.primary-toolbar GtkComboBox .button:insensitive,+.primary-toolbar GtkComboBox.combobox-entry .button:insensitive,+column-header.button:insensitive,+column-header .button:insensitive,+.scale.slider:insensitive,+GtkSwitch.slider:insensitive,+.scrollbar.slider:insensitive,+.check:insensitive,+.check row:insensitive,+.view.cell.check:insensitive,+.radio:insensitive,+.radio row:insensitive,+.view.cell.radio:insensitive,+.notebook tab:insensitive,+.button.default:insensitive,+.toolbar .button.raised.default:insensitive,+.toolbar .raised .button.default:insensitive,+.suggested-action.button:insensitive,+.primary-toolbar .suggested-action.button:insensitive,+.selection-mode.toolbar GtkToolButton.suggested-action .button:insensitive,+.progressbar:insensitive,+.progressbar row:insensitive,+.scale.progressbar:insensitive,+.destructive-action.button:insensitive,+.primary-toolbar .destructive-action.button:insensitive {+    background-image: none;+    background-color: mix(@theme_bg_color, mix(@button_top_color, @button_bottom_color, 0.5), 0.5);+    color: @insensitive_fg_color;+}++/* Insensitive Pushed button and through background and text */+.button:active:insensitive,+.toolbar .button.raised:active:insensitive,+.toolbar .raised .button:active:insensitive,+.primary-toolbar .button:active:insensitive,+.primary-toolbar .spinbutton .button:active:insensitive,+.primary-toolbar GtkComboBox .button:active:insensitive,+.primary-toolbar GtkComboBox.combobox-entry .button:active:insensitive,+column-header.button:active:insensitive,+column-header .button:active:insensitive,+.trough:insensitive,+.trough row:insensitive,+.scale.trough:insensitive,+GtkSwitch.trough:insensitive,+.scrollbar.trough:insensitive,+.button.default:active:insensitive,+.toolbar .button.raised.default:active:insensitive,+.toolbar .raised .button.default:active:insensitive,+.primary-toolbar .button.default:active:insensitive,+.suggested-action.button:active:insensitive,+.primary-toolbar .suggested-action.button:active:insensitive,+.selection-mode.toolbar GtkToolButton.suggested-action .button:active:insensitive,+.scale.trough.highlight:insensitive,+GtkSwitch.trough:active:insensitive,+.destructive-action.button:active:insensitive,+.primary-toolbar .destructive-action.button:active:insensitive {+    background-image: none;+    background-color: mix(@theme_bg_color, mix(@button_top_active_color, @button_bottom_active_color, 0.5), 0.5);+    color: @insensitive_fg_color;+}++/* Active menu button and tab background and text */+.menubar .menuitem:hover,+.button.menuitem.menubar:active,+GtkMenuButton.button:active,+.toolbar GtkMenuButton.button.raised:active,+.toolbar .raised GtkMenuButton.button:active,+.primary-toolbar GtkMenuButton.button:active,+.selection-mode.toolbar .selection-menu.button:active,+.selection-mode.header-bar .selection-menu.button:active,+GtkComboBox .button:active,+GtkComboBox.combobox-entry .button:active,+.notebook tab:active {+    background-image: none;+    background-color: @theme_base_color;+    color: @theme_text_color;+}++/* Entry background and text */+.entry {+    background-image: linear-gradient(to bottom,+                                      alpha(@theme_tooltip_bg_color, 0.2),+                                      alpha(@theme_tooltip_bg_color, 0) 4px+                                      );+    background-color: @theme_base_color;+    color: @theme_text_color;+}++/* Insensitive entry background and text */+.entry:insensitive {+    background-image: none;+    background-color: @alt_base_color;+    color: @insensitive_fg_color;+}++/* Toolbar and header bar background */+.toolbar,+.header-bar {+    background-image: none;+    background-color: @theme_bg_color;+}++/* Unfocused window toolbar and header bar background */+.toolbar:backdrop,+.header-bar:backdrop {+    background-image: none;+    background-color: @theme_bg_color;+}++/* Selection mode toolbar and header bar background */+.selection-mode.header-bar {+    background-image: linear-gradient(to bottom,+                                      mix(@info_color, @button_top_color, 0.8),+                                      mix(@info_color, @theme_bg_color, 0.8)+                                      );+    background-color: transparent;+}++/* Unfocused window selection mode toolbar and header bar background */+.selection-mode.toolbar,+.selection-mode.toolbar:backdrop,+.selection-mode.header-bar:backdrop {+    background-image: none;+    background-color: mix(@info_color, @theme_bg_color, 0.8);+}++/* Primary and inline toolbars background */+.primary-toolbar .toolbar,+.primary-toolbar.toolbar,+.inline-toolbar.toolbar {+    background-image: linear-gradient(to bottom,+                                      mix(@subdued_color, @theme_tooltip_bg_color, 0.2),+                                      mix(@subdued_color, @theme_bg_color, 0.2)+                                      );+    background-color: transparent;+}++/* Unfocused window primary toolbar and insensitive inline toolbar background */+.primary-toolbar .toolbar:backdrop,+.primary-toolbar.toolbar:backdrop,+.inline-toolbar.toolbar:insensitive,+.primary-toolbar .toolbar.vertical,+.primary-toolbar.toolbar.vertical,+.inline-toolbar.toolbar.vertical {+    background-image: none;+    background-color: @subdued_color;+}
+ app-data/themes/gtk/default/gtk-widgets-borders.css view
@@ -0,0 +1,215 @@+/* Generic element borders */+.entry,+.button,+.toolbar .button.raised,+.toolbar .raised .button,+.primary-toolbar .button:hover,+.primary-toolbar .button:active,+.primary-toolbar .spinbutton .button,+.primary-toolbar GtkComboBox .button,+.primary-toolbar GtkComboBox.combobox-entry .button,+column-header.button,+column-header .button,+.scale.slider,+GtkSwitch.slider,+.trough,+.trough row,+.scale.trough,+GtkSwitch.trough,+.notebook tab {+    border-radius: 4px;+    border-width: 1px;+    border-style: solid;+    border-color: @alt_border_color;+}++.scrollbar.slider,+.scrollbar.trough,+.check,+.check row,+.view.cell.check,+.radio,+.radio row,+.view.cell.radio {+    box-shadow: inset 0 0 0 1px @alt_border_color;+}++/* Colored element borders */+.button.default,+.toolbar .button.raised.default,+.toolbar .raised .button.default,+.primary-toolbar .button.default:hover,+.primary-toolbar .button.default:active {+    border-radius: 4px;+    border-width: 1px;+    border-style: solid;+    border-color: @colored_border_color;+}++.check:inconsistent,+.check row:inconsistent,+.view.cell.check:inconsistent,+.radio:inconsistent,+.radio row:inconsistent,+.view.cell.radio:inconsistent {+    box-shadow: inset 0 0 0 1px @colored_border_color;+}++/* Suggested action buttons borders */+.suggested-action.button,+.primary-toolbar .suggested-action.button,+.selection-mode.toolbar GtkToolButton.suggested-action .button,+.progressbar,+.progressbar row,+.scale.progressbar,+.scale.trough.highlight,+GtkSwitch.trough:active {+    border-radius: 4px;+    border-width: 1px;+    border-style: solid;+    border-color: @suggested_action_border_color;+}++.check:active,+.check row:active,+.view.cell.check:active,+.radio:active,+.radio row:active,+.view.cell.radio:active {+    box-shadow: inset 0 0 0 1px @suggested_action_border_color;+}++/* Destructive action buttons borders */+.destructive-action.button,+.primary-toolbar .destructive-action.button {+    border-radius: 4px;+    border-width: 1px;+    border-style: solid;+    border-color: @destructive_action_border_color;+}++/* Focused element borders */+.entry:focus,+.button:focus,+.toolbar .button.raised:focus,+.toolbar .raised .button:focus,+.primary-toolbar .button:focus,+.primary-toolbar .spinbutton .button:focus,+.primary-toolbar GtkComboBox .button:focus,+.primary-toolbar GtkComboBox.combobox-entry .button:focus,+column-header.button:focus,+column-header .button:focus,+.scale.slider:active,+/* GtkSwitch.slider:active, */+.scale.trough:focus,+GtkSwitch.trough:focus,+.notebook tab:active:focus {+    border-color: @focused_border_color;+    box-shadow: inset 0 0 0 1px alpha(@focused_border_color, 0.2);+}++.scrollbar.slider:active,+.check:focus,+.check row:focus,+.view.cell.check:focus,+.radio:focus,+.radio row:focus,+.view.cell.radio:focus {+    box-shadow: inset 0 0 0 2px alpha(@focused_border_color, 0.2),+                inset 0 0 0 1px @focused_border_color;+}++/* Focused colored element borders */+.button.default:focus,+.toolbar .button.raised.default:focus,+.toolbar .raised .button.default:focus,+.primary-toolbar .button.default:focus,+.scale.slider.fine-tune:active {+    border-color: @focused_border_color;+    box-shadow: inset 0 0 0 1px alpha(@focused_border_color, 0.2);+}++.scrollbar.slider.fine-tune:active,+.check:inconsistent:focus,+.check row:inconsistent:focus,+.view.cell.check:inconsistent:focus,+.radio:inconsistent:focus,+.radio row:inconsistent:focus,+.view.cell.radio:inconsistent:focus {+    box-shadow: inset 0 0 0 2px alpha(@focused_border_color, 0.2),+                inset 0 0 0 1px @focused_border_color;+}++/* Focused suggested action buttons borders */+.suggested-action.button:focus,+.primary-toolbar .suggested-action.button:focus,+.selection-mode.toolbar GtkToolButton.suggested-action .button:focus,+.scale.progressbar:focus,+.scale.trough.highlight:focus,+GtkSwitch.trough:active:focus {+    border-color: @suggested_action_border_color;+    box-shadow: inset 0 0 0 1px alpha(@theme_selected_fg_color, 0.6);+}++.check:active:focus,+.check row:active:focus,+.view.cell.check:active:focus,+.radio:active:focus,+.radio row:active:focus,+.view.cell.radio:active:focus {+    box-shadow: inset 0 0 0 2px alpha(@theme_selected_fg_color, 0.6),+                inset 0 0 0 1px @suggested_action_border_color;+}++/* Focused destructive action buttons borders */+.destructive-action.button:focus,+.primary-toolbar .destructive-action.button:focus {+    border-color: @destructive_action_border_color;+    box-shadow: inset 0 0 0 1px alpha(@theme_selected_fg_color, 0.6);+}++/* Insensitive element borders */+.entry:insensitive,+.button:insensitive,+.toolbar .button.raised:insensitive,+.toolbar .raised .button:insensitive,+.primary-toolbar .button:active:insensitive,+.primary-toolbar .spinbutton .button:insensitive,+.primary-toolbar GtkComboBox .button:insensitive,+.primary-toolbar GtkComboBox.combobox-entry .button:insensitive,+column-header.button:insensitive,+column-header .button:insensitive,+.scale.slider:insensitive,+GtkSwitch.slider:insensitive,+.trough:insensitive,+.trough row:insensitive,+.scale.trough:insensitive,+GtkSwitch.trough:insensitive,+.notebook tab:insensitive,+.button.default:insensitive,+.toolbar .button.raised.default:insensitive,+.toolbar .raised .button.default:insensitive,+.primary-toolbar .button.default:active:insensitive,+.suggested-action.button:insensitive,+.primary-toolbar .suggested-action.button:insensitive,+.selection-mode.toolbar GtkToolButton.suggested-action .button:insensitive,+.progressbar:insensitive,+.progressbar row:insensitive,+.scale.progressbar:insensitive,+.scale.trough.highlight:insensitive,+GtkSwitch.trough:active:insensitive,+.destructive-action.button:insensitive,+.primary-toolbar .destructive-action.button:insensitive {+    border-color: @insensitive_border_color;+}++.scrollbar.slider:insensitive,+.scrollbar.trough:insensitive,+.check:insensitive,+.check row:insensitive,+.view.cell.check:insensitive,+.radio:insensitive,+.radio row:insensitive,+.view.cell.radio:insensitive {+    box-shadow: inset 0 0 0 1px @insensitive_border_color;+}
+ app-data/themes/gtk/default/gtk-widgets.css view
@@ -0,0 +1,2178 @@+* {+    padding: 0;+    background-clip: border-box;++    -GtkWidget-link-color: @link_color;+    -GtkWidget-visited-link-color: @link_color;+    -GtkIMHtml-hyperlink-color: @link_color;+    -GtkHTML-link-color: @link_color;++    -GtkTextView-error-underline-color: @error_color;++    -GtkPaned-handle-size: 4;++    -GtkWindow-resize-grip-width: 0;+    -GtkWindow-resize-grip-height: 0;++    -GtkCheckButton-indicator-size: 16;+    -GtkCheckMenuItem-indicator-size: 16;++    -GtkToolItemGroup-expander-size: 12;+    -GtkExpander-expander-size: 12;+    -GtkTreeView-expander-size: 12;++    /* The size for scrollbars. The slider is 2px smaller, but we keep it+     * up so that the whole area is sensitive to button presses for the+     * slider. The stepper button is larger in both directions, the slider+     * only in the width+     */+    -GtkScrolledWindow-scrollbar-spacing: 0;+    -GtkScrolledWindow-scrollbars-within-bevel: 1;++    -GtkToolButton-icon-spacing: 4;++    -GtkTreeView-horizontal-separator: 4;++    -GtkMenu-horizontal-padding: 0;+    -GtkMenu-vertical-padding: 0;++    -WnckTasklist-fade-overlay-rect: 0;++    -GtkWidget-focus-padding: 0;+    -GtkWidget-focus-line-width: 0;++    -GtkWidget-cursor-color: white;++    outline-offset: -3px;+    /* outline-radius: 4px; unsupported by older gtk */+    outline-style: dashed;+    outline-color: @internal_element_color;+}++/***************+ * Base States *+ ***************/+.background {+    background-color: @theme_bg_color;+    color: @theme_fg_color;+}++/* FIXME: why do we still need this? */+GtkClutterOffscreen {+    background-color: @theme_bg_color;+    color: @theme_fg_color;+}++*:insensitive {+    border-color: @insensitive_border_color;+    color: @insensitive_fg_color;+}++*:selected {+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++*:insensitive:selected {+    color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.5);+}++.gtkstyle-fallback {+    background-color: @theme_bg_color;+    color: @theme_fg_color;+}++.gtkstyle-fallback:hover {+    background-color: shade(@theme_bg_color, 1.1);+    color: @theme_fg_color;+}++.gtkstyle-fallback:active {+    background-color: shade(@theme_bg_color, 0.9);+    color: @theme_fg_color;+}++.gtkstyle-fallback:insensitive {+    background-color: @theme_bg_color;+    color: @insensitive_fg_color;+}++.gtkstyle-fallback:selected {+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++GtkImage,+GtkImage:insensitive,+GtkLabel,+GtkLabel:insensitive {+    background-color: transparent;+}++/*****************+ * Miscellaneous *+ *****************/+@keyframes spinner {+    0.00% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)); }++    12.5% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)); }++    25.0% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)); }++    37.5% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)); }++    50.0% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)); }++    62.5% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)); }++    75.0% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)); }++    87.5% { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)); }++    100%  { background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                              -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)); }+}++.spinner {+    background-color: transparent;+    background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent));+    background-position: 14% 14%, 0% 50%, 14% 86%, 50% 100%, 86% 86%, 100% 50%, 86% 14%, 50% 0%;+    background-size: 20% 20%;+    background-repeat: no-repeat;+}++.spinner:active {+    background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.875)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.750)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.625)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.500)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.375)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.250)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(alpha(currentColor, 0.125)), to(transparent)),+                      -gtk-gradient(radial, center center, 0, center center, 0.5, to(currentColor), to(transparent));+    animation: spinner 1s infinite linear;+}++.button .spinner:active {+    color: @theme_fg_color;+}++GtkStatusbar {+    -GtkStatusbar-shadow-type: none;++    padding: 3px;+    color: @theme_fg_color;+}++.rubberband,+.view.rubberband,+.content-view.view.rubberband {+    border-width: 1px;+    border-style: solid;+    border-color: alpha (@theme_selected_bg_color, 0.8);+    background-color: alpha (@theme_selected_bg_color, 0.2);+}++.dnd,+GtkTreeView.dnd {+    border-width: 2px;+    border-style: solid;+    border-color: @internal_element_color;+}++.separator,+GtkTreeView.separator,+GtkTreeView.view.separator {+    background-color: transparent;+    color: @insensitive_border_color;+}++.pane-separator {+    background-color: transparent;+    color: @internal_element_color;+}++.pane-separator:hover {+    color: @theme_fg_color;+}++.pane-separator:active {+    color: @theme_selected_bg_color;+}++.pane-separator:insensitive {+    color: @insensitive_internal_element_color;+}++.pane-separator:selected {+    color: @selected_internal_element_color;+}++.pane-separator:selected:hover {+    color: @theme_selected_fg_color;+}++.notebook .pane-separator {+    background-color: @theme_base_color;+}++/* Calendars */+GtkCalendar {+    padding: 2px;+}++GtkCalendar.view {+    padding: 2px;+}++GtkCalendar.header {+    border-radius: 0;+    border-style: none;+    background-color: @theme_bg_color;+}++GtkCalendar.button,+GtkCalendar.button:insensitive {+    background-image: none;+    background-color: transparent;+}++.highlight,+GtkCalendar.highlight {+    padding: 0;+    border-radius: 0;+    border-style: none;+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++/*******************+ * Symbolic images *+ *******************/+.image,+.image:focus {+    color: @internal_element_color;+}++.image:hover,+.image:focus:hover {+    color: @theme_fg_color;+}++.image:active,+.image:focus:active {+    color: @theme_selected_bg_color;+}++.image:insensitive {+    color: @insensitive_internal_element_color;+}++.image:selected {+    color: @selected_internal_element_color;+}++.image:selected:hover {+    color: @theme_selected_fg_color;+}++.image:insensitive:selected {+    color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.7);+}++.view.image,+.view.image:hover {+    color: @theme_fg_color;+}++.view.image:selected,+.view.image:selected:hover {+    color: @theme_selected_fg_color;+}++.view.image:insensitive:selected {+    color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.5);+}++/**************+ * Dim labels *+ **************/+.dim-label,+.view.dim-label {+    color: @internal_element_color;+}++.dim-label:selected,+.view.dim-label:selected {+    color: @selected_internal_element_color;+}++/**********+ * Frames *+ **********/+.frame,+GtkScrolledWindow.frame {+    padding: 0;+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+}++.frame:insensitive,+GtkScrolledWindow.frame:insensitive {+    border-color: @insensitive_border_color;+}++/* avoid double borders when a viewport is + * packed into a GtkScrolledWindow */+GtkScrolledWindow GtkViewport.frame {+    border-style: none;+}++/**************+ * GtkInfoBar *+ **************/+GtkInfoBar {+    border-style: none;+    color: @theme_fg_color;+}++.info {+    border-color: mix(shade(@info_color, 0.5), @border_color, 0.5);+    background-color: mix(@info_color, @theme_bg_color, 0.5);+}++.warning {+    border-color: mix(shade(@warning_color, 0.5), @border_color, 0.5);+    background-color: mix(@warning_color, @theme_bg_color, 0.5);+}++.question {+    border-color: mix(shade(@question_color, 0.5), @border_color, 0.5);+    background-color: mix(@question_color, @theme_bg_color, 0.5);+}++.error {+    border-color: mix(shade(@error_color, 0.5), @border_color, 0.5);+    background-color: mix(@error_color, @theme_bg_color, 0.5);+}++.other {+    border-color: mix(shade(@other_color, 0.5), @border_color, 0.5);+    background-color: mix(@other_color, @theme_bg_color, 0.5);+}++/*****************+ * Color Chooser *+ *****************/+GtkColorSwatch {+    border-radius: 0;+    box-shadow: inset 0 0 0 1px alpha(black, 0.5), inset 0 0 0 1px alpha(@alt_border_color, 0.5);+    background-color: transparent;+}++GtkColorSwatch.top {+    border-top-left-radius: 4px;+    border-top-right-radius: 4px;+}++GtkColorSwatch.bottom {+    border-bottom-right-radius: 4px;+    border-bottom-left-radius: 4px;+}++GtkColorSwatch.left,+GtkColorSwatch:first-child {+    border-top-left-radius: 4px;+    border-bottom-left-radius: 4px;+}++GtkColorSwatch.right,+GtkColorSwatch:last-child {+    border-top-right-radius: 4px;+    border-bottom-right-radius: 4px;+}++GtkColorSwatch:only-child {+    border-radius: 4px;+}++GtkColorEditor GtkColorSwatch {+    border-radius: 4px;+}++GtkColorSwatch.color-light:hover {+    background-image: -gtk-gradient(radial, 0.5 1.5, 0, 0.5 0.5, 1,+                                    color-stop (0.0, alpha(black, 0.5)),+                                    color-stop (0.5, alpha(black, 0))+                                    );+    background-color: transparent;+}++GtkColorSwatch.color-dark:hover {+    background-image: -gtk-gradient(radial, 0.5 1.5, 0, 0.5 0.5, 1,+                                    color-stop (0.0, alpha(white, 1)),+                                    color-stop (0.5, alpha(white, 0))+                                    );+    background-color: transparent;+}++GtkColorSwatch.color-light:selected:hover,+GtkColorSwatch.color-dark:selected:hover {+    background-image: none;+}++.color-active-badge,+.color-active-badge:selected {+    border-width: 2px;+    border-style: solid;+    background-color: transparent;+}++.color-active-badge.color-light {+    border-color: black;+    color: black;+}++.color-active-badge.color-dark {+    border-color: white;+    color: white;+}++GtkColorChooserWidget #add-color-button {+    background-image: linear-gradient(to bottom,+                                      alpha(@theme_base_color, 0.25),+                                      alpha(@theme_base_color, 0.25)+                                      ),+                      linear-gradient(to bottom, alpha(lime, 0.75), alpha(lime, 0)),+                      linear-gradient(to left, red, blue);+    background-color: transparent;+    color: alpha(white, 0.75);+}++GtkColorChooserWidget #add-color-button:hover {+    background-image: -gtk-gradient(radial, 0.5 1.5, 0, 0.5 0.5, 1,+                                    color-stop(0.0, alpha(white, 1)),+                                    color-stop(0.5, alpha(white, 0))+                                    ),+                      linear-gradient(to bottom,+                                      alpha(@theme_base_color, 0.25),+                                      alpha(@theme_base_color, 0.25)+                                      ),+                      linear-gradient(to bottom, alpha(lime, 0.75), alpha(lime, 0)),+                      linear-gradient(to left, red, blue);+    background-color: transparent;+    color: alpha(white, 0.75);+}++/****************+ * Progress bar *+ ****************/+GtkProgressBar {+    -GtkProgressBar-min-horizontal-bar-height: 20;+    -GtkProgressBar-min-vertical-bar-width: 20;++    padding: 0; /* FIXME: this should really be a margin... */+}++.progressbar,+.progressbar row,+.trough,+.trough row {+    border-radius: 100px;+}++/* for progressbars in cell renderers */+.trough row {+    padding: 0;+}++.trough row:selected {+    color: @theme_fg_color;+}++/* level bars as used for password quality or remaining power */+GtkLevelBar {+    -GtkLevelBar-min-block-width: 32;+    -GtkLevelBar-min-block-height: 8;+}++GtkLevelBar.vertical {+    -GtkLevelBar-min-block-width: 8;+    -GtkLevelBar-min-block-height: 32;+}++.level-bar.trough {+    padding: 0;+    border-width: 1px 0;+    border-color: transparent;+    background-image: none;+    background-color: transparent;+}++.level-bar.indicator-continuous.fill-block {+    padding: 0;+}++.level-bar.indicator-discrete.fill-block.horizontal {+    margin: 0;+    border-radius: 0;+    border-left-width: 0;+}++.level-bar.indicator-discrete.fill-block.vertical {+    margin: 0;+    border-radius: 0;+    border-bottom-width: 0;+    border-left-width: 1px;+}++/* discrete indicator border rounding,+   uncomment when :nth-child will be working+   on the widget++.level-bar.indicator-discrete.fill-block.horizontal:first-child {+    border-radius: 100px 0 0 100px;+    border-left-width: 1px;+}++.level-bar.indicator-discrete.fill-block.horizontal:last-child {+    border-radius: 0 100px 100px 0;+}++.level-bar.indicator-discrete.fill-block.horizontal:only-child {+    border-radius: 100px;+    border-left-width: 1px;+}++.level-bar.indicator-discrete.fill-block.vertical:first-child {+    border-radius: 100px 100px 0 0;+}++.level-bar.indicator-discrete.fill-block.vertical:last-child {+    border-radius: 0 0 100px 100px;+    border-bottom-width: 1px;+}++.level-bar.indicator-discrete.fill-block.vertical:only-child {+    border-radius: 100px;+    border-bottom-width: 1px;+}++*/++.level-bar.fill-block {+    border-radius: 100px;+    border-width: 1px;+    border-style: solid;+    border-color: mix(@alt_border_color, shade(@info_color, 0.2), 0.2);+    background-image: linear-gradient(to bottom,+                                      mix(@theme_bg_color, shade(@info_color, 1.1), 0.8),+                                      alpha(mix(@theme_bg_color, shade(@info_color, 1.1), 0.8), 0) 3px+                                      ),+                      linear-gradient(to top,+                                      mix(@theme_bg_color, shade(@info_color, 0.9), 0.8),+                                      alpha(mix(@theme_bg_color, shade(@info_color, 0.9), 0.8), 0) 3px+                                      );+    background-color: mix(mix(@theme_bg_color, shade(@info_color, 1.1), 0.8), mix(@theme_bg_color, shade(@info_color, 0.9), 0.8), 0.5);+}++.level-bar.fill-block.level-high {+    border-color: @suggested_action_border_color;+    background-image: linear-gradient(to bottom,+                                      @suggested_action_button_top_color,+                                      alpha(@suggested_action_button_top_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @suggested_action_button_bottom_color,+                                      alpha(@suggested_action_button_bottom_color, 0) 3px+                                      );+    background-color: mix(@suggested_action_button_top_color, @suggested_action_button_bottom_color, 0.5);+}++.level-bar.fill-block.level-low {+    border-color: @destructive_action_border_color;+    background-image: linear-gradient(to bottom,+                                      @destructive_action_button_top_color,+                                      alpha(@destructive_action_button_top_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @destructive_action_button_bottom_color,+                                      alpha(@destructive_action_button_bottom_color, 0) 3px+                                      );+    background-color: mix(@destructive_action_button_top_color, @destructive_action_button_bottom_color, 0.5);+}++.level-bar.fill-block.empty-fill-block {+    border-color: @alt_border_color;+    background-image: linear-gradient(to bottom,+                                      @button_top_active_color,+                                      alpha(@button_top_active_color, 0) 3px+                                      ),+                      linear-gradient(to top,+                                      @button_bottom_active_color,+                                      alpha(@button_bottom_active_color, 0) 3px+                                      );+    background-color: mix(@button_top_active_color, @button_bottom_active_color, 0.5);+}++/************+ * GtkScale *+ ************/+.scale {+    -GtkScale-slider-length: 24;+    -GtkRange-slider-width: 24;+    -GtkRange-trough-border: 0;+}++.scale.slider {+    border-radius: 100px;+}++.scale.scale-has-marks-above.slider.horizontal,+.scale.scale-has-marks-above.slider.vertical,+.scale.scale-has-marks-below.slider.horizontal,+.scale.scale-has-marks-below.slider.vertical {+    border-style: none;+}++/* +.scale.scale-has-marks-above.slider.horizontal {+    transform: rotate(45deg);+    border-top-left-radius: 0;+}++.scale.scale-has-marks-above.slider.vertical {+    transform: rotate(45deg);+    border-bottom-left-radius: 0;+}++.scale.scale-has-marks-below.slider.horizontal {+    transform: rotate(45deg);+    border-bottom-right-radius: 0;+}++.scale.scale-has-marks-below.slider.vertical {+    transform: rotate(45deg);+    border-top-right-radius: 0;+}+ */++.scale.trough {+    margin: 8px 0;+}++.scale.trough.vertical {+    margin: 0 8px;+}++.scale.trough,+.scale.trough.vertical,+.scale.trough.highlight,+.scale.trough.highlight.vertical,+.scale.progressbar,+.scale.progressbar.vertical {+    border-radius: 100px;+}++.scale.mark.separator {+    color: @insensitive_border_color;+}++/**************+ * Scrollbars *+ **************/+.scrollbar {+    -GtkScrollbar-has-backward-stepper: false;+    -GtkScrollbar-has-forward-stepper: false;+    -GtkRange-slider-width: 12px;+    -GtkScrollbar-min-slider-length: 12px;+    -GtkRange-trough-border: 0;+    -GtkRange-stepper-spacing: 0;+    -GtkRange-trough-under-steppers: 1;++    background-clip: padding-box;+}++.scrollbar.slider,+.scrollbar.trough {+    border-radius: 100px;+    border-width: 2px;+    border-style: solid;+    border-color: transparent;+}++/* the small square between scrollbars!!! */+.scrollbars-junction {+}++.scrollbar.button {+    border-style: none;+    background-image: none;+    background-color: transparent;+}++.scrollbar.button {+    color: @internal_element_color;+}++.scrollbar.button:hover {+    color: @theme_fg_color;+}++.scrollbar.button:active {+    color: @theme_selected_bg_color;+}++.scrollbar.button:insensitive {+    color: @insensitive_internal_element_color;+}++/*************+ * GtkSwitch *+ *************/+GtkSwitch {+    -GtkSwitch-slider-height: 24;+}++GtkSwitch.slider {+    padding: 4px;+    border-radius: 100px;+}++/****************+ * Text Entries *+ ****************/+.entry {+    padding: 4px;+}++.entry.progressbar,+.entry.progressbar.pulse {+    margin: 3px;+    border-radius: 0;+    border-style: none;+    box-shadow: none;+    background-image: linear-gradient(to top,+                                      @theme_selected_bg_color 2px,+                                      transparent 2px+                                      );+    background-color: transparent;+}++.entry:selected {+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++/* needed for webkit/GtkStyle/Evolution compatibility */+GtkHTML:active,+.entry:active {+    background-color: @subdued_color;+    color: @theme_fg_color;+}++.cursor-handle.bottom,+.cursor-handle.top {+    border-style: none;+    /* background-image in assets */+}++/***********+ * Buttons *+ ***********/+.button {+    -GtkButton-image-spacing: 4;+    -GtkButton-interior-focus: true;+    -GtkButton-default-border: 0;+    -GtkButton-inner-border: 0;+}++.button,+.button.menuitem.menubar,+GtkColorButton.button {+    padding: 4px;+}++.button.text-button {+    padding: 4px 8px;+}++.button.image-button {+    padding: 7px;+}++.button .separator {+    color: @insensitive_border_color;+}++GtkLinkButton.button {+}++/* Remove borders and backgrounds from primary toolbar buttons */+.primary-toolbar .button,+.primary-toolbar .button:insensitive {+    border-color: transparent;+    background-image: none;+    background-color: transparent;+}++/* linked entries/buttons */++/* Middle button */+.linked .entry,+.linked .button,+.toolbar .button.raised.linked,+.toolbar .raised.linked .button,+.primary-toolbar .linked .button,+.inline-toolbar.toolbar .button,+.inline-toolbar.toolbar GtkToolButton .button,+.osd.toolbar .button {+    border-radius: 0;+    border-left-width: 0;+}++/* Leftmost button */+.linked .entry:first-child,+.linked .button:first-child,+.toolbar .button.raised.linked:first-child,+.toolbar .raised.linked .button:first-child,+.primary-toolbar .linked .button:first-child,+.inline-toolbar.toolbar .button:first-child,+.inline-toolbar.toolbar GtkToolButton:first-child .button,+.osd.toolbar .button:first-child {+    border-radius: 4px 0 0 4px;+    border-left-width: 1px;+}++/* Rightmost button */+.linked .entry:last-child,+.linked .button:last-child,+.toolbar .button.raised.linked:last-child,+.toolbar .raised.linked .button:last-child,+.primary-toolbar .linked .button:last-child,+.inline-toolbar.toolbar .button:last-child,+.inline-toolbar.toolbar GtkToolButton:last-child .button,+.osd.toolbar .button:last-child {+    border-radius: 0 4px 4px 0;+}++/* Single button */+.linked .entry:only-child,+.linked .button:only-child,+.toolbar .button.raised.linked:only-child,+.toolbar .raised.linked .button:only-child,+.primary-toolbar .linked .button:only-child,+.inline-toolbar.toolbar .button:only-child,+.inline-toolbar.toolbar GtkToolButton:only-child .button,+.osd.toolbar .button:only-child {+    border-radius: 4px;+    border-left-width: 1px;+}++/* Middle button (vertical) */+.linked.vertical .entry,+.linked.vertical .button,+.inline-toolbar.toolbar.vertical .button,+.inline-toolbar.toolbar.vertical GtkToolButton .button {+    border-radius: 0;+    border-bottom-width: 0;+    border-left-width: 1px;+}++/* Topmost button (vertical) */+.linked.vertical .entry:first-child,+.linked.vertical .button:first-child,+.inline-toolbar.toolbar.vertical .button:first-child,+.inline-toolbar.toolbar.vertical GtkToolButton:first-child .button {+    border-radius: 4px 4px 0 0;+}++/* Bottommost button (vertical) */+.linked.vertical .entry:last-child,+.linked.vertical .button:last-child,+.inline-toolbar.toolbar.vertical .button:last-child,+.inline-toolbar.toolbar.vertical GtkToolButton:last-child .button {+    border-radius: 0 0 4px 4px;+    border-bottom-width: 1px;+}++/* Single button (vertical) */+.linked.vertical .entry:only-child,+.linked.vertical .button:only-child,+.inline-toolbar.toolbar.vertical .button:only-child,+.inline-toolbar.toolbar.vertical GtkToolButton:only-child .button {+    border-radius: 4px;+    border-bottom-width: 1px;+}++/* Special-case GtkMenuToolButton, since it's a GtkToolButton, but it+ * has a box inside to pack the button and the actual menu */+.inline-toolbar.toolbar GtkMenuToolButton .button:first-child,+.inline-toolbar.toolbar GtkMenuToolButton .button:last-child {+    border-radius: 0;+    border-left-width: 0;+}++.inline-toolbar.toolbar GtkMenuToolButton:first-child .button:first-child {+    border-radius: 4px 0 0 4px;+    border-left-width: 1px;+}++.inline-toolbar.toolbar GtkMenuToolButton:last-child .button:last-child {+    border-radius: 0 4px 4px 0;+}++.osd.toolbar GtkToolButton .button,+.osd.toolbar GtkToolButton:first-child .button,+.osd.toolbar GtkToolButton:last-child .button,+.osd.toolbar GtkToolButton:only-child .button {+    border-radius: 4px;+    border-width: 1px;+}++/****************+ * Radiobuttons *+ ****************/+.check {+    border-radius: 0;+}++.radio {+    border-radius: 100px;+}++.check:insensitive,+.radio:insensitive {+    background-image: linear-gradient(to bottom, transparent, transparent);+}++GtkCheckButton:hover,+GtkCheckButton:active:hover,+GtkCheckButton:selected {+    background-color: transparent;+}++/*****************+ * GtkSpinButton *+ *****************/+.spinbutton .button {+    padding-right: 6px;+    padding-left: 7px;+    border-radius: 0;+    border-width: 0 0 0 1px;+}++.spinbutton .button:first-child {+    border-radius: 4px 0 0 4px;+}++.spinbutton .button:last-child {+    border-radius: 0 4px 4px 0;+}++.spinbutton .button:dir(rtl) {+    border-width: 0 1px 0 0;+}++.spinbutton.vertical.entry {+    border-radius: 0;+}++.spinbutton.vertical .button {+    padding: 5px;+}++.spinbutton.vertical .button:first-child {+    border-radius: 4px 4px 0 0;+    border-width: 1px 1px 0 1px;+}++.spinbutton.vertical .button:last-child {+    border-radius: 0 0 4px 4px;+    border-width: 0 1px 1px 1px;+}++.spinbutton.vertical .button,+/* :active:active to override the dark overriden style for+   normal spinbutton buttons, yeah we lack !important */+.spinbutton.vertical .button:active:active {+}++/* :insensitive:insensitive to override the dark overriden style for+   normal spinbutton buttons, yeah we lack !important */+.spinbutton.vertical .button:insensitive:insensitive {+}++/**************+ * ComboBoxes *+ **************/+GtkComboBox {+    -GtkComboBox-arrow-scaling: 0.5;+    -GtkComboBox-shadow-type: none;++    padding: 0;+}++GtkComboBox .separator {+    /* always disable separators */+    -GtkWidget-wide-separators: true;+    -GtkWidget-horizontal-separator: 0;+    -GtkWidget-vertical-separator: 0;+}++GtkComboBox .button {+    padding: 2px;+}++GtkComboBox.combobox-entry .button {+    padding: 7px;+}++GtkComboBox.combobox-entry .entry:first-child,+GtkComboBox.combobox-entry .button:first-child {+    border-radius: 4px 0 0 4px;+}++GtkComboBox.combobox-entry .entry:last-child,+GtkComboBox.combobox-entry .button:last-child {+    border-radius: 0 4px 4px 0;+    border-left-width: 0;+}++/***************+ * Menu Button *+ ***************/+.selection-mode.toolbar .selection-menu.button,+.selection-mode.header-bar .selection-menu.button {+    border-color: transparent;+    background-image: none;+    background-color: transparent;+}++.selection-mode.toolbar .selection-menu.button:hover,+.selection-mode.header-bar .selection-menu.button:hover {+    border-color: @alt_border_color;+    background-image: linear-gradient(to bottom,+                                      @button_top_hover_color,+                                      @button_bottom_hover_color+                                      );+    background-color: transparent;+}++GtkComboBox.combobox-entry .button:active,+.linked GtkMenuButton.button:active,+.toolbar GtkMenuButton.button.raised.linked:active,+.toolbar .raised.linked GtkMenuButton.button:active,+.primary-toolbar .linked GtkMenuButton.button:active {+    border-radius: 0;+    border-left-width: 0;+    border-bottom-color: transparent;+}++GtkComboBox.combobox-entry .button:active:first-child,+.linked GtkMenuButton.button:active:first-child,+.toolbar GtkMenuButton.button.raised.linked:active:first-child,+.toolbar .raised.linked GtkMenuButton.button:active:first-child,+.primary-toolbar .linked GtkMenuButton.button:active:first-child {+    border-radius: 4px 0 0 0;+    border-left-width: 1px;+}++GtkComboBox.combobox-entry .button:active:last-child,+.linked GtkMenuButton.button:active:last-child,+.toolbar GtkMenuButton.button.raised.linked:active:last-child,+.toolbar .raised.linked GtkMenuButton.button:active:last-child,+.primary-toolbar .linked GtkMenuButton.button:active:last-child {+    border-radius: 0 4px 0 0;+}++.menubar .menuitem:hover, /* remove the image from the prelight areas */+.button.menuitem.menubar:active,+GtkMenuButton.button:active,+.toolbar GtkMenuButton.button.raised:active,+.toolbar .raised GtkMenuButton.button:active,+.primary-toolbar GtkMenuButton.button:active,+.selection-mode.toolbar .selection-menu.button:active,+.selection-mode.header-bar .selection-menu.button:active,+.linked GtkMenuButton.button:active:only-child,+.toolbar GtkMenuButton.button.raised.linked:active:only-child,+.toolbar .raised.linked GtkMenuButton.button:active:only-child,+.primary-toolbar .linked GtkMenuButton.button:active:only-child {+    border-radius: 4px 4px 0 0;+    border-width: 1px;+    border-style: solid;+    border-color: @alt_border_color;+    border-bottom-color: transparent;+}++/*********+ * Menus *+ *********/+.context-menu {+    font: initial;+}++.menu {+    padding: 1px;+    border-width: 1px;+    border-style: solid;+    border-color: @alt_border_color;+    background-color: @theme_base_color;+    color: @theme_text_color;+}++.menubar .menu,+.button.menubar .menu,+GtkMenuButton .menu,+.selection-mode.toolbar .selection-menu .menu,+.selection-mode.header-bar .selection-menu .menu,+GtkComboBox.combobox-entry .menu {+    padding-top: 0;+    border-top-width: 0;+}++.menu.button,+.primary-toolbar .menu.button {+    border-style: none;+    background-image: none;+    background-color: @theme_base_color;+    color: @internal_element_color;+}++.menu.button:hover,+.primary-toolbar .menu.button:hover {+    border-style: none;+    background-image: none;+    background-color: @theme_base_color;+    color: @theme_fg_color;+}++.menu.button:insensitive,+.primary-toolbar .menu.button:insensitive {+    border-style: none;+    background-image: none;+    background-color: @theme_base_color;+    color: @insensitive_internal_element_color;+}++.menu .menuitem,+.menubar .menu .menuitem,+.button .menu .menuitem {+    -GtkMenuItem-arrow-scaling: 0.5;++    padding: 3px 4px;+}++.menu .menuitem:hover {+    border-radius: 0;+    border-style: none;+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++.menu .menuitem:insensitive {+    background-color: @theme_base_color;+}++.menu .menuitem *:insensitive {+    color: @insensitive_fg_color;+}++.menuitem .accelerator {+    color: @internal_element_color;+}++.menuitem .accelerator:hover {+    color: @selected_internal_element_color;+}++.menuitem .accelerator:insensitive {+    color: @insensitive_internal_element_color;+}++.menuitem.arrow {+    color: @theme_text_color;+}++.menuitem.arrow:hover {+    color: @theme_selected_fg_color;+}++.menuitem.arrow:insensitive {+    color: @insensitive_fg_color;+}++.menuitem.separator {+    -GtkMenuItem-horizontal-padding: 0;++    color: @insensitive_border_color;+}++.menuitem.check,+.menuitem.check:active,+.menuitem.check:insensitive,+.menuitem.radio,+.menuitem.radio:active,+.menuitem.radio:insensitive {+    box-shadow: none;+}++.menuitem.check,+.menuitem.check:hover,+.menuitem.check:insensitive,+.menuitem.radio,+.menuitem.radio:hover,+.menuitem.radio:insensitive {+    background-image: none;+    background-color: transparent;+}++/* this controls the general appearance of the menubar */+.menubar {+    -GtkWidget-window-dragging: true;++    border-style: none;+}++.menubar .menuitem {+    padding: 3px 8px;+}++/* combobox menus */+GtkTreeMenu.menu {+    background-color: @theme_base_color;+}++GtkTreeMenu.menu .menuitem {+    padding: 4px 2px 2px 2px;+    color: @theme_text_color;+}++/**********************+ * Notebooks and tabs *+ **********************/+.notebook {+    engine: none;++    -GtkNotebook-initial-gap: 4;+    -GtkNotebook-tab-overlap: 1;+    -GtkNotebook-tab-curvature: 0;++    padding: 0;+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+    background-color: @theme_base_color;+}++.notebook:insensitive {+    border-color: @insensitive_border_color;+}++.notebook GtkViewport {+    background-color: @theme_base_color;+}++.notebook tab {+    padding: 5px 9px;+}++.notebook tab.top {+    border-radius: 0;+    border-width: 1px 1px 0 1px;+}++.notebook tab:first-child.top {+    border-top-left-radius: 4px;+}++.notebook tab:last-child.top {+    border-top-right-radius: 4px;+}++.notebook tab.top:active:focus {+/* +    border-image-slice: 1;+    border-image-source: linear-gradient(to bottom, @focused_border_color, @border_color);+ */+    box-shadow: inset 0 1px alpha(@focused_border_color, 0.2),+                inset -1px 0 alpha(@focused_border_color, 0.1),+                inset 1px 0 alpha(@focused_border_color, 0.1);+}++.notebook tab.right {+    border-radius: 0;+    border-width: 1px 1px 1px 0;+}++.notebook tab:first-child.right {+    border-top-right-radius: 4px;+}++.notebook tab:last-child.right {+    border-bottom-right-radius: 4px;+}++.notebook tab.right:active:focus {+/* +    border-image-slice: 1;+    border-image-source: linear-gradient(to left, @focused_border_color, @border_color);+ */+    box-shadow: inset -1px 0 alpha(@focused_border_color, 0.2),+                inset 0 1px alpha(@focused_border_color, 0.1),+                inset 0 -1px alpha(@focused_border_color, 0.1);+}++.notebook tab.bottom {+    border-radius: 0;+    border-width: 0 1px 1px 1px;+}++.notebook tab:first-child.bottom {+    border-bottom-left-radius: 4px;+}++.notebook tab:last-child.bottom {+    border-bottom-right-radius: 4px;+}++.notebook tab.bottom:active:focus {+/* +    border-image-slice: 1;+    border-image-source: linear-gradient(to top, @focused_border_color, @border_color);+ */+    box-shadow: inset 0 -1px alpha(@focused_border_color, 0.2),+                inset -1px 0 alpha(@focused_border_color, 0.1),+                inset 1px 0 alpha(@focused_border_color, 0.1);+}++.notebook tab.left {+    border-radius: 0;+    border-width: 1px 0 1px 1px;+}++.notebook tab:first-child.left {+    border-top-left-radius: 4px;+}++.notebook tab:last-child.left {+    border-bottom-left-radius: 4px;+}++.notebook tab.left:active:focus {+/* +    border-image-slice: 1;+    border-image-source: linear-gradient(to right, @focused_border_color, @border_color);+ */+    box-shadow: inset 1px 0 alpha(@focused_border_color, 0.2),+                inset 0 1px alpha(@focused_border_color, 0.1),+                inset 0 -1px alpha(@focused_border_color, 0.1);+}++/* close button styling */+.notebook tab .button,+.notebook tab .button:hover,+.notebook tab .button:active {+    border-style: none;+    background-image: none;+    background-color: transparent;+}++.notebook tab .button {+    color: @internal_element_color;+}++.notebook tab .button:hover {+    color: @theme_fg_color;+}++.notebook tab .button:active {+    color:  @theme_selected_bg_color;+}++/************+ * Toolbars *+ ************/+.toolbar {+    padding: 6px;+    border-width: 0;+    border-style: solid;+    border-color: @border_color;+    color: @theme_fg_color;+}++.toolbar:insensitive {+    color: @insensitive_fg_color;+}++.toolbar .separator {+    color: @insensitive_border_color;+}++.toolbar .button {+    padding: 3px;+}++.toolbar .button.text-button {+    padding: 4px 16px;+}++.toolbar .button.image-button {+    padding: 7px;+}++/********************+ * Menubar Toolbars *+ ********************/+.toolbar.menubar {+    -GtkToolbar-button-relief: normal;+}++/***************+ * Header bars *+ ***************/+.header-bar {+    padding: 6px;+    border-width: 0 0 1px 0;+    border-style: solid;+    border-color: @border_color;+}++.header-bar:backdrop {+    color: @internal_element_color;+}++.header-bar .button.text-button {+    padding: 4px 16px;+}++.header-bar .button.image-button {+    padding: 7px;+}++.header-bar .title {+    font: Bold 11;+}++.header-bar .subtitle {+    font: 9;+}++/********************+ * Primary Toolbars *+ ********************/+/* applications using EggEditableToolbar usually set the primary-toolbar+ * hint on the containing vbox, so we need to handle both these cases here.+ */+.primary-toolbar .toolbar,+.primary-toolbar.toolbar {+    -GtkWidget-window-dragging: true;+    -GtkToolbar-button-relief: normal;++    padding-top: 3px;+    padding-bottom: 3px;+    border-width: 1px 0;+    border-style: solid;+    border-color: @border_color;+}++/*******************+ * Inline toolbars *+ *******************/+.inline-toolbar.toolbar {+    -GtkToolbar-button-relief: normal;++    padding: 3px;+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+}++.inline-toolbar.toolbar:insensitive {+    border-color: @insensitive_border_color;+}++.inline-toolbar.toolbar:last-child {+    border-top-width: 0;+}++.inline-toolbar.toolbar.vertical:last-child {+    border-left-width: 0;+}++.inline-toolbar.toolbar .button {+    padding: 7px;+}++/***********+ * Sidebar *+ ***********/+.sidebar,+.sidebar .view,+.sidebar GtkScrolledWindow {+    background-color: @alt_subdued_color;+}++.sidebar .view:hover {+    background-color: @subdued_color;+}++.sidebar .view:selected {+    background-color: @theme_selected_bg_color;+}++.sidebar .view.radio,+.sidebar .view.radio:active,+.sidebar .view.radio:focus,+.sidebar .view.radio:active:focus {+    box-shadow: none;+}++.sidebar .view.radio,+.sidebar .view.radio:selected {+    background-image: none;+    background-color: transparent;+}++/****************+ * GtkAssistant *+ ****************/+GtkAssistant .sidebar {+    padding: 12px;+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+    background-color: @alt_subdued_color;+    color: @internal_element_color;+    /* shall we make it like sidebars in general? */+}++GtkAssistant .sidebar .highlight {+    background-color: transparent;+    color: @theme_fg_color;+    font: bold;+}++/***********************+ * Tree and Icon views *+ ***********************/+GtkTreeView {+    -GtkTreeView-vertical-separator: 0;+}++GtkIconView.cell:selected {+    /* FIXME: this probably needs to be better;+     * see https://bugzilla.gnome.org/show_bug.cgi?id=644157+     */+    -GtkWidget-focus-padding: 1;+    -GtkWidget-focus-line-width: 1;++    border-radius: 8px;+}++GtkTreeView:selected:focus,+GtkIconView.cell:selected:focus {+    outline-color: @selected_internal_element_color;+}++GtkTreeView.cell {+    padding: 2px;+}++GtkTreeView.cell:hover {+    background-color: @alt_base_color;+    color: @theme_selected_fg_color;+}++.cell:insensitive {+    color: @insensitive_fg_color;+}++.cell:selected, row:selected, .cell:hover:selected {+    background-color: @theme_selected_bg_color;+    border-width: 0;+    border-radius: 3px;+    color: @theme_selected_fg_color;+    box-shadow: inset 0px 0px 3px mix(@theme_base_color, @theme_selected_bg_color, 0.4);+}++.cell:insensitive:selected {+    color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.5);+}++column-header.button,+column-header .button {+    padding: 2px 4px;+    border-radius: 0;+    border-width: 0 1px 1px 0;+}++column-header.button:last-child,+column-header:last-child .button {+    border-right-width: 0;+}++column-header .button.dnd {+    border-width: 0 1px 1px 1px;+}++.expander,+.expander:active {+    border-color: @internal_element_color;+    color: @internal_element_color;+}++.expander:hover,+.expander:active:hover {+    border-color: @theme_fg_color;+    color: @theme_fg_color;+}++.expander:insensitive,+.expander:active:insensitive {+    border-color: @insensitive_internal_element_color;+    color: @insensitive_internal_element_color;+}++.expander:focus,+.expander:active:focus {+    border-color: @theme_selected_bg_color;+}++.expander row:selected,+.expander row:active:selected {+    border-color: @selected_internal_element_color;+    color: @selected_internal_element_color;+}++.expander row:selected:hover,+.expander row:active:selected:hover {+    border-color: @theme_selected_fg_color;+    color: @theme_selected_fg_color;+}++.expander row:insensitive:selected,+.expander row:active:insensitive:selected {+    border-color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.7);+    color: mix(@theme_selected_fg_color, @theme_selected_bg_color, 0.7);+}++/**************+ * List boxes *+ **************/+.list-row,+EggListBox {+    -GtkWidget-focus-padding: 1;+    -GtkWidget-focus-line-width: 1;+}++.list,+EggListBox {+    background-color: @theme_base_color;+    color: @theme_text_color;+}++.list-row:hover,+EggListBox:hover {+    background-color: @alt_base_color;+}++.list-row:insensitive,+EggListBox:insensitive {+    background-color: @alt_base_color;+    color: @insensitive_fg_color;+}++.list-row:selected,+EggListBox:selected {+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++.list-row:selected:focus,+EggListBox:selected:focus {+    outline-color: @selected_internal_element_color;+}++/****************+ * Content view *+ ****************/+/* FIXME: EggListBox should set the .cell style class on+ * the background it renders for the children, like+ * GtkIconView and GtkTreeView do */+.content-view.view,+.content-view.cell {+    background-color: @alt_base_color;+    color: @theme_fg_color;+}++.content-view.view:hover,+.content-view.cell:hover,+EggListBox.content-view:hover {+    background-color: @theme_bg_color;+}++.content-view.view:insensitive,+.content-view.cell:insensitive,+EggListBox.content-view:insensitive {+    color: @insensitive_fg_color;+}++.content-view.view:active,+.content-view.view:selected,+.content-view.cell:active,+.content-view.cell:selected,+EggListBox.content-view:active,+EggListBox.content-view:selected {+    background-image: none;+    background-color: @theme_selected_bg_color;+    color: @theme_selected_fg_color;+}++GdMainIconView.content-view {+    -GdMainIconView-icon-size: 40;+}++GtkIconView.content-view.cell.check {+    opacity: 0.9;+    background-size: contain;+}++GtkIconView.content-view.check:hover,+GtkIconView.content-view.check:insensitive,+GtkIconView.content-view.check:selected {+    background-color: transparent;+}++.content-view.view.check,+.content-view.view.check:active {+    background-color: transparent;+}++.content-view.view .separator {+    color: @insensitive_border_color;+}++/* used by Documents and Evince */+.content-view.document-page {+    border-image: url("assets/thumbnail-frame.png") 3 3 6 4;+    border-width: 3px 3px 6px 4px;+    border-style: solid;+}++/************+ * Tooltips *+ ************/+.tooltip {+    opacity: 0.9;+    padding: 5px;+    border-radius: 4px;+    background-color: alpha(@theme_tooltip_bg_color, 0.9);+    color: alpha(@theme_tooltip_fg_color, 0.9);+}++/*****************+ * Floating bars *+ *****************/+.floating-bar {+    opacity: 0.9;+    padding: 3px;+    border-radius: 4px;+    background-color: @theme_tooltip_bg_color;+    color: @theme_tooltip_fg_color;+}++.floating-bar.top {+    border-top-left-radius: 0;+    border-top-right-radius: 0;+}++.floating-bar.right {+    border-top-right-radius: 0;+    border-bottom-right-radius: 0;+}++.floating-bar.bottom {+    border-bottom-right-radius: 0;+    border-bottom-left-radius: 0;+}++.floating-bar.left {+    border-top-left-radius: 0;+    border-bottom-left-radius: 0;+}++/*********************+ * App Notifications *+ *********************/+.app-notification {+    opacity: 0.9;+    padding: 8px;+    border-radius: 0 0 8px 8px;+    background-color: @theme_tooltip_bg_color;+    color: @theme_tooltip_fg_color;+}++/*******+ * OSD *+ *******/+.osd {+    opacity: 0.9;+}++.background.osd {+    background-color: @theme_tooltip_bg_color;+    color: @theme_tooltip_fg_color;+}++GtkOverlay.osd {+    background-color: transparent;+}++.osd.frame {+    background-clip: border-box;+    background-origin: border-box;+}++.osd .button {+    padding: 7px;+}++.osd.button {+    padding: 11px;+}++.osd.toolbar {+    -GtkToolbar-button-relief: normal;++    padding: 8px;+    border-radius: 8px;+    border-style: none;+    background-image: linear-gradient(to bottom,+                                      mix(@theme_tooltip_bg_color, @subdued_color, 0.2),+                                      mix(@theme_tooltip_bg_color, @border_color, 0.2)+                                      );+    background-color: transparent;+    color: @theme_tooltip_fg_color;+}++.osd.toolbar .separator {+    color: @insensitive_border_color;+}++/* used by gnome-settings-daemon's media-keys OSD */+.osd.progressbar {+    background-color: @theme_selected_bg_color;+}++.osd.trough {+    background-color: mix(@button_top_active_color, @button_bottom_active_color, 0.5);+}++.osd GtkProgressBar,+GtkProgressBar.osd {+    -GtkProgressBar-xspacing: 0;+    -GtkProgressBar-yspacing: 4;+    -GtkProgressBar-min-horizontal-bar-height: 4;++    padding: 0;+}++.osd GtkProgressBar.progressbar,+GtkProgressBar.osd.progressbar {+    border-radius: 0;+    border-style: none;+    background-image: none;+    background-color: @theme_selected_bg_color;+}++.osd GtkProgressBar.trough,+GtkProgressBar.osd.trough {+    padding: 0;+    border-radius: 0;+    border-style: none;+    background-image: none;+    background-color: transparent;+}++.osd .view,+.osd.view {+    background-color: @theme_tooltip_bg_color;+    color: @theme_tooltip_fg_color;+}++/* used by Documents */+.osd .page-thumbnail {+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+    /* when there's no pixbuf yet */+    background-color: @theme_tooltip_bg_color;+}++/*************************+ * Touch text selections *+ *************************/+GtkBubbleWindow {+    border-radius: 8px;+}++GtkBubbleWindow.osd.background {+    background-color: @theme_tooltip_bg_color;+}++GtkBubbleWindow .toolbar {+    background-color: transparent;+}++/*******+ * CSD *+ *******/+.titlebar {+    background-image: linear-gradient(to bottom,+                                      @button_top_color,+                                      @theme_bg_color);+    border-radius: 7px 7px 0px 0px;+}++/* this is the default titlebar that is added by GTK+ * when client-side decorations are in use and the application+ * did not set a custom titlebar.+ */+.titlebar.default-decoration {+    border: none;+    box-shadow: none;+}++.titlebar .title {+    font: Bold 11;+}++.titlebar:backdrop {+    text-shadow: none;+    background-image: none;+    background-color: @theme_bg_color;+}++.titlebar .titlebutton {+    color: @theme_fg_color;+}++.titlebar .titlebutton:hover {+}++.titlebar .titlebutton:active {+}++.titlebar .titlebutton:backdrop {+    color: @internal_element_color;+}++.titlebar .titlebutton:backdrop:hover {+    color: @theme_fg_color;+}++.titlebar .right .titlebutton:first-child {+/*    border-left: 1px solid @menu_separator; */+}++.titlebar .right .titlebutton:last-child {++}++.titlebar .left .titlebutton:last-child {+/*    border-right: 1px solid @menu_separator; */+}++.titlebar .left .titlebutton:first-child {++}++.window-frame {+    border-radius: 7px 7px 0 0;+    border-width: 1px;+    border-style: solid;+    border-color: @border_color;+    box-shadow: 0 2px 8px 2px alpha(black, 0.5), 0 0 0 2px @border_color;++    /* this is used for the resize cursor area */+    margin: 10px;+}++.window-frame:backdrop {+    box-shadow: 0 2px 4px 0 alpha(black, 0.5), 0 0 0 2px @border_color;+}++/**********************+ * Fallback Mode Panel+ **********************/+.gnome-panel-menu-bar,+PanelApplet > GtkMenuBar.menubar,+PanelToplevel,+PanelWidget,+PanelAppletFrame,+PanelApplet {+    background-image: none;+    background-color: @os_chrome_bg_color;+    color: @os_chrome_fg_color;+}++ClockBox,+.gnome-panel-menu-bar.menubar,+PanelApplet > GtkMenuBar.menubar {+    font: bold;+}++.gnome-panel-menu-bar.menubar .menuitem:hover,+PanelApplet > GtkMenuBar.menubar .menuitem:hover {+    text-shadow: 0 1px @os_chrome_bg_color;+}++.gnome-panel-menu-bar.menubar .menu,+PanelApplet > GtkMenuBar.menubar .menu {+    font: regular;+}++.gnome-panel-menu-bar.menubar .menu:hover,+PanelApplet > GtkMenuBar.menubar .menu:hover {+    text-shadow: none;+}++.gnome-panel-menu-bar .menuitem:hover,+PanelApplet > GtkMenuBar.menubar .menuitem:hover {+    background-color: @os_chrome_selected_bg_color;+    color: @os_chrome_selected_fg_color;+}++PanelApplet .button,+PanelApplet .button:hover {+    padding: 4px;++    border-radius: 0;+    border-image: none;+    border-width: 0;++    background-image: none;+    background-color: @os_chrome_bg_color;++    color: @os_chrome_fg_color;+    text-shadow: none;+}++PanelApplet .button:active:hover,+PanelApplet .button:active {+    border-radius: 0;+    border-image: none;+    border-width: 0;+    background-image: none;+    background-color: @os_chrome_selected_bg_color;+}++PanelApplet:hover {+    color: @os_chrome_selected_fg_color;+}++PanelApplet:active,+PanelApplet:hover:active {+    color: @os_chrome_selected_fg_color;+    text-shadow: 0 1px @os_chrome_bg_color;+}++WnckPager {+    background-color: lighter(@os_chrome_selected_bg_color);+}++NaTrayApplet {+    -NaTrayApplet-icon-padding: 12;+    -NaTrayApplet-icon-size: 16;+}++GsmFailWhaleDialog {+    background-image: none;+    background-color: @os_chrome_bg_color;+    color: @os_chrome_fg_color;+}++GsmFailWhaleDialog .button,+GsmFailWhaleDialog .button:active {+    border-image: none;+    border-width: 1px;+    border-color: @alt_border_color;+}++GtkSourceView {+    background-color: @theme_bg_color;+    color: @theme_fg_color;+    font: monospace;+}+
+ app-data/themes/gtk/default/gtk.css view
@@ -0,0 +1,31 @@+/* Default color scheme */+@define-color theme_base_color #ffffff;+@define-color theme_text_color #2e3436;++@define-color border_color #888a85;+@define-color internal_element_color #888a85;++@define-color theme_selected_bg_color #4e9a06;+@define-color theme_selected_fg_color #36342e;++@define-color link_color #729fcf;+@define-color info_color #c4a000;+@define-color warning_color #f57900;+@define-color question_color #ad7fa8;+@define-color error_color #ef2929;+@define-color other_color #c17d11;++@define-color subdued_color shade(@theme_base_color, 0.7);+@define-color theme_bg_color mix(@theme_base_color, @subdued_color, 0.7);+@define-color theme_fg_color @theme_text_color;+@define-color theme_tooltip_bg_color mix(@subdued_color, #000000, 0.5);+@define-color theme_tooltip_fg_color @theme_text_color;++@define-color placeholder_text_color @internal_element_color;++@import url("gtk-common.css");+@import url("gtk-widgets-assets.css");+@import url("gtk-widgets-backgrounds-and-texts.css");+@import url("gtk-widgets-borders.css");+@import url("gtk-widgets.css");+@import url("gnome-applications.css");
+ app-data/themes/gtk/default/keybindings.css view
@@ -0,0 +1,10 @@++@binding-set treeViewExpander+{+    bind "Left" { "expand-collapse-cursor-row" (1, 0, 0) };+    bind "Right" { "expand-collapse-cursor-row" (1, 1, 0) };+}++GtkTreeView {+    gtk-key-bindings: treeViewExpander;   +}
+ app-data/themes/gtk/default/reset.css view
@@ -0,0 +1,63 @@+/* from http://ruby-doc.org/gems/docs/g/gtk3-2.2.0/sample/gtk-demo/reset_css.html */++* {+  color: inherit;+  font-size: inherit;+  background-color: initial;+  font-family: inherit;+  font-style: inherit;+  font-variant: inherit;+  font-weight: inherit;+  text-shadow: inherit;+  icon-shadow: inherit;+  box-shadow: initial;+  margin-top: initial;+  margin-left: initial;+  margin-bottom: initial;+  margin-right: initial;+  padding-top: initial;+  padding-left: initial;+  padding-bottom: initial;+  padding-right: initial;+  border-top-style: initial;+  border-top-width: initial;+  border-left-style: initial;+  border-left-width: initial;+  border-bottom-style: initial;+  border-bottom-width: initial;+  border-right-style: initial;+  border-right-width: initial;+  border-top-left-radius: initial;+  border-top-right-radius: initial;+  border-bottom-right-radius: initial;+  border-bottom-left-radius: initial;+  outline-style: initial;+  outline-width: initial;+  outline-offset: initial;+  background-clip: initial;+  background-origin: initial;+  background-size: initial;+  background-position: initial;+  border-top-color: initial;+  border-right-color: initial;+  border-bottom-color: initial;+  border-left-color: initial;+  outline-color:  initial;+  background-repeat: initial;+  background-image: initial;+  border-image-source: initial;+  border-image-repeat: initial;+  border-image-slice: initial;+  border-image-width: initial;+  transition-property: initial;+  transition-duration: initial;+  transition-timing-function: initial;+  transition-delay: initial;+  engine: initial;+  gtk-key-bindings: initial;++  -GtkWidget-focus-line-width: 0;+  -GtkWidget-focus-padding: 0;+  -GtkNotebook-initial-gap: 0;+}+
+ app-data/themes/gtksourceview/molokai.xml view
@@ -0,0 +1,33 @@+<?xml version="1.0" ?>+<style-scheme id="molokai" name="Molokai" version="1.0">+	<author/>+	<_description>+		Port of the Molokai Text Mate Theme to GTKSourceView. +	</_description>+	<style foreground="#AE81FF" name="def:boolean"/>+	<style foreground="#AE81FF" name="def:number"/>+	<style foreground="#E6DB74" name="def:string"/>+	<style bold="true" foreground="#AE81FF" name="def:constant"/>+	<style background="#F8F8F0" foreground="#000000" name="cursor"/>+	<style background="#13354A" name="diff:added-line"/>+	<style background="#4C4745" foreground="#89807D" name="diff:changed-line"/>+	<style background="#1E0010" foreground="#960050" name="diff:removed-line"/>+	<style background="#1E0010" foreground="#960050" name="def:error"/>+	<style foreground="#A6E22E" name="def:function"/>+	<style foreground="#FD971F" name="def:identifier"/>+	<style bold="true" foreground="#F92672" name="def:keyword"/>+	<style background="#FD971F" bold="true" foreground="#000000" name="bracket-match"/>+	<style foreground="#A6E22E" name="def:preprocessor"/>+	<style background="#455354" foreground="#FFFFFF" name="search-match"/>+	<style background="#bg" foreground="#66D9EF" italic="true" name="def:specials"/>+	<style bold="true" foreground="#F92672" name="def:statement"/>+	<style foreground="#66D9EF" name="def:type"/>+	<style background="#272822" foreground="#F8F8F2" name="text"/>+	<style foreground="#75715E" name="def:comment"/>+	<style background="#3E3D32" name="current-line"/>+	<style background="#272822" foreground="#F8F8F2" name="text"/>+	<style foreground="#465457" name="def:comment"/>+	<style background="#3e3d32" name="current-line"/>+	<style background="#3b3a32" foreground="#bcbca7" name="line-numbers"/>+</style-scheme>+
+ app-data/ui.glade view
@@ -0,0 +1,122 @@+<?xml version="1.0" encoding="UTF-8"?>+<!-- Generated with glade 3.16.1 -->+<interface>+  <requires lib="gtk+" version="3.10"/>+  <object class="GtkWindow" id="mainWindow">+    <property name="can_focus">False</property>+    <child>+      <object class="GtkPaned" id="sidebarPaned">+        <property name="visible">True</property>+        <property name="can_focus">False</property>+        <child>+          <object class="GtkBox" id="box2">+            <property name="width_request">170</property>+            <property name="visible">True</property>+            <property name="can_focus">False</property>+            <property name="orientation">vertical</property>+            <child>+              <object class="GtkScrolledWindow" id="sidebarScroller">+                <property name="visible">True</property>+                <property name="can_focus">False</property>+                <child>+                  <object class="GtkTreeView" id="directoryListing">+                    <property name="visible">True</property>+                    <property name="can_focus">True</property>+                    <child internal-child="selection">+                      <object class="GtkTreeSelection" id="treeview-selection1"/>+                    </child>+                    <style>+                      <class name="sidebar"/>+                    </style>+                  </object>+                </child>+              </object>+              <packing>+                <property name="expand">True</property>+                <property name="fill">True</property>+                <property name="position">0</property>+              </packing>+            </child>+            <child>+              <object class="GtkEntry" id="directoryListingSearch">+                <property name="can_focus">True</property>+                <property name="hexpand">True</property>+                <property name="invisible_char">●</property>+              </object>+              <packing>+                <property name="expand">False</property>+                <property name="fill">True</property>+                <property name="position">1</property>+              </packing>+            </child>+          </object>+          <packing>+            <property name="resize">False</property>+            <property name="shrink">True</property>+          </packing>+        </child>+        <child>+          <object class="GtkBox" id="box1">+            <property name="visible">True</property>+            <property name="can_focus">False</property>+            <property name="orientation">vertical</property>+            <child>+              <object class="GtkNotebook" id="tabbedEditArea">+                <property name="visible">True</property>+                <property name="can_focus">True</property>+                <property name="hexpand">True</property>+                <property name="vexpand">True</property>+                <property name="show_border">False</property>+              </object>+              <packing>+                <property name="expand">True</property>+                <property name="fill">True</property>+                <property name="position">0</property>+              </packing>+            </child>+            <child>+              <object class="GtkBox" id="box6">+                <property name="visible">True</property>+                <property name="can_focus">False</property>+                <child>+                  <object class="GtkEntry" id="command">+                    <property name="visible">True</property>+                    <property name="can_focus">True</property>+                    <property name="invisible_char">●</property>+                    <property name="caps_lock_warning">False</property>+                  </object>+                  <packing>+                    <property name="expand">True</property>+                    <property name="fill">True</property>+                    <property name="position">0</property>+                  </packing>+                </child>+                <child>+                  <object class="GtkLabel" id="activeMode">+                    <property name="visible">True</property>+                    <property name="can_focus">False</property>+                  </object>+                  <packing>+                    <property name="expand">False</property>+                    <property name="fill">False</property>+                    <property name="pack_type">end</property>+                    <property name="position">1</property>+                  </packing>+                </child>+              </object>+              <packing>+                <property name="expand">False</property>+                <property name="fill">False</property>+                <property name="position">2</property>+              </packing>+            </child>+          </object>+          <packing>+            <property name="resize">True</property>+            <property name="shrink">True</property>+          </packing>+        </child>+      </object>+    </child>+  </object>+</interface>
+ hob.cabal view
@@ -0,0 +1,71 @@+name: hob+version: 0.0.1.0+cabal-version: >=1.10+build-type: Simple+license: GPL-3+license-file: LICENSE+copyright: (c) Sarunas Valaskevicius+maintainer: Sarunas Valaskevicius <rakatan@gmail.com>+synopsis: A source code editor aiming for the convenience of use+description: A simple command based code editor being developed for the mouse-free workflow.+homepage: http://svalaskevicius.github.io/hob/+stability: alpha+bug-reports: http://github.com/svalaskevicius/hob/issues+category: IDE+author: Sarunas Valaskevicius+data-dir: app-data+data-files: ui.glade,+            themes/gtksourceview/*.xml,+            themes/gtk/default/*.css,+            themes/gtk/default/assets/*.png,+            themes/gtk/default/assets/*.svg++source-repository head+    type: git+    location: https://github.com/svalaskevicius/hob++executable hob+    build-depends: base >=4.2 && <5, gtk3 >=0.13.0.1, mtl >=2.1.0 && <2.2.0,+                   directory -any, containers -any, filepath -any, hob, bytestring -any, text >= 1.1.1.0 && < 1.1.2.0,+                   gtksourceview3 >=0.13.0.0+    main-is: hob.hs+    buildable: True+    default-language: Haskell2010+    ghc-options:+        -Wall+    hs-source-dirs: src++library+    Exposed-modules:     Hob.Ui, Hob.Ui.Editor, Hob.Ui.Sidebar, Hob.Ui.CommandEntry,+                         Hob.Ui.SidebarSearch, Hob.Ui.Editor.Search,+                         Hob.Command.FindText, Hob.Command.ReplaceText, Hob.Command.CloseCurrentTab,+                         Hob.Command.SaveCurrentTab, Hob.Command.NewTab, Hob.Command.FocusCommandEntry,+                         Hob.Command.FocusNextTab, Hob.Command.ReloadSidebarTree, Hob.Command.FocusSidebar,+                         Hob.Command.FocusPreviousTab, Hob.Command.FocusNumberedTab,+                         Hob.Context, Hob.Context.StyleContext, Hob.Context.FileContext, Hob.Context.UiContext,+                         Hob.Context.Types, Hob.Context.Events, Hob.Context.CommandMatcher, Hob.Context.Editor,+                         Hob.DirectoryTree, Hob.Control+    default-language:    Haskell2010+    ghc-options:+        -Wall+    hs-source-dirs:      src/lib+    build-depends: base >=4.7 && <5, containers -any,+                   filepath -any, glib >=0.13.0.0, gtk3 >=0.13.0.1, pango >= 0.13.0.0,+                   gtksourceview3 >=0.13.0.0, mtl >=2.1.0 && <2.2.0,+                   transformers >=0.3.0.0 && <0.4, text >= 1.1.1.0,+                   system-filepath -any, gtk-largeTreeStore >= 0.0.1.0, vector >= 0.10.12.2 && < 0.10.13++test-suite spec+  type:+      exitcode-stdio-1.0+  default-language: Haskell2010+  ghc-options:+      -Wall -Werror+  hs-source-dirs:+      test+  main-is:+      Spec.hs+  other-modules: Hob.Ui.SidebarSpec, Hob.Ui.EditorSpec, Hob.Ui.CommandEntrySpec, Hob.Ui.Editor.SearchSpec, Hob.Ui.SidebarSearchSpec, Hob.UiSpec, Hob.ContextSpec, Hob.ControlSpec, Hob.DirectoryTreeSpec, Hob.Command.FocusNextTabSpec, Hob.Command.FindTextSpec, Hob.Command.CloseCurrentTabSpec, Hob.Command.FocusSidebarSpec, Hob.Command.SaveCurrentTabSpec, Hob.Command.ReplaceTextSpec, Hob.Command.FocusCommandEntrySpec, Hob.Command.NewTabSpec, Hob.Command.FocusPreviousTabSpec, Hob.Command.FocusNumberedTabSpec, Hob.Command.ReloadSidebarTreeSpec, Hob.Context.FileContextSpec, Hob.Context.StyleContextSpec, HobTest.Sidebar, HobTest.Editor, HobTest.Context.Stubbed, HobTest.Context.Default, HobTest.Control+  build-depends:+      base    >= 4.2 && <5, containers -any, mtl >=2.1.0 && <2.2.0,+      hspec   >= 1.11, gtk3 >=0.13.0.1, hob, text >= 1.1.1.0, gtksourceview3 >=0.13.0.0
+ src/hob.hs view
@@ -0,0 +1,55 @@+module Main (main) where++import           Control.Monad.Trans (liftIO)+import qualified Data.ByteString     as BS+import qualified Data.Text.Encoding  as E+import           Graphics.UI.Gtk+import           System.Directory+import           System.Environment  (getArgs)+import           System.IO           (hPutStr, stderr)++import Hob.Context+import Hob.Context.FileContext  (FileLoader, FileTreeLoader, FileWriter,+                                 defaultFileContext)+import Hob.Context.StyleContext (defaultStyleContext)+import Hob.Context.UiContext+import Hob.DirectoryTree+import Hob.Ui++import Paths_hob++main :: IO ()+main = do+    fileCtx <- getFileContext+    styleCtx <- getStyleContext+    ctx <- loadGui fileCtx styleCtx+    let window = mainWindow . uiContext $ ctx+    _ <- window `on` deleteEvent $ liftIO mainQuit >> return False+    widgetShow window+    mainGUI+    where+         getFileContext = do+             projectRoot <- getProjectDirectory+             defaultFileContext loadFile storeFile (fileTreeFromDirectory projectRoot)+         getStyleContext = defaultStyleContext =<< getDataDir+         getProjectDirectory = do+             args <- getArgs+             case args of+                 [] -> getCurrentDirectory+                 [path] -> canonicalizePath path+                 _ -> error "unsupported command options"+++fileTreeFromDirectory :: FilePath -> FileTreeLoader+fileTreeFromDirectory = fileTreeGenerator getDirectoryContents doesDirectoryExist++loadFile :: FileLoader+loadFile path = do+        contents <- BS.readFile path+        checkError $ E.decodeUtf8' contents+        where checkError (Left e) = do hPutStr stderr (show e)+                                       return Nothing+              checkError (Right t) = return $ Just t++storeFile :: FileWriter+storeFile path = BS.writeFile path . E.encodeUtf8
+ src/lib/Hob/Command/CloseCurrentTab.hs view
@@ -0,0 +1,24 @@+module Hob.Command.CloseCurrentTab (closeCurrentEditorTab) where+++import Control.Monad.Trans (liftIO)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext++closeCurrentEditorTab :: CommandHandler+closeCurrentEditorTab = CommandHandler Nothing closeCurrentEditorTabHandler++closeCurrentEditorTabHandler :: App()+closeCurrentEditorTabHandler = do+    ui <- fromContext uiContext+    let tabbed = mainNotebook ui+    currentPage <- liftIO $ notebookGetCurrentPage tabbed+    nthPage <- liftIO $ notebookGetNthPage tabbed currentPage+    case nthPage of+        Just pageContents -> do+            liftIO $ notebookRemovePage tabbed currentPage+            liftIO $ widgetDestroy pageContents+        Nothing -> return ()+
+ src/lib/Hob/Command/FindText.hs view
@@ -0,0 +1,54 @@+module Hob.Command.FindText (+        searchCommandHandler,+        searchNextCommandHandler,+        searchBackwardsCommandHandler,+        searchPreview,+        searchResetPreview,+        searchMode,+    ) where++import Data.Monoid     (mconcat)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Ui.Editor+import Hob.Ui.Editor.Search++searchCommandHandler :: String -> CommandHandler+searchCommandHandler searchText = CommandHandler (Just $ PreviewCommandHandler (searchPreview searchText) searchResetPreview) (searchStart searchText)++searchNextCommandHandler :: CommandHandler+searchNextCommandHandler = CommandHandler Nothing searchNext++searchBackwardsCommandHandler :: CommandHandler+searchBackwardsCommandHandler = CommandHandler Nothing searchPrevious++searchPreview :: String -> App()+searchPreview text = invokeOnActiveEditor (`highlightSearchPreview` text)++searchReset :: App()+searchReset = invokeOnActiveEditor resetSearch++searchResetPreview :: App()+searchResetPreview = invokeOnActiveEditor resetSearchPreview++searchNext :: App()+searchNext = invokeOnActiveEditor findNext++searchPrevious :: App()+searchPrevious = invokeOnActiveEditor findPrevious++searchStart :: String -> App()+searchStart text = do+    enterMode searchMode+    invokeOnActiveEditor $ \editor -> do+        findFirstFromCursor editor text+        widgetGrabFocus editor++searchMode :: Mode+searchMode = Mode "search" matcher searchReset+    where matcher = mconcat [+                              createMatcherForKeyBinding ([Control], "Down") searchNextCommandHandler,+                              createMatcherForKeyBinding ([Control], "Up") searchBackwardsCommandHandler]++
+ src/lib/Hob/Command/FocusCommandEntry.hs view
@@ -0,0 +1,47 @@+module Hob.Command.FocusCommandEntry (+    toggleFocusOnCommandEntryCommandHandler,+    focusActiveEditorAndExitLastModeCommandHandler,+    focusCommandEntryCommandHandler,+    ) where++import Control.Monad.Reader+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext+import Hob.Control+import Hob.Ui.Editor++focusCommandEntryCommandHandler :: CommandHandler+focusCommandEntryCommandHandler = CommandHandler Nothing focusCommandEntry++focusActiveEditorAndExitLastModeCommandHandler :: CommandHandler+focusActiveEditorAndExitLastModeCommandHandler = CommandHandler Nothing focusActiveEditorAndExitLastMode++toggleFocusOnCommandEntryCommandHandler :: CommandHandler+toggleFocusOnCommandEntryCommandHandler = CommandHandler Nothing toggleFocusOnCommandEntry+++focusCommandEntry :: App()+focusCommandEntry = do+    ctx <- ask+    liftIO $ widgetGrabFocus $ cmdEntry ctx+    where cmdEntry ctx = commandEntry.uiContext $ ctx++focusActiveEditorAndExitLastMode :: App()+focusActiveEditorAndExitLastMode = do+    exitLastMode+    ctx <- ask+    editor <- liftIO $ getActiveEditor ctx+    liftIO $ maybeDo widgetGrabFocus editor++toggleFocusOnCommandEntry :: App()+toggleFocusOnCommandEntry = do+    ctx <- ask+    isFocused <- liftIO $ widgetGetIsFocus $ cmdEntry ctx+    if isFocused then do+        editor <- liftIO $ getActiveEditor ctx+        liftIO $ maybeDo widgetGrabFocus editor+    else+        liftIO $ widgetGrabFocus $ cmdEntry ctx+    where cmdEntry ctx = commandEntry.uiContext $ ctx
+ src/lib/Hob/Command/FocusNextTab.hs view
@@ -0,0 +1,22 @@+module Hob.Command.FocusNextTab (focusNextTabCommandHandler) where++import Control.Monad.Trans (liftIO)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext++focusNextTabCommandHandler :: CommandHandler+focusNextTabCommandHandler = CommandHandler Nothing focusNextTab++focusNextTab :: App()+focusNextTab = do+    ui <- fromContext uiContext+    let notebook = mainNotebook ui+    pages <- liftIO $ notebookGetNPages notebook+    currentPage <- liftIO $ notebookGetCurrentPage notebook+    liftIO $ notebookSetCurrentPage notebook (nextPage currentPage pages)+    where+        nextPage currentPage pages =+            if currentPage == (pages - 1) then 0 else currentPage + 1+
+ src/lib/Hob/Command/FocusNumberedTab.hs view
@@ -0,0 +1,18 @@+module Hob.Command.FocusNumberedTab (focusNumberedTabCommandHandler) where++import Control.Monad       (when)+import Control.Monad.Trans (liftIO)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext++focusNumberedTabCommandHandler :: Int -> CommandHandler+focusNumberedTabCommandHandler nr = CommandHandler Nothing $ focusNumberedTab nr++focusNumberedTab :: Int -> App()+focusNumberedTab nr = do+    ui <- fromContext uiContext+    let notebook = mainNotebook ui+    pages <- liftIO $ notebookGetNPages notebook+    when (nr >= 0 && nr < pages) $ liftIO $ notebookSetCurrentPage notebook nr
+ src/lib/Hob/Command/FocusPreviousTab.hs view
@@ -0,0 +1,22 @@+module Hob.Command.FocusPreviousTab (focusPreviousTabCommandHandler) where++import Control.Monad.Trans (liftIO)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext++focusPreviousTabCommandHandler :: CommandHandler+focusPreviousTabCommandHandler = CommandHandler Nothing focusPreviousTab++focusPreviousTab :: App()+focusPreviousTab = do+    ui <- fromContext uiContext+    let notebook = mainNotebook ui+    pages <- liftIO $ notebookGetNPages notebook+    currentPage <- liftIO $ notebookGetCurrentPage notebook+    liftIO $ notebookSetCurrentPage notebook (previousPage currentPage pages)+    where+        previousPage currentPage pages =+            if currentPage == 0 then pages - 1 else currentPage - 1+
+ src/lib/Hob/Command/FocusSidebar.hs view
@@ -0,0 +1,37 @@+module Hob.Command.FocusSidebar (+    focusSidebarCommandHandler,+    syncFocusSidebarCommandHandler+    ) where++import Control.Monad.Reader+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.UiContext+import Hob.Control+import Hob.Ui.Editor         (getActiveEditor, getEditorFilePath)+import Hob.Ui.Sidebar        (syncPathToSidebar)++focusSidebarCommandHandler :: CommandHandler+focusSidebarCommandHandler = CommandHandler Nothing focusSidebar++syncFocusSidebarCommandHandler :: CommandHandler+syncFocusSidebarCommandHandler = CommandHandler Nothing syncFocusSidebar++focusSidebar :: App()+focusSidebar = do+    ctx <- ask+    liftIO $ widgetGrabFocus . sidebarTree . uiContext $ ctx++syncActiveEditorPathToSidebar :: App()+syncActiveEditorPathToSidebar = do+    ctx <- ask+    editor <- liftIO $ getActiveEditor ctx+    maybeDo syncToEditor editor+    where syncToEditor editor = maybeDo syncPathToSidebar =<< liftIO (getEditorFilePath editor)+++syncFocusSidebar :: App()+syncFocusSidebar = syncActiveEditorPathToSidebar >> focusSidebar++
+ src/lib/Hob/Command/NewTab.hs view
@@ -0,0 +1,51 @@+module Hob.Command.NewTab (+            launchNewFileEditor,+            editNewFile,+            editNewFileCommandHandler,+            NewFileEditorLauncher) where+++import Control.Monad.Reader+import Data.Maybe           (mapMaybe)+import Data.Text            (pack)+import Graphics.UI.Gtk++import Hob.Context+import Hob.Context.FileContext+import Hob.Context.UiContext+import Hob.Control+import Hob.Ui.Editor++type NewFileEditorLauncher = FilePath -> IO ()++editNewFileCommandHandler :: CommandHandler+editNewFileCommandHandler = CommandHandler Nothing editNewFile++launchNewFileEditor :: Context -> Notebook -> NewFileEditorLauncher+launchNewFileEditor ctx targetNotebook filePath = do+    let fileLoader = contextFileLoader . fileContext $ ctx+    currentEditors <- mapM getEditorFromNotebookTab <=< containerGetChildren $ targetNotebook+    editorsForFile <- filterM (\(_, ed) -> isEditorFileMatching ed ) $ numberedJusts currentEditors+    case alreadyLoadedPage editorsForFile of+        Just nr -> notebookSetCurrentPage targetNotebook nr+        Nothing -> maybeDo launchEditor =<< fileLoader filePath++    where launchEditor text = deferredRunner ctx $ newEditorForText targetNotebook (Just filePath) text+          isEditorFileMatching editor = do+              f <- getEditorFilePath editor+              return $ maybe False (filePath ==) f+          alreadyLoadedPage [(nr, _)] = Just nr+          alreadyLoadedPage _ = Nothing++editNewFile :: App()+editNewFile = do+    ctx <- ask+    let tabbed = mainNotebook.uiContext $ ctx+    newEditorForText tabbed Nothing $ pack ""++liftTupledMaybe :: (a, Maybe b) -> Maybe (a, b)+liftTupledMaybe (x, Just y) = Just (x, y)+liftTupledMaybe (_, Nothing) = Nothing++numberedJusts :: [Maybe a] -> [(Int, a)]+numberedJusts a = mapMaybe liftTupledMaybe $ zip [0..] a
+ src/lib/Hob/Command/ReloadSidebarTree.hs view
@@ -0,0 +1,11 @@+module Hob.Command.ReloadSidebarTree (reloadSidebarTreeCommandHandler) where++import Hob.Context+import Hob.Ui.Sidebar++reloadSidebarTreeCommandHandler :: CommandHandler+reloadSidebarTreeCommandHandler = CommandHandler Nothing reloadCmd++reloadCmd :: App()+reloadCmd = reloadSidebarTree+
+ src/lib/Hob/Command/ReplaceText.hs view
@@ -0,0 +1,67 @@+module Hob.Command.ReplaceText (+        createMatcherForReplace,+        replaceCommandHandler,+        replaceNextCommandHandler,+    ) where++import Data.Monoid     (mconcat)+import Graphics.UI.Gtk++import Hob.Command.FindText+import Hob.Context+import Hob.Ui.Editor+import Hob.Ui.Editor.Search++createMatcherForReplace :: Char -> (String -> String -> CommandHandler) -> CommandMatcher+createMatcherForReplace prefix handler = CommandMatcher (const Nothing) match+    where match [] = Nothing+          match (p:ps)+           | p == prefix = matchSearchAndReplaceFromStart ps+           | otherwise = Nothing++          matchSearchAndReplaceFromStart [] = Nothing+          matchSearchAndReplaceFromStart (separator:xs) = matchSearchAndReplaceFromSearch separator xs ""++          matchSearchAndReplaceFromSearch _ [] _ = Nothing+          matchSearchAndReplaceFromSearch separator (x:xs) accumSearch+           | '\\' == x = case xs of+                            [] -> Nothing+                            (s:xss) -> if s == separator then matchSearchAndReplaceFromSearch separator xss (accumSearch++[separator])+                                       else matchSearchAndReplaceFromSearch separator xs (accumSearch++[x])+           | separator == x = matchSearchAndReplaceFromReplace separator xs accumSearch ""+           | otherwise = matchSearchAndReplaceFromSearch separator xs (accumSearch++[x])++          matchSearchAndReplaceFromReplace _ [] search accumReplace = Just $ handler search accumReplace+          matchSearchAndReplaceFromReplace separator (x:xs) search accumReplace+           | '\\' == x = case xs of+                            [] -> Just $ handler search (accumReplace++[x])+                            (s:xss) -> if s == separator then matchSearchAndReplaceFromReplace separator xss search (accumReplace++[separator])+                                       else matchSearchAndReplaceFromReplace separator xs search (accumReplace++[x])+           | separator == x = Just $ handler search accumReplace+           | otherwise = matchSearchAndReplaceFromReplace separator xs search (accumReplace++[x])++replaceCommandHandler :: String -> String -> CommandHandler+replaceCommandHandler searchText replaceText = CommandHandler (Just $ PreviewCommandHandler (searchPreview searchText) searchResetPreview) (replaceStart searchText replaceText)++replaceNextCommandHandler :: CommandHandler+replaceNextCommandHandler = CommandHandler Nothing invokeReplaceNext++replaceStart :: String -> String -> App()+replaceStart searchText replaceText = do+    enterMode replaceMode+    invokeOnActiveEditor $ \editor -> do+        startReplace editor searchText replaceText+        widgetGrabFocus editor++invokeReplaceNext :: App()+invokeReplaceNext = invokeOnActiveEditor replaceNext++replaceReset :: App()+replaceReset = invokeOnActiveEditor resetReplace++replaceMode :: Mode+replaceMode = Mode "replace" matcher replaceReset+    where matcher = mconcat [ commandMatcher searchMode+                            , createMatcherForKeyBinding ([Shift, Control], "Down") replaceNextCommandHandler+                            ]+
+ src/lib/Hob/Command/SaveCurrentTab.hs view
@@ -0,0 +1,59 @@+module Hob.Command.SaveCurrentTab (+        NewFileNameChooser,+        saveCurrentEditorTab,+        saveCurrentEditorTabHandler) where++import Control.Monad.Reader+import Graphics.UI.Gtk+import Graphics.UI.Gtk.SourceView (SourceView)++import Hob.Context+import Hob.Context.FileContext+import Hob.Context.UiContext+import Hob.Control+import Hob.Ui.Editor++type NewFileNameChooser = IO (Maybe FilePath)++saveCurrentEditorTab :: CommandHandler+saveCurrentEditorTab = CommandHandler Nothing (do+    ctx <- ask+    saveCurrentEditorTabHandler $ fileChooser ctx)+    where+        fileChooser :: Context -> IO (Maybe FilePath)+        fileChooser ctx = do+            dialog <- fileChooserDialogNew Nothing (Just $ mainWindow.uiContext $ ctx) FileChooserActionSave [("Cancel", ResponseCancel), ("Save", ResponseOk)]+            resp <- dialogRun dialog+            file <- if resp == ResponseOk then fileChooserGetFilename dialog else return Nothing+            widgetDestroy dialog+            return file++saveCurrentEditorTabHandler :: NewFileNameChooser -> App()+saveCurrentEditorTabHandler newFileNameChooser = do+    ctx <- ask+    maybeEditor <- liftIO $ getActiveEditor ctx+    maybeDo (saveInContext newFileNameChooser) maybeEditor+++saveInContext :: NewFileNameChooser -> SourceView -> App ()+saveInContext newFileNameChooser editor = do+    ctx <- ask+    liftIO $ saveEditor ctx+    where fileWriter ctx = contextFileWriter . fileContext $ ctx+          saveEditor ctx = do+              path <- getEditorFilePath editor+              case path of+                  Just filePath -> saveEditorContents ctx filePath+                  Nothing -> askForFile $ saveAsNewFile ctx+          askForFile onSuccess = newFileNameChooser >>= maybe (return()) onSuccess+          saveAsNewFile ctx filePath = do+              saveEditorContents ctx filePath+              setEditorFilePath editor $ Just filePath+              updateEditorTitle editor++          saveEditorContents ctx filePath = do+              textBuf <- textViewGetBuffer editor+              text <- get textBuf textBufferText+              fileWriter ctx filePath text+              textBuf `set` [textBufferModified := False]+              return ()
+ src/lib/Hob/Context.hs view
@@ -0,0 +1,85 @@+module Hob.Context (+    App,+    Context(..),+    PreviewCommandHandler(..),+    CommandHandler(..),+    CommandMatcher(..),+    KeyboardBinding,+    KeyCommandMatcher,+    TextCommandMatcher,+    Mode(..),+    Event(..),+    Editor(..),+    EditorList(..),+    initContext,+    runOnEditor,+    enterMode,+    exitLastMode,+    activeModes,+    deferredRunner,+    registerEventHandler,+    emitEvent,+    createMatcherForPrefix,+    createMatcherForCommand,+    createMatcherForKeyBinding,+    fromContext,+    runApp,+    getActiveCommands,+) where++import Control.Concurrent.MVar+import Control.Monad.Reader+import Graphics.UI.Gtk          (postGUIAsync)+import GtkExtras.LargeTreeStore as LTS (TreeStore)++import Hob.Context.CommandMatcher+import Hob.Context.Editor+import Hob.Context.Events+import Hob.Context.FileContext+import Hob.Context.StyleContext+import Hob.Context.Types+import Hob.Context.UiContext+import Hob.DirectoryTree++++initContext :: StyleContext -> FileContext -> UiContext -> LTS.TreeStore DirectoryTreeElement -> CommandMatcher -> IO Context+initContext styleCtx fileCtx uiCtx treeModel initCommands = do+    actionSync <- newMVar True+    deferredMessagesRef <- newMVar []+    bus <- initEventBus+    editorList <- initEditors+    initialisedIdGenerator <- initIdGenerator+    let ctx = Context styleCtx fileCtx uiCtx treeModel initCommands editorList (messageRunner actionSync deferredMessagesRef) bus initialisedIdGenerator+    return ctx+    where+        messageRunner actionSync deferredMessagesRef ctx message = do+            queueMessage deferredMessagesRef message+            sync <- tryTakeMVar actionSync+            case sync of+                Just _ -> flushMessageQueue deferredMessagesRef ctx >> putMVar actionSync True+                Nothing -> return()+        flushMessageQueue deferredMessagesRef ctx = do+            messages <- swapMVar deferredMessagesRef []+            unless (null messages) $ foldM runMessage ctx messages >>= flushMessageQueue deferredMessagesRef+        queueMessage deferredMessagesRef message = modifyMVar_ deferredMessagesRef (\messages -> return $ messages ++ [message])++runApp :: Context -> App a -> IO a+runApp ctx appSteps = runReaderT appSteps ctx++runMessage :: Context -> Message -> IO Context+runMessage  ctx (AppAction action) = runApp ctx action >> return ctx++deferredRunner :: Context -> App() -> IO()+deferredRunner ctx actions = postGUIAsync $ messageLoop ctx ctx $ AppAction actions++initIdGenerator :: IO (IO Int)+initIdGenerator = do+    generatorStorage <- newMVar 0+    return $ do+        lastGeneratdId <- takeMVar generatorStorage+        let newId = lastGeneratdId + 1+        putMVar generatorStorage newId+        return newId++
+ src/lib/Hob/Context/CommandMatcher.hs view
@@ -0,0 +1,33 @@+module Hob.Context.CommandMatcher (+    createMatcherForPrefix,+    createMatcherForCommand,+    createMatcherForKeyBinding,+) where++import Hob.Context.Types+++createMatcherForPrefix :: String -> (String -> CommandHandler) -> CommandMatcher+createMatcherForPrefix prefix handler = CommandMatcher (const Nothing) (matchHandler prefix)+    where+        matchHandler :: String -> String -> Maybe CommandHandler+        matchHandler (p:xs) (t:xt) = if p == t then matchHandler xs xt else Nothing+        matchHandler "" params = Just $ handler params+        matchHandler _ "" = Nothing++createMatcherForCommand :: String -> CommandHandler -> CommandMatcher+createMatcherForCommand command handler = CommandMatcher (const Nothing) (matchHandler command)+    where+        matchHandler :: String -> String -> Maybe CommandHandler+        matchHandler (p:xs) (t:xt) = if p == t then matchHandler xs xt else Nothing+        matchHandler "" "" = Just handler+        matchHandler _ "" = Nothing+        matchHandler "" _ = Nothing++createMatcherForKeyBinding :: KeyboardBinding -> CommandHandler -> CommandMatcher+createMatcherForKeyBinding keyBinding handler = CommandMatcher (matchHandler keyBinding) (const Nothing)+    where+        matchHandler :: KeyboardBinding -> KeyboardBinding -> Maybe CommandHandler+        matchHandler boundKey matchedKey = if boundKey == matchedKey then Just handler else Nothing++
+ src/lib/Hob/Context/Editor.hs view
@@ -0,0 +1,90 @@+module Hob.Context.Editor (+    initEditors,+    runOnEditor,+    enterMode,+    exitLastMode,+    activeModes,+    getActiveCommands,+    ) where++import Control.Concurrent.MVar+import Control.Monad.Reader+import Data.Monoid++import Hob.Context.Events+import Hob.Context.Types+++runOnEditor :: (Editor -> Editor -> a) -> Editor -> a+runOnEditor f editor = f editor editor++initEditors :: IO EditorList+initEditors = do+    editorList <- newMVar []+    return $ EditorList (updateEditorsHandler editorList) (getEditorsHandler editorList)+    where+        updateEditorsHandler editorList updater = do+            oldEditors <- takeMVar editorList+            newEditors <- updater oldEditors+            putMVar editorList newEditors+        getEditorsHandler = readMVar++currentEditor :: App (Maybe Editor)+currentEditor = do+    editorList <- fromContext editors+    active <- filterM (\e -> isCurrentlyActive e e) =<< liftIO (getEditors editorList)+    return $+        if null active then Nothing+        else Just $ head active++enterMode :: Mode -> App()+enterMode mode = do+    updateActiveEditor $ \editor -> do+        editor' <- clearEditorModes editor+        runOnEditor enterEditorMode editor' mode+    emitEvent $ Event "core.mode.change"+    where clearEditorModes editor = do+              modes <- runOnEditor modeStack editor+              if not . null $ modes then do+                  editor' <- runOnEditor exitLastEditorMode editor+                  clearEditorModes editor'+              else return editor++activeModes :: App (Maybe [Mode])+activeModes = do+    active <- currentEditor+    maybe (return Nothing) (runOnEditor modeStack >=> return . Just) active++exitLastMode :: App()+exitLastMode = do+    updateActiveEditor $ \editor -> runOnEditor exitLastEditorMode editor+    emitEvent $ Event "core.mode.change"++updateActiveEditor :: (Editor -> App Editor) -> App()+updateActiveEditor actions = do+    ctx <- ask+    editorList <- fromContext editors+    liftIO $ updateEditors editorList $ \oldEditors -> runReaderT (updateActiveEditorHandler oldEditors) ctx+    where+        updateActiveEditorHandler oldEditors = do+            (e1, e2) <- splitBeforeFirstActive oldEditors+            if null e2 then return oldEditors+            else do+                let active = head e2+                active' <- actions active+                return $ e1 ++ [active'] ++ tail e2+        splitBeforeFirstActive [] = return ([], [])+        splitBeforeFirstActive (x:xs) = do+            active <- runOnEditor isCurrentlyActive x+            if active then return ([], x:xs)+            else do+                (n, ns) <- splitBeforeFirstActive xs+                return (x:n, ns)++getActiveCommands :: App CommandMatcher+getActiveCommands = do+    base <- asks baseCommands+    maybeModes <- activeModes+    maybe (return base)+          (\modes -> return $ base `mappend` mconcat (fmap commandMatcher modes))+          maybeModes
+ src/lib/Hob/Context/Events.hs view
@@ -0,0 +1,45 @@+module Hob.Context.Events (+    initEventBus,+    registerEventHandler,+    emitEvent,+) where++import Control.Concurrent.MVar+import Control.Monad.Reader++import Hob.Context.Types++initEventBus :: IO EventBus+initEventBus = do+    bus <- newMVar []+    return $ EventBus (addEventListener bus) (lookupEvent bus)+    where+        addEventListener bus event action = do+            listeners <- takeMVar bus+            putMVar bus $ combineEventListeners event action listeners++        combineEventListeners :: Event -> App() -> [(Event, [App()])] -> [(Event, [App()])]+        combineEventListeners event action [] = [(event, [action])]+        combineEventListeners event action (x@(evt, initHandlers):xs) =+            if evt == event then (evt, action:initHandlers) : xs+            else x : combineEventListeners event action xs++        lookupEvent bus event = do+            listeners <- readMVar bus+            return $ findEvent event listeners++        findEvent _ [] = []+        findEvent event ((evt, handlers):xs) = if evt == event then handlers+                                               else findEvent event xs++registerEventHandler :: Event -> App() -> App()+registerEventHandler event handler = do+    bus <- fromContext eventBus+    liftIO $ addListener bus event handler++emitEvent :: Event -> App()+emitEvent event = do+    bus <- fromContext eventBus+    handlers <- liftIO $ listenersForEvent bus event+    sequence_ handlers+
+ src/lib/Hob/Context/FileContext.hs view
@@ -0,0 +1,35 @@+module Hob.Context.FileContext (+    FileContext(..),+    FileLoader,+    FileWriter,+    FileTreeLoader,+    defaultFileContext,+    sourceLanguage+) where++import Data.Text                  (Text)+import Data.Tree                  (Forest)+import Graphics.UI.Gtk.SourceView (SourceLanguage, SourceLanguageManager,+                                   sourceLanguageManagerGuessLanguage,+                                   sourceLanguageManagerNew)++import Hob.DirectoryTree++type FileLoader = FilePath -> IO (Maybe Text)+type FileWriter = FilePath -> Text -> IO ()+type FileTreeLoader = IO (Forest DirectoryTreeElement)++data FileContext = FileContext {+    contextLanguageManager :: SourceLanguageManager,+    contextFileLoader      :: FileLoader,+    contextFileWriter      :: FileWriter,+    contextFileTreeLoader  :: FileTreeLoader+}++defaultFileContext :: FileLoader -> FileWriter -> FileTreeLoader -> IO FileContext+defaultFileContext loader writer treeLoader = do+    languageManager <- sourceLanguageManagerNew+    return $ FileContext languageManager loader writer treeLoader++sourceLanguage :: FileContext -> FilePath -> IO (Maybe SourceLanguage)+sourceLanguage ctx filePath = sourceLanguageManagerGuessLanguage (contextLanguageManager ctx) (Just filePath) (Nothing::Maybe String)
+ src/lib/Hob/Context/StyleContext.hs view
@@ -0,0 +1,43 @@+module Hob.Context.StyleContext (+    StyleContext,+    defaultStyleContext,+    uiFile,+    uiTheme,+    sourceStyleScheme,+    sourceStyleFont+) where++import Control.Monad                 (liftM)+import Graphics.Rendering.Pango.Font (FontDescription,+                                      fontDescriptionFromString)+import Graphics.UI.Gtk.SourceView    (SourceStyleScheme,+                                      SourceStyleSchemeManager,+                                      sourceStyleSchemeManagerGetDefault,+                                      sourceStyleSchemeManagerGetScheme,+                                      sourceStyleSchemeManagerSetSearchPath)+import System.FilePath               ((</>))++data StyleContext = StyleContext {+    contextDataPath     :: FilePath,+    contextStyleManager :: SourceStyleSchemeManager+}++defaultStyleContext :: FilePath -> IO StyleContext+defaultStyleContext dataDir = do+    styleManager <- sourceStyleSchemeManagerGetDefault+    sourceStyleSchemeManagerSetSearchPath styleManager (Just [dataDir </> "themes" </> "gtksourceview"])+    return $ StyleContext dataDir styleManager++uiFile :: StyleContext -> FilePath+uiFile ctx = contextDataPath ctx </> "ui.glade"++uiTheme :: StyleContext -> FilePath+uiTheme ctx = contextDataPath ctx </> "themes" </> "gtk" </> "default" </> "gtk-dark.css"++sourceStyleScheme :: StyleContext -> Maybe FilePath -> IO (Maybe SourceStyleScheme)+sourceStyleScheme ctx _ = do+    style <- sourceStyleSchemeManagerGetScheme (contextStyleManager ctx) "molokai"+    return $ Just style++sourceStyleFont :: StyleContext -> Maybe FilePath -> IO (Maybe FontDescription)+sourceStyleFont _ _ = liftM Just $ fontDescriptionFromString "monospace 12"
+ src/lib/Hob/Context/Types.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE MultiParamTypeClasses #-}++module Hob.Context.Types (+    App,+    EventBus(..),+    Context(..),+    PreviewCommandHandler(..),+    CommandHandler(..),+    CommandMatcher(..),+    Message(..),+    KeyboardBinding,+    KeyCommandMatcher,+    TextCommandMatcher,+    Mode(..),+    Event(..),+    Editor(..),+    EditorList(..),+    fromContext,+    ) where++import Control.Monad.Reader+import Data.Maybe               (isJust)+import Data.Monoid+import Graphics.UI.Gtk          (Modifier)+import GtkExtras.LargeTreeStore as LTS (TreeStore)++import Hob.Context.FileContext+import Hob.Context.StyleContext+import Hob.Context.UiContext+import Hob.DirectoryTree+++type App = ReaderT Context IO++newtype Event = Event String deriving (Eq, Show)++data Editor = Editor {+    editorId           :: Editor -> App Int,+    enterEditorMode    :: Editor -> Mode -> App Editor,+    exitLastEditorMode :: Editor -> App Editor,+    modeStack          :: Editor -> App [Mode],+    isCurrentlyActive  :: Editor -> App Bool+}++data EventBus = EventBus {+    addListener       :: Event -> App() -> IO(),+    listenersForEvent :: Event -> IO [App()]+}++data EditorList = EditorList {+    updateEditors :: ([Editor] -> IO [Editor]) -> IO(),+    getEditors    :: IO [Editor]+}++data Context = Context {+    styleContext  :: StyleContext,+    fileContext   :: FileContext,+    uiContext     :: UiContext,+    fileTreeStore :: LTS.TreeStore DirectoryTreeElement,+    baseCommands  :: CommandMatcher,+    editors       :: EditorList,+    messageLoop   :: Context -> Message -> IO(),+    eventBus      :: EventBus,+    idGenerator   :: IO Int+}++data Mode = Mode {+    modeName       :: String,+    commandMatcher :: CommandMatcher,+    cleanup        :: App()+}++data Message = AppAction (App())+++data PreviewCommandHandler = PreviewCommandHandler {+                    previewExecute :: App(),+                    previewReset   :: App()+                }++data CommandHandler = CommandHandler {+                    commandPreview :: Maybe PreviewCommandHandler,+                    commandExecute :: App()+                }++type KeyboardBinding = ([Modifier], String)+type SingleCommandMatcher a = a -> Maybe CommandHandler+type KeyCommandMatcher = SingleCommandMatcher KeyboardBinding+type TextCommandMatcher = SingleCommandMatcher String++data CommandMatcher = CommandMatcher {+                    matchKeyBinding :: KeyCommandMatcher,+                    matchCommand    :: TextCommandMatcher+                }++instance Monoid CommandMatcher where+    mempty = CommandMatcher (const Nothing) (const Nothing)+    mappend l r = CommandMatcher (combineMatchKeyBinding l r) (combineMatchCommand l r)+        where combineMatchKeyBinding = combineMatcher matchKeyBinding+              combineMatchCommand = combineMatcher matchCommand+++fromContext :: MonadReader r m => (r -> a) -> m a+fromContext = asks+++combineMatcher :: (CommandMatcher -> SingleCommandMatcher a) -> CommandMatcher -> CommandMatcher -> SingleCommandMatcher a+combineMatcher combiner l r cmd = if isJust rightResult then rightResult else leftResult+    where leftResult = combiner l cmd+          rightResult = combiner r cmd
+ src/lib/Hob/Context/UiContext.hs view
@@ -0,0 +1,14 @@+module Hob.Context.UiContext (+    UiContext(..)+) where++import Graphics.UI.Gtk (Entry, Label, Notebook, TreeView, Window)++data UiContext = UiContext {+    mainWindow        :: Window,+    mainNotebook      :: Notebook,+    commandEntry      :: Entry,+    sidebarTree       :: TreeView,+    sidebarTreeSearch :: Entry,+    activeModesLabel  :: Label+}
+ src/lib/Hob/Control.hs view
@@ -0,0 +1,15 @@+module Hob.Control (+    maybeDo,+    flushEvents+) where++import Control.Monad   (when)+import Graphics.UI.Gtk (eventsPending, mainIteration)++maybeDo :: Monad b => (a -> b ()) -> Maybe a -> b ()+maybeDo = maybe (return())++flushEvents :: IO()+flushEvents = do+    pending <- eventsPending+    when (pending > 0) $ mainIteration >> flushEvents
+ src/lib/Hob/DirectoryTree.hs view
@@ -0,0 +1,54 @@+module Hob.DirectoryTree (+    DirectoryForest,+    DirectoryTreeLoader,+    DirectoryReader,+    IsDirectoryCheck,+    DirectoryTreeElement(..),+    fileTreeGenerator+) where++import Control.Monad   (forM)+import Data.List       (sortBy)+import Data.Tree+import System.FilePath++type IsDirectory = Bool++data DirectoryTreeElement = DirectoryTreeElement { elementLabel :: String, elementPath :: FilePath, isDirectory :: IsDirectory }++instance Show (DirectoryTreeElement) where+  show (DirectoryTreeElement label path isDir) = show label ++" ["++ show path ++"] "++(if isDir then "(directory)" else "(file)")++instance  Eq (DirectoryTreeElement)  where+    (DirectoryTreeElement label path isDir) == (DirectoryTreeElement label' path' isDir') = (label == label') && (path == path') && (isDir == isDir')++type DirectoryForest = Forest DirectoryTreeElement+type DirectoryTreeLoader = FilePath -> IO DirectoryForest+type DirectoryReader = FilePath -> IO [FilePath]+type IsDirectoryCheck = FilePath -> IO Bool++fileTreeGenerator :: DirectoryReader -> IsDirectoryCheck -> DirectoryTreeLoader+fileTreeGenerator getDirectoryContents doesDirectoryExist root = do+    directoryContents <- retrieveDirectoryContents+    forM directoryContents $ \ (name, path, isDir) -> do+        childrenForest <- if isDir then callSelf path else return []+        return $ Node (DirectoryTreeElement name path isDir) childrenForest+    where+        callSelf = fileTreeGenerator getDirectoryContents doesDirectoryExist+        removeBannedDirectories = filter (`notElem` bannedDirectories)+        addFileInfo contents =+            forM contents $ \ child -> do+                let childPath = root </> child+                isDir <- doesDirectoryExist childPath+                return (child, childPath, isDir)+        retrieveDirectoryContents = do+            contents <- getDirectoryContents root+            let filteredContents = removeBannedDirectories contents+            filteredFileInfo <- addFileInfo filteredContents+            return $ sortBy contentsSortCriteria filteredFileInfo+        bannedDirectories = [".", "..", ".git"]+        contentsSortCriteria (name1, _, isDir1) (name2, _, isDir2)+            | isDir1 && not isDir2 = LT+            | isDir2 && not isDir1 = GT+            | otherwise = compare name1 name2+
+ src/lib/Hob/Ui.hs view
@@ -0,0 +1,150 @@+module Hob.Ui (loadGui,+               getActiveEditorText,+               getActiveEditorTab,+               getEditorText,+               getActiveEditor) where++import           Control.Monad.Reader+import           Data.Char                            (intToDigit)+import           Data.IORef+import           Data.List                            (intercalate)+import           Data.Monoid                          (mconcat)+import           Data.Text                            (unpack)+import           Graphics.UI.Gtk+import           Graphics.UI.Gtk.General.CssProvider+import qualified Graphics.UI.Gtk.General.StyleContext as GtkSc+import           GtkExtras.LargeTreeStore             as LTS++import Hob.Command.CloseCurrentTab+import Hob.Command.FindText+import Hob.Command.FocusCommandEntry+import Hob.Command.FocusNextTab+import Hob.Command.FocusNumberedTab+import Hob.Command.FocusPreviousTab+import Hob.Command.FocusSidebar+import Hob.Command.NewTab+import Hob.Command.ReloadSidebarTree+import Hob.Command.ReplaceText+import Hob.Command.SaveCurrentTab+import Hob.Context+import Hob.Context.FileContext+import Hob.Context.StyleContext+import Hob.Context.UiContext+import Hob.Ui.CommandEntry+import Hob.Ui.Editor+import Hob.Ui.Sidebar+import Hob.Ui.SidebarSearch++loadGui :: FileContext -> StyleContext -> IO Context+loadGui fileCtx styleCtx = do+        _ <- initGUI++        builder <- loadUiBuilder+        setGtkStyle styleCtx++        ctx <- initCtx builder defaultCommands+        initMainWindow ctx+        initEditingArea ctx+        initSidebar ctx+        initCommandEntry ctx+        initActiveModesMonitor ctx+        return ctx+    where+        initCtx builder initCommands = do+            window <- builderGetObject builder castToWindow "mainWindow"+            notebook <- builderGetObject builder castToNotebook "tabbedEditArea"+            cmdEntry <- builderGetObject builder castToEntry "command"+            treeView <- builderGetObject builder castToTreeView "directoryListing"+            treeViewSearch <- builderGetObject builder castToEntry "directoryListingSearch"+            activeModesObject <- builderGetObject builder castToLabel "activeMode"+            treeModel <- LTS.treeStoreNew []+            let uiCtx = UiContext window notebook cmdEntry treeView treeViewSearch activeModesObject+            initContext styleCtx fileCtx uiCtx treeModel initCommands++        loadUiBuilder = do+            builder <- builderNew+            builderAddFromFile builder $ uiFile styleCtx+            return builder++        initSidebar ctx = do+            let treeView = sidebarTree . uiContext $ ctx+            let treeViewSearch = sidebarTreeSearch . uiContext $ ctx+            widgetSetName treeView "directoryListing"+            widgetSetName treeViewSearch "sidebarSearchEntry"+            let mainEditNotebook = mainNotebook . uiContext $ ctx+            newSideBarFileTree ctx treeView $ launchNewFileEditor ctx mainEditNotebook+            newSideBarFileTreeSearch ctx++        initCommandEntry ctx = do+            let cmdEntry = commandEntry . uiContext $ ctx+            widgetSetName cmdEntry "commandEntry"+            deferredRunner ctx $ newCommandEntry cmdEntry++        initMainWindow ctx = do+            let window = mainWindow . uiContext $ ctx+            lastPressedKeyRef <- newIORef ""+            widgetSetName window "mainWindow"+            _ <- window `on` keyPressEvent $ do+                modifier <- eventModifier+                keyT <- eventKeyName+                let key = unpack keyT+                liftIO $ writeIORef lastPressedKeyRef key+                if key == "Control_L" then return False+                else invokeKeyCommand ctx (modifier, key)+            _ <- window `on` keyReleaseEvent $ do+                modifier <- eventModifier+                keyT <- eventKeyName+                lastPressedKey <- liftIO $ readIORef lastPressedKeyRef+                let key = unpack keyT+                if (lastPressedKey == key) && (key == "Control_L") then invokeKeyCommand ctx (modifier, key)+                else return False+            return ()++        initEditingArea ctx = do+            let mainEditNotebook = mainNotebook . uiContext $ ctx+            _ <- mainEditNotebook `on` switchPage $ const $ deferredRunner ctx (emitEvent $ Event "core.editor.focused")+            return ()++        invokeKeyCommand ctx command = liftIO . runApp ctx $ do+                                         activeCommands <- getActiveCommands+                                         maybe (return False)+                                           (\cmd -> commandExecute cmd >> return True) $+                                           matchKeyBinding activeCommands command++        initActiveModesMonitor ctx = deferredRunner ctx $ do+            registerEventHandler (Event "core.editor.focused") refreshModesLabel+            registerEventHandler (Event "core.mode.change") refreshModesLabel++        refreshModesLabel = do+            activeCtx <- ask+            modes <- activeModes+            let modesUi = activeModesLabel . uiContext $ activeCtx+            let modesToString = intercalate " | " . filter (not . null) . map modeName+            liftIO $ labelSetText modesUi $ maybe "-" modesToString modes++        defaultCommands = mconcat $ [+                                    createMatcherForKeyBinding ([Control], "w") closeCurrentEditorTab,+                                    createMatcherForKeyBinding ([Control], "s") saveCurrentEditorTab,+                                    createMatcherForKeyBinding ([Control], "n") editNewFileCommandHandler,+                                    createMatcherForKeyBinding ([Control], "r") reloadSidebarTreeCommandHandler,+                                    createMatcherForKeyBinding ([Control], "Tab") focusNextTabCommandHandler,+                                    createMatcherForKeyBinding ([Shift, Control], "Tab") focusPreviousTabCommandHandler,+                                    createMatcherForKeyBinding ([Shift, Control], "ISO_Left_Tab") focusPreviousTabCommandHandler,+                                    createMatcherForKeyBinding ([Control], "t") focusSidebarCommandHandler,+                                    createMatcherForKeyBinding ([Shift, Control], "T") syncFocusSidebarCommandHandler,+                                    createMatcherForPrefix "/" searchCommandHandler,+                                    createMatcherForReplace 's' replaceCommandHandler,+                                    createMatcherForKeyBinding ([Control], "Control_L") focusCommandEntryCommandHandler,+                                    createMatcherForKeyBinding ([], "Escape") focusActiveEditorAndExitLastModeCommandHandler+                                ] +++                                [+                                    createMatcherForKeyBinding ([Control], [intToDigit $ (position + 1) `mod` 10]) $ focusNumberedTabCommandHandler position+                                        | position <- [0..9]+                                ]++setGtkStyle :: StyleContext -> IO ()+setGtkStyle styleCtx = do+    cssProvider <- cssProviderNew+    cssProviderLoadFromPath cssProvider $ uiTheme styleCtx+    maybe (return()) (\screen -> GtkSc.styleContextAddProviderForScreen screen cssProvider 800) =<< screenGetDefault+
+ src/lib/Hob/Ui/CommandEntry.hs view
@@ -0,0 +1,86 @@+module Hob.Ui.CommandEntry (newCommandEntry, newCommandEntryDetached) where++import           Control.Monad.Reader+import           Data.IORef+import           Data.Text                            (unpack)+import           Graphics.UI.Gtk+import qualified Graphics.UI.Gtk.General.StyleContext as GtkSc++import Hob.Context+import Hob.Control++type PreviewResetState = (PreviewCommandHandler -> App(), App())++commandPreviewResetState :: App PreviewResetState+commandPreviewResetState = do+    state <- liftIO $ newIORef Nothing+    return (+        liftIO . writeIORef state . Just,+        do+            resetCommand <- liftIO $ readIORef state+            maybeDo previewReset resetCommand+            liftIO $ writeIORef state Nothing+        )++newCommandEntry :: Entry -> App ()+newCommandEntry cmdEntry = do+    ctx <- ask+    (onChange, onReturn) <- newCommandEntryDetached cmdEntry+    let liftedOn a b c = liftIO $ on a b c+    _ <- cmdEntry `liftedOn` editableChanged $ deferredRunner ctx onChange+    _ <- cmdEntry `liftedOn` keyPressEvent $ do+        modifier <- eventModifier+        key <- eventKeyName+        case (modifier, unpack key) of+            ([], "Return") -> liftIO $ deferredRunner ctx onReturn >> return True+            _ -> return False+    return ()++newCommandEntryDetached :: Entry -> App (App(), App())+newCommandEntryDetached cmdEntry = do+    previewResetState <- commandPreviewResetState+    return (onChanged previewResetState, onReturn previewResetState)+    where+        onChanged =+            previewCmd cmdEntry+        onReturn previewResetState = do+            runCmd cmdEntry previewResetState+            liftIO $ entrySetText cmdEntry ""+++previewCmd :: Entry -> PreviewResetState -> App ()+previewCmd cmdEntry (setLastPreviewCmd, dispatchLastPreviewReset) = do+    dispatchLastPreviewReset+    text <- liftIO $ entryGetText cmdEntry+    if text == "" then+        setOkStatus cmdEntry+    else do+        cmdMatcher <- getActiveCommands+        let command = matchCommand cmdMatcher text+        maybe notifyFailure handleCommand command+    where+        notifyFailure = setErrorStatus cmdEntry+        handleCommand command = do+            setOkStatus cmdEntry+            maybeDo invokePreview $ commandPreview command+        invokePreview prev = do+            previewExecute prev+            setLastPreviewCmd prev++runCmd :: Entry -> PreviewResetState -> App ()+runCmd cmdEntry (_, dispatchLastPreviewReset) = do+    dispatchLastPreviewReset+    text <- liftIO $ entryGetText cmdEntry+    cmdMatcher <- getActiveCommands+    let command = matchCommand cmdMatcher text+    maybeDo commandExecute command++setErrorStatus :: Entry -> App ()+setErrorStatus cmdEntry = do+    cmdEntryStyleContext <- liftIO $ widgetGetStyleContext cmdEntry+    liftIO $ GtkSc.styleContextAddClass cmdEntryStyleContext "error"++setOkStatus :: Entry -> App ()+setOkStatus cmdEntry = do+    cmdEntryStyleContext <- liftIO $ widgetGetStyleContext cmdEntry+    liftIO $ GtkSc.styleContextRemoveClass cmdEntryStyleContext "error"
+ src/lib/Hob/Ui/Editor.hs view
@@ -0,0 +1,217 @@+module Hob.Ui.Editor (+               newEditorForText,+               getActiveEditorText,+               getActiveEditorTab,+               getActiveEditor,+               invokeOnActiveEditor,+               getEditorText,+               getEditorFilePath,+               setEditorFilePath,+               getEditorFromNotebookTab,+               updateEditorTitle+               ) where++import Control.Monad.Reader+import Data.Text                  (Text)+import Filesystem.Path.CurrentOS  (decodeString, encodeString, filename)+import Graphics.UI.Gtk+import Graphics.UI.Gtk.SourceView (SourceDrawSpacesFlags (..), SourceView,+                                   castToSourceView,+                                   sourceBufferBeginNotUndoableAction,+                                   sourceBufferEndNotUndoableAction,+                                   sourceBufferNew,+                                   sourceBufferSetHighlightSyntax,+                                   sourceBufferSetLanguage,+                                   sourceBufferSetStyleScheme,+                                   sourceViewNewWithBuffer,+                                   sourceViewSetAutoIndent,+                                   sourceViewSetDrawSpaces,+                                   sourceViewSetHighlightCurrentLine,+                                   sourceViewSetIndentOnTab,+                                   sourceViewSetIndentWidth,+                                   sourceViewSetInsertSpacesInsteadOfTabs,+                                   sourceViewSetShowLineNumbers,+                                   sourceViewSetTabWidth)+import System.Glib.GObject        (Quark)++import Hob.Context+import Hob.Context.FileContext+import Hob.Context.StyleContext+import Hob.Context.UiContext+import Hob.Control++gtkEditor :: SourceView -> Editor+gtkEditor sourceView = Editor+            { editorId = const . liftIO $ getEditorId sourceView++            , enterEditorMode = \editor mode -> do+                modes <- liftIO $ getEditorModes sourceView+                liftIO $ setEditorModes sourceView $ modes++[mode]+                return editor++            , exitLastEditorMode = \editor -> do+                modes <- liftIO $ getEditorModes sourceView+                if null modes then return editor+                else do+                    cleanup $ last modes+                    liftIO $ setEditorModes sourceView $ init modes+                    return editor++            , modeStack  = const . liftIO $ getEditorModes sourceView++            , isCurrentlyActive = const $ do+                ctx <- ask+                active <- liftIO $ getActiveEditor ctx+                return $ active == Just sourceView+            }++newEditorForText :: Notebook -> Maybe FilePath -> Text -> App ()+newEditorForText targetNotebook filePath text = do+    ctx <- ask+    liftIO $ do+        newId <- idGenerator ctx+        editor <- createNewEditor ctx+        setEditorId editor newId+        setEditorModes editor []+        updateEditors (editors ctx) $ \oldEditors -> return $ oldEditors ++ [gtkEditor editor]+    where+        title = tabTitleForFile filePath+        setBufferLanguage buffer (Just lang) = sourceBufferSetLanguage buffer (Just lang) >> sourceBufferSetHighlightSyntax buffer True+        setBufferLanguage _ Nothing = return()+        createNewEditor ctx = do+            buffer <- sourceBufferNew Nothing+            maybeDo (setBufferLanguage buffer <=< sourceLanguage (fileContext ctx)) filePath++            sourceBufferBeginNotUndoableAction buffer+            textBufferSetText buffer text+            textBufferSetModified buffer False+            sourceBufferEndNotUndoableAction buffer++            sourceBufferSetStyleScheme buffer =<< sourceStyleScheme (styleContext ctx) filePath++            editor <- sourceViewNewWithBuffer buffer+            sourceViewSetShowLineNumbers editor True+            sourceViewSetAutoIndent editor True+            sourceViewSetIndentOnTab editor True+            sourceViewSetIndentWidth editor 4+            sourceViewSetTabWidth editor 4+            sourceViewSetInsertSpacesInsteadOfTabs editor True+            sourceViewSetHighlightCurrentLine editor True+            sourceViewSetDrawSpaces editor SourceDrawSpacesTrailing++            scrolledWindow <- scrolledWindowNew Nothing Nothing+            scrolledWindow `containerAdd` editor++            widgetModifyFont editor =<< sourceStyleFont (styleContext ctx) filePath++            widgetShowAll scrolledWindow+            tabNr <- notebookAppendPage targetNotebook scrolledWindow title+            notebookSetCurrentPage targetNotebook tabNr+            notebookSetShowTabs targetNotebook True++            _ <- buffer `on` modifiedChanged $ notebookSetTabLabelText targetNotebook scrolledWindow =<< tabTitleForEditor editor++            setEditorFilePath editor filePath+            return editor+++getActiveEditorText :: Context -> IO (Maybe Text)+getActiveEditorText ctx = do+    editor <- getActiveEditor ctx+    maybe (return Nothing) ((return . Just) <=< getEditorText) editor++getEditorText :: TextViewClass a => a -> IO Text+getEditorText textEdit = do+    textBuf <- textViewGetBuffer textEdit+    get textBuf textBufferText++getActiveEditor :: Context -> IO (Maybe SourceView)+getActiveEditor = maybe (return Nothing) getEditorFromNotebookTab <=< getActiveEditorTab++invokeOnActiveEditor :: (SourceView -> IO()) -> App ()+invokeOnActiveEditor actions = do+    ctx <- ask+    editor <- liftIO $ getActiveEditor ctx+    liftIO $ maybeDo actions editor++getEditorFromNotebookTab :: Widget -> IO (Maybe SourceView)+getEditorFromNotebookTab currentlyActiveEditor =+    if currentlyActiveEditor `isA` gTypeScrolledWindow then do+        let textEditScroller = castToScrolledWindow currentlyActiveEditor+        textEdit <- binGetChild textEditScroller+        return $ fmap castToSourceView textEdit+    else return Nothing++getActiveEditorTab :: Context -> IO (Maybe Widget)+getActiveEditorTab ctx = do+    pageNum <- notebookGetCurrentPage tabbed+    if pageNum < 0 then+        return Nothing+    else do+        tabs <- containerGetChildren tabbed+        return $ Just $ tabs!!pageNum+    where tabbed = mainNotebook.uiContext $ ctx++tabTitleForFile :: Maybe FilePath -> String+tabTitleForFile (Just filePath) = filename' filePath+    where filename' = encodeString . filename . decodeString+tabTitleForFile Nothing = "(new file)"++tabTitleForEditor :: SourceView -> IO String+tabTitleForEditor editor = do+    filePath <- getEditorFilePath editor+    buffer <- textViewGetBuffer editor+    modified <- buffer `get` textBufferModified+    return $ if modified then tabTitleForFile filePath ++ "*" else tabTitleForFile filePath++setEditorFilePath :: SourceView -> Maybe FilePath -> IO ()+setEditorFilePath editor filePath = do+    quark <- fileNameQuark+    objectSetAttribute quark editor filePath++getEditorFilePath :: SourceView -> IO (Maybe FilePath)+getEditorFilePath editor = do+    quark <- fileNameQuark+    objectGetAttributeUnsafe quark editor++setEditorId :: SourceView -> Int -> IO ()+setEditorId editor identifier = do+    quark <- editorIdQuark+    objectSetAttribute quark editor $ Just identifier++getEditorId :: SourceView -> IO Int+getEditorId editor = do+    quark <- editorIdQuark+    mRet <- objectGetAttributeUnsafe quark editor+    case mRet of+        Just ret -> return ret+        Nothing -> error "editor has no id assigned"++setEditorModes :: SourceView -> [Mode] -> IO ()+setEditorModes editor modes = do+    quark <- editorModesQuark+    objectSetAttribute quark editor $ Just modes++getEditorModes :: SourceView -> IO [Mode]+getEditorModes editor = do+    quark <- editorModesQuark+    mRet <- objectGetAttributeUnsafe quark editor+    case mRet of+        Just ret -> return ret+        Nothing -> error "editor has no modes assigned"++updateEditorTitle :: SourceView -> IO ()+updateEditorTitle editor = do+    Just scrolledW <- widgetGetParent editor+    Just notebookW <- widgetGetParent scrolledW+    let notebook = castToNotebook notebookW+    notebookSetTabLabelText notebook scrolledW =<< tabTitleForEditor editor++fileNameQuark :: IO Quark+fileNameQuark = quarkFromString "fileName"++editorIdQuark :: IO Quark+editorIdQuark = quarkFromString "editorId"++editorModesQuark :: IO Quark+editorModesQuark = quarkFromString "editorModes"
+ src/lib/Hob/Ui/Editor/Search.hs view
@@ -0,0 +1,153 @@+module Hob.Ui.Editor.Search (+        highlightSearchPreview,+        resetSearchPreview,+        findFirstFromCursor,+        findNext,+        findPrevious,+        resetSearch,+        getEditorSearchString,+        startReplace,+        replaceNext,+        resetReplace,+    ) where++import Control.Monad              (when)+import Data.Text                  (pack)+import Graphics.UI.Gtk+import Graphics.UI.Gtk.SourceView (SourceView)+import System.Glib.GObject        (Quark)++import Hob.Control++highlightSearchPreview :: SourceView -> String -> IO()+highlightSearchPreview editor text = do+    buffer <- textViewGetBuffer editor+    tagTable <- textBufferGetTagTable buffer+    tag <- maybe (addNewSearchTag tagTable) return =<< textTagTableLookup tagTable "search"+    (start, end) <- textBufferGetBounds buffer+    addNewSearchTags buffer tag start end+    where+        addNewSearchTag tagTable = do+            tag <- textTagNew $ Just $ pack "search"+            tag `set` [textTagBackground := "#707550"]+            textTagTableAdd tagTable tag+            return tag+        addNewSearchTags buffer tag start end = do+            result <- textIterForwardSearch start text [TextSearchTextOnly] (Just end)+            case result of+                Just (matchStart, matchEnd) -> do+                    textBufferApplyTag buffer tag matchStart matchEnd+                    addNewSearchTags buffer tag matchEnd end+                Nothing -> return()++resetSearch :: SourceView -> IO()+resetSearch editor = do+    setEditorSearchString editor Nothing+    resetSearchPreview editor++resetSearchPreview :: SourceView -> IO()+resetSearchPreview editor = do+    buffer <- textViewGetBuffer editor+    tagTable <- textBufferGetTagTable buffer+    maybeDo (removeEditorTag buffer) =<< textTagTableLookup tagTable "search"+    where+        removeEditorTag buffer tag = do+            (start, end) <- textBufferGetBounds buffer+            textBufferRemoveTag buffer tag start end++findNext :: SourceView -> IO()+findNext editor = do+     searchString <- getEditorSearchString editor+     maybeDo (searchExecute editor) searchString++findPrevious :: SourceView -> IO()+findPrevious editor = do+    searchString <- getEditorSearchString editor+    maybeDo (searchExecuteBackwards editor) searchString++findFirstFromCursor :: SourceView -> String -> IO()+findFirstFromCursor editor text = do+    setEditorSearchString editor $ Just text+    highlightSearchPreview editor text+    searchExecute editor text+++startReplace :: SourceView -> String -> String -> IO()+startReplace editor textFrom textTo = do+    findFirstFromCursor editor textFrom+    setEditorReplaceString editor $ Just textTo++replaceNext :: SourceView -> IO()+replaceNext editor = do+    maybeDo replaceSelectionWith =<< getEditorReplaceString editor+    findNext editor+    where+        replaceSelectionWith replaceText = maybeDo (replaceSearchSelectionWith replaceText) =<< getEditorSearchString editor+        replaceSearchSelectionWith replaceText searchText = do+            buffer <- textViewGetBuffer editor+            (s, e) <- textBufferGetSelectionBounds buffer+            selectedText <- textBufferGetText buffer s e False+            when (searchText == selectedText) $ do+                textBufferDelete buffer s e+                textBufferInsert buffer s replaceText++resetReplace :: SourceView -> IO()+resetReplace editor = do+    resetSearch editor+    setEditorReplaceString editor Nothing+++searchExecute :: SourceView -> String -> IO()+searchExecute editor text = do+    buffer <- textViewGetBuffer editor+    (_, start) <- textBufferGetSelectionBounds buffer+    maybe (retryFromStart buffer) (selectMatch editor buffer) =<< findNextResult start+    where+        findNextResult start = textIterForwardSearch start text [TextSearchTextOnly] Nothing+        retryFromStart buffer = do+            (start, _) <- textBufferGetBounds buffer+            maybeDo (selectMatch editor buffer) =<< findNextResult start++searchExecuteBackwards :: SourceView -> String -> IO()+searchExecuteBackwards editor text = do+    buffer <- textViewGetBuffer editor+    (end, _) <- textBufferGetSelectionBounds buffer+    maybe (retryFromEnd buffer) (selectMatch editor buffer) =<< findPreviousResult end+    where+        findPreviousResult end = textIterBackwardSearch end text [TextSearchTextOnly] Nothing+        retryFromEnd buffer = do+            (_, end) <- textBufferGetBounds buffer+            maybeDo (selectMatch editor buffer) =<< findPreviousResult end++selectMatch :: (TextViewClass tv, TextBufferClass tb) => tv -> tb -> (TextIter, TextIter) -> IO ()+selectMatch editor buffer (start, end) = do+    textBufferSelectRange buffer start end+    caretMark <- textBufferGetInsert buffer+    textViewScrollToMark editor caretMark 0.1 Nothing++setEditorSearchString :: SourceView -> Maybe String -> IO ()+setEditorSearchString editor searchString = do+    quark <- searchStringQuark+    objectSetAttribute quark editor searchString++getEditorSearchString :: SourceView -> IO (Maybe String)+getEditorSearchString editor = do+    quark <- searchStringQuark+    objectGetAttributeUnsafe quark editor++searchStringQuark :: IO Quark+searchStringQuark = quarkFromString "activeSearchString"++setEditorReplaceString :: SourceView -> Maybe String -> IO ()+setEditorReplaceString editor replaceString = do+    quark <- replaceStringQuark+    objectSetAttribute quark editor replaceString++getEditorReplaceString :: SourceView -> IO (Maybe String)+getEditorReplaceString editor = do+    quark <- replaceStringQuark+    objectGetAttributeUnsafe quark editor++replaceStringQuark :: IO Quark+replaceStringQuark = quarkFromString "activeReplaceString"+
+ src/lib/Hob/Ui/Sidebar.hs view
@@ -0,0 +1,108 @@+module Hob.Ui.Sidebar (+    newSideBarFileTree,+    reloadSidebarTree,+    activateSidebarPath,+    syncPathToSidebar,+    nameColumn,+    pathColumn+    ) where++import Control.Monad.Reader+import Data.List                 (isPrefixOf)+import Graphics.UI.Gtk+import Graphics.UI.Gtk.ModelView as Mv+import GtkExtras.LargeTreeStore  as LTS++import Hob.Command.NewTab+import Hob.Context+import Hob.Context.FileContext+import Hob.Context.UiContext+import Hob.Control+import Hob.DirectoryTree++newSideBarFileTree :: Context -> TreeView -> NewFileEditorLauncher -> IO ()+newSideBarFileTree ctx treeView launchFile = do+    let treeStore = fileTreeStore ctx+    runApp ctx reloadSidebarTree+    initNameColumn treeStore++    treeViewSetHeadersVisible treeView False+    treeViewSetEnableSearch treeView False+    treeViewSetModel treeView treeStore++    _ <- treeView `on` rowCollapsed $ \ _ _ -> treeViewColumnsAutosize treeView+    _ <- treeView `on` rowActivated $ \ path _ -> activateRow path =<< LTS.treeStoreGetValue treeStore path++    return ()++    where+        initNameColumn treeStore = do+            customStoreSetColumn treeStore nameColumn elementLabel+            customStoreSetColumn treeStore pathColumn elementPath++            col <- treeViewColumnNew++            rend <- Mv.cellRendererTextNew+            Mv.cellLayoutPackStart col rend True+            Mv.cellLayoutSetAttributes col rend treeStore (\v -> [Mv.cellText := elementLabel v])++            _ <- treeViewAppendColumn treeView col+            return ()++        activateRow :: TreePath -> DirectoryTreeElement -> IO ()+        activateRow path el = if isDirectory el then void $ treeViewExpandRow treeView path False+                              else launchFile . elementPath $ el+++nameColumn :: ColumnId row String+nameColumn = makeColumnIdString 0++pathColumn :: ColumnId row FilePath+pathColumn = makeColumnIdString 1++reloadSidebarTree :: App ()+reloadSidebarTree = do+    ctx <- ask+    let treeStore = fileTreeStore ctx+    let fileCtx = fileContext ctx+    let fileTreeLoader = contextFileTreeLoader fileCtx+    liftIO $ LTS.treeStoreClear treeStore+    liftIO $ LTS.treeStoreInsertForest treeStore [] 0 =<< fileTreeLoader+    emitEvent $ Event "core.sidebar.reload"+++activateSidebarPath :: TreeViewClass tv => tv -> TreePath -> IO ()+activateSidebarPath treeView path = do+    treeViewCollapseAll treeView+    treeViewExpandToPath treeView path+    treeViewSetCursor treeView path Nothing+++++syncPathToSidebar :: FilePath -> App()+syncPathToSidebar filePath = do+    ctx <- ask+    let treeView = sidebarTree.uiContext $ ctx+    liftIO (maybeDo (syncTreeViewModel treeView) =<< treeViewGetModel treeView)+    where+        syncTreeViewModel treeView model = do+            mStartIter <- treeModelGetIterFirst model+            maybeDo (syncToMatchingPath treeView model) mStartIter+        syncToMatchingPath treeView model startingIter =+            maybeDo (syncToIter treeView model) =<< findFilePath model filePath startingIter+        syncToIter treeView model iter = activateSidebarPath treeView =<< treeModelGetPath model iter++findFilePath :: TreeModelClass self =>+                self -> FilePath -> TreeIter -> IO (Maybe TreeIter)+findFilePath model filePath iter = do+        path <- treeModelGetValue model iter pathColumn+        if path == filePath then return $ Just iter+        else if (path++"/") `isPrefixOf` filePath then matchChildren+        else matchNextSibling+    where matchChildren = recurseToMaybeIter =<< treeModelIterChildren model iter+          matchNextSibling = recurseToMaybeIter =<< treeModelIterNext model iter+          recurseToMaybeIter Nothing = return Nothing+          recurseToMaybeIter (Just it) = findFilePath model filePath it++
+ src/lib/Hob/Ui/SidebarSearch.hs view
@@ -0,0 +1,349 @@+module Hob.Ui.SidebarSearch (+        newSideBarFileTreeSearch,+        startSidebarSearch,+        updateSidebarSearch,+        continueSidebarSearch,+        continueSidebarSearchBackwards,+        initFileTreeIndex,+    ) where++import           Control.Concurrent.MVar              (newMVar, readMVar,+                                                       swapMVar)+import           Control.Monad.Reader+import           Data.Char                            (isPrint, toLower)+import           Data.List                            (isPrefixOf, sortBy)+import           Data.Maybe+import           Data.Text                            (unpack)+import           Data.Tree+import qualified Data.Vector                          as V+import           Graphics.UI.Gtk+import           Graphics.UI.Gtk.General.StyleContext (styleContextAddClass,+                                                       styleContextRemoveClass)++import Hob.Context+import Hob.Context.FileContext+import Hob.Context.UiContext+import Hob.Control+import Hob.DirectoryTree+import Hob.Ui.Sidebar++{-| Index based on suffix arrays++The two vectors contain the path element surrounded by slashes '/'+and a sorted symbol positions respectively. The index is generated+by a function 'mkIndex'.++Example:++@+mkIndex "example"+LetterIndex (fromList "/example/") (fromList [0,8,3,1,7,6,4,5,2])+@+-}+data LetterIndex = LetterIndex (V.Vector Char) (V.Vector Int) deriving Show+data SearchIndexNode a = PathNode LetterIndex a (SearchIndex a) | LeafNode LetterIndex a deriving Show+type SearchIndex a = [SearchIndexNode a]++instance Eq a => Eq (SearchIndexNode a) where+    (LeafNode _ a) == (LeafNode _ b) = a == b+    (PathNode _ a _) == (PathNode _ b _) = a == b+    _ == _ = False++type DirectorySearchIndex = SearchIndex DirectoryTreeElement++mkIndex :: String -> LetterIndex+mkIndex s = LetterIndex word indices+     where+        word = V.fromList . map toLower $ '/':s++"/"+        indices = V.fromList . sortBy indexOrdering . take (V.length word) $ [0..]+        indexOrdering i1 i2 = let c1 = word V.! i1+                                  c2 = word V.! i2+                                  cmp = compare c1 c2+                              in if cmp == EQ then compare i1 i2 else cmp++{-| Find all positions for a character -}+findOccurrences :: LetterIndex -> Char -> [Int]+findOccurrences (LetterIndex word idx) c = range mid+    where+        binSearch low high+          | low > high = Nothing+          | value > c = binSearch low (middle-1)+          | value < c = binSearch (middle+1) high+          | otherwise = Just middle+            where+                value = word V.! (idx V.! middle)+                middle = (low + high) `quot` 2++        mid = binSearch 0 (highBound-1)++        startFrom x+          | x < 0 = 0+          | otherwise = if (word V.! (idx V.! x)) == c then startFrom (x-1) else x+1++        endFrom x+          | x == highBound = highBound - 1+          | otherwise = if (word V.! (idx V.! x)) == c then endFrom (x+1) else x-1++        range Nothing = []+        range (Just x) = V.toList . V.slice s (e-s+1) $ idx+            where+                e = endFrom x+                s = startFrom x+        highBound = V.length word++{-| Match query against the index++A query is a list for strings.+Each string is matched as a substring of the given index.+Then the next query string is matched.+Once there is a match failure, the rest of the query is returned as the result.++Example:++@+matchQuery (mkIndex "example") ["/ex", "ple"] = []+matchQuery (mkIndex "example") ["/ex", "pla"] = ["pla"]+matchQuery (mkIndex "example") ["/ex", "pla", "the rest"] = ["pla", "the rest"]+@+-}+matchQuery :: LetterIndex -> [String] -> [String]+matchQuery index@(LetterIndex word _) = match 0+    where+          match _ [] = []+          match from ([]:qs) = match from qs+          match from (q:qs)+            | from > highBound = q:qs+            | otherwise = if null subMatches then q:qs+                          else let from' = head subMatches+                               in match from' qs++                where+                    subMatches = mapMaybe (`matchSubString` q) $ findPossibleStarts from q++          findPossibleStarts _ [] = []+          findPossibleStarts from (c:_) = filter (>=from) . findOccurrences index $ c++          matchSubString from [] = Just from+          matchSubString from (c:cs)+            | from > highBound = Nothing+            | (word V.! from) == c = matchSubString (from+1) cs+            | otherwise = Nothing++          highBound = V.length word - 1++buildIndex :: Forest DirectoryTreeElement -> DirectorySearchIndex+buildIndex = fmap addNode+    where+        addNode Node{rootLabel=element, subForest=children} = if isDirectory element then pathNode else leafNode+            where+                pathNode = PathNode index element (buildIndex children)+                leafNode = LeafNode index element+                index = mkIndex $ elementLabel element++findNextMatch :: DirectorySearchIndex -> FilePath -> [String] -> Maybe DirectoryTreeElement+findNextMatch index previous = findMatch $ filterFromPath index previous++findPreviousMatch :: DirectorySearchIndex -> FilePath -> [String] -> Maybe DirectoryTreeElement+findPreviousMatch index next = findMatch $ filterFromPath (reverseIndex index) next+    where+        reverseIndex = map reverseNode . reverse+            where+                reverseNode n@(LeafNode _ _) = n+                reverseNode (PathNode letterIdx el children) = PathNode letterIdx el $ reverseIndex children++filterFromPath :: DirectorySearchIndex -> FilePath -> DirectorySearchIndex+filterFromPath [] _ = []+filterFromPath (node@(LeafNode _ el):is) path+ | elementPath el == path = node:is+ | otherwise = filterFromPath is path+filterFromPath (node@(PathNode lidx el children):is) path+ | elementPath el == path = node:is+ | (elementPath el ++ "/") `isPrefixOf` path = PathNode lidx el (filterFromPath children path) : is+ | otherwise = filterFromPath is path+++findMatch :: DirectorySearchIndex -> [String] -> Maybe DirectoryTreeElement+findMatch [] _ = Nothing+findMatch (LeafNode idx el : is) queries+ | matchSuccess = Just el+ | otherwise = findMatch is queries+    where matchSuccess = null $ matchQuery idx queries+findMatch (PathNode idx _ children : is) queries = mplus childrenMatch $ findMatch is queries+    where childrenMatch = findMatch children $ matchQuery idx queries++{-| Prepare the query string++Parse the query into a query for matching.++Example:+@+prepareQueries "example" = ["example"]+prepareQueries "exam ple" = ["exam","ple"]+prepareQueries "exam/ple" = ["exam/","/ple"]+prepareQueries "exam//ple" = ["exam/","/","/ple"]+prepareQueries "exam/ ple" = ["exam/","ple"]+@+-}+prepareQueries :: String -> [String]+prepareQueries = concatMap breakSlashes . breakSpaces . map toLower+    where+        breakSpaces s = case break (== ' ') s of+                            ([], []) -> []+                            (a, []) -> [a]+                            ([], ' ':b) -> breakSpaces b+                            (a, ' ':b) -> a : breakSpaces b+                            (a, b) -> a : breakSpaces b+        breakSlashes s = case break (== '/') s of+                            ([], []) -> []+                            (a, []) -> [a]+                            ([], '/':b) -> prependToFirst '/' $ breakSlashes b+                            (a, '/':b) -> (a++"/") : prependToFirst '/' (breakSlashes b)+                            (a, b) -> (a++"/") : prependToFirst '/' (breakSlashes b)+        prependToFirst _ [] = []+        prependToFirst a ([]:xs) = [a]:xs+        prependToFirst a (x@(q:_):xs)+         | a == q = [a]:x:xs+         | otherwise = (a:x):xs++newSideBarFileTreeSearch :: Context -> IO ()+newSideBarFileTreeSearch ctx = do+    let treeView = sidebarTree.uiContext $ ctx+    let searchEntry = sidebarTreeSearch.uiContext $ ctx+    index <- newMVar =<< runApp ctx initFileTreeIndex+    runApp ctx $ registerEventHandler (Event "core.sidebar.reload") (initFileTreeIndex >>= (liftIO . swapMVar index) >> return())+    _ <- treeView `on` keyPressEvent $ do+        key <- eventKeyVal+        maybe (return False) startSearch $ keyToChar key+    _ <- searchEntry `on` editableChanged $ runApp ctx $ liftIO (readMVar index) >>= updateSidebarSearch+    _ <- searchEntry `on` focusOutEvent $ liftIO $ widgetHide searchEntry >> return False+    _ <- searchEntry `on` keyPressEvent $ do+        modifier <- eventModifier+        if Prelude.null modifier then do+            key <- eventKeyName+            case unpack key of+                "Down" -> liftIO $ runApp ctx $ liftIO (readMVar index) >>= continueSidebarSearch >> return True+                "Up" -> liftIO $ runApp ctx $ liftIO (readMVar index) >>= continueSidebarSearchBackwards >> return True+                "Return" -> stopSearchAndActivateResult treeView searchEntry+                _ -> return False+        else return False+    return ()+    where+        startSearch firstChar+            | isPrint firstChar = liftIO $ do+                startSidebarSearch ctx [firstChar]+                return True+            | otherwise = return False+        stopSearchAndActivateResult treeView searchEntry = liftIO $ do+            widgetGrabFocus treeView+            widgetHide searchEntry+            (path, _) <- treeViewGetCursor treeView+            column <- treeViewGetColumn treeView 0+            maybeDo (treeViewRowActivated treeView path) column+            return True++initFileTreeIndex :: App DirectorySearchIndex+initFileTreeIndex = do+    fileCtx <- fromContext fileContext+    nodeForest <- liftIO $ contextFileTreeLoader fileCtx+    return $ buildIndex nodeForest++startSidebarSearch :: Context -> String -> IO ()+startSidebarSearch ctx searchString = do+    let entry = sidebarTreeSearch.uiContext $ ctx+        sidebar = sidebarTree . uiContext $ ctx+        len = length searchString+    treeViewSetCursor sidebar [] Nothing+    entrySetText entry ""+    entrySetText entry searchString+    widgetShow entry+    widgetGrabFocus entry+    editableSelectRegion entry len len++updateSidebarSearch :: DirectorySearchIndex -> App ()+updateSidebarSearch index = invokeOnTreeViewAndModel $ continueSearch index selectNextMatch iterOnSelection+    where+        iterOnSelection treeView model = do+            (path, _) <- liftIO $ treeViewGetCursor treeView+            selectedIter <- liftIO $ treeModelGetIter model path+            maybe (treeModelGetIterFirst model) (return.Just) selectedIter++continueSidebarSearch :: DirectorySearchIndex -> App ()+continueSidebarSearch index = invokeOnTreeViewAndModel $ continueSearch index selectNextMatch iterAfterSelection+    where+        iterAfterSelection treeView model = do+            (path, _) <- treeViewGetCursor treeView+            currentIter <- treeModelGetIter model path+            maybe (return Nothing) (findNextSubtree model) currentIter++continueSidebarSearchBackwards :: DirectorySearchIndex -> App ()+continueSidebarSearchBackwards index = invokeOnTreeViewAndModel $ continueSearch index selectPreviousMatch iterBeforeSelection+    where+        iterBeforeSelection treeView model = do+            (path, _) <- treeViewGetCursor treeView+            currentIter <- treeModelGetIter model path+            maybe (return Nothing) (findPreviousSubtree model) currentIter+++continueSearch :: t2 -> (t2 -> t3 -> Entry -> String -> a -> App()) -> (t1 -> t3 -> IO (Maybe a)) -> t1 -> t3 -> App()+continueSearch index selectMatch selectionIter treeView model = do+    ctx <- ask+    let searchEntry = sidebarTreeSearch.uiContext $ ctx+    searchString <- liftIO $ entryGetText searchEntry+    maybeFirstIter <- liftIO $ selectionIter treeView model+    maybeDo (selectMatch index model searchEntry searchString) maybeFirstIter++invokeOnTreeViewAndModel :: (TreeView -> TreeModel -> App ()) -> App ()+invokeOnTreeViewAndModel fnc = do+    ctx <- ask+    let treeView = sidebarTree.uiContext $ ctx+    model <- liftIO $ treeViewGetModel treeView+    maybeDo (fnc treeView) model++selectNextMatch :: (TreeModelClass tm, EntryClass e) => DirectorySearchIndex -> tm -> e -> String -> TreeIter -> App ()+selectNextMatch index treeModel searchEntry searchString currentIter = do+    path <- liftIO $ treeModelGetValue treeModel currentIter pathColumn+    case findNextMatch index path (prepareQueries searchString) of+        Just match -> do+            liftIO $ unsetErrorState searchEntry+            syncPathToSidebar $ elementPath match+        Nothing -> liftIO $ setErrorState searchEntry++selectPreviousMatch :: (TreeModelClass tm, EntryClass e) => DirectorySearchIndex -> tm -> e -> String -> TreeIter -> App ()+selectPreviousMatch index treeModel searchEntry searchString currentIter = do+    path <- liftIO $ treeModelGetValue treeModel currentIter pathColumn+    case findPreviousMatch index path (prepareQueries searchString) of+        Just match -> do+            liftIO $ unsetErrorState searchEntry+            syncPathToSidebar $ elementPath match+        Nothing -> liftIO $ setErrorState searchEntry++setErrorState :: EntryClass e => e -> IO ()+setErrorState searchEntry = do+    widgetStyleContext <- widgetGetStyleContext searchEntry+    styleContextAddClass widgetStyleContext "error"++unsetErrorState :: EntryClass e => e -> IO ()+unsetErrorState searchEntry = do+    widgetStyleContext <- widgetGetStyleContext searchEntry+    styleContextRemoveClass widgetStyleContext "error"++findNextSubtree :: TreeModelClass treeModel => treeModel -> TreeIter -> IO (Maybe TreeIter)+findNextSubtree model iter = do+    next <- treeModelIterNext model iter+    if isJust next then return next+    else maybe (return Nothing) (findNextSubtree model) =<< treeModelIterParent model iter++findPreviousSubtree :: TreeModelClass treeModel => treeModel -> TreeIter -> IO (Maybe TreeIter)+findPreviousSubtree model iter = do+    prev <- treeModelIterPrevious model iter+    if isJust prev then return prev+    else maybe (return Nothing) (findPreviousSubtree model) =<< treeModelIterParent model iter++treeModelIterPrevious :: TreeModelClass treeModel => treeModel -> TreeIter -> IO (Maybe TreeIter)+treeModelIterPrevious model iter = do+    parent <- treeModelIterParent model iter+    currentPath <- treeModelGetPath model iter+    let nth = last currentPath+    if nth > 0 then treeModelIterNthChild model parent (nth-1)+    else return Nothing+
+ test/Hob/Command/CloseCurrentTabSpec.hs view
@@ -0,0 +1,35 @@+module Hob.Command.CloseCurrentTabSpec (main, spec) where++import Test.Hspec++import Graphics.UI.Gtk++import           Hob.Command.CloseCurrentTab+import           Hob.Command.NewTab          (launchNewFileEditor)+import           Hob.Context+import qualified Hob.Context.UiContext       as HC++import HobTest.Context.Stubbed+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+    describe "close current tab command" $+        it "closes the currently active editor tab" $ do+            ctx <- loadStubbedContext+            launchEditorTab ctx "/xxx/testName.hs"+            runCtxActions ctx $ commandExecute closeCurrentEditorTab+            pagesAfterActivatingDirectory <- getNumberOfEditorPages ctx+            pagesAfterActivatingDirectory `shouldBe` 0++launchEditorTab :: Context -> String -> IO ()+launchEditorTab ctx file = do+    let notebook = HC.mainNotebook . uiContext $ ctx+    launchNewFileEditor ctx notebook file++getNumberOfEditorPages :: Context -> IO Int+getNumberOfEditorPages = notebookGetNPages . HC.mainNotebook . uiContext+
+ test/Hob/Command/FindTextSpec.hs view
@@ -0,0 +1,70 @@+module Hob.Command.FindTextSpec (main, spec) where++import Control.Monad.State (liftIO)+import Data.IORef+import Data.Maybe+import Data.Text           (pack)+import Graphics.UI.Gtk+import Test.Hspec++import           Hob.Command.FindText+import           Hob.Context+import qualified Hob.Context.UiContext as HC+import           Hob.Ui                (getActiveEditor)+import           Hob.Ui.Editor         (newEditorForText)++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+  describe "search command handler" $ do+    it "focuses editor on execute" $ do+      (ctx, _) <- loadGuiAndExecuteSearch+      editorFocused <- widgetGetIsFocus . fromJust =<< getActiveEditor ctx+      editorFocused `shouldBe` True++    it "enters the search mode" $ do+      (ctx, _) <- loadGuiAndExecuteSearch+      ref <- newIORef Nothing+      runCtxActions ctx $ activeModes >>= (liftIO . writeIORef ref)+      modes <- readIORef ref+      (modeName . last . fromJust) modes `shouldBe` "search"++  describe "search reset command on mode exit" $+    it "stops the next search" $ do+      (ctx, buffer) <- loadGuiAndExecuteSearch+      runCtxActions ctx exitLastMode+      runCtxActions ctx $ commandExecute searchNextCommandHandler+      (start, end) <- getSelectionOffsets buffer+      (start, end) `shouldBe` (0, 4)++loadGuiAndPreviewSearch :: IO (Context, TextBuffer)+loadGuiAndPreviewSearch = do+    ctx <- loadDefaultContext+    let notebook = HC.mainNotebook . uiContext $ ctx+    runCtxActions ctx $ newEditorForText notebook Nothing $ pack "text - initial text! text"+    mEditor <- getActiveEditor ctx+    let editor = fromJust mEditor+    runCtxActions ctx $ (previewExecute . fromJust . commandPreview) (searchCommandHandler "text")+    buffer <- textViewGetBuffer editor+    return (ctx, buffer)++loadGuiAndExecuteSearch :: IO (Context, TextBuffer)+loadGuiAndExecuteSearch = do+    (ctx, buffer) <- loadGuiAndPreviewSearch+    runCtxActions ctx $ (previewReset . fromJust . commandPreview) (searchCommandHandler "text")+    iterBufferStart <- textBufferGetIterAtOffset buffer 0+    textBufferSelectRange buffer iterBufferStart iterBufferStart+    runCtxActions ctx $ commandExecute (searchCommandHandler "text")+    return (ctx, buffer)++getSelectionOffsets :: TextBuffer -> IO (Int, Int)+getSelectionOffsets buffer = do+    (iterStart, iterEnd) <- textBufferGetSelectionBounds buffer+    start <- textIterGetOffset iterStart+    end <- textIterGetOffset iterEnd+    return (start, end)
+ test/Hob/Command/FocusCommandEntrySpec.hs view
@@ -0,0 +1,51 @@+module Hob.Command.FocusCommandEntrySpec (main, spec) where++import Data.Maybe+import Graphics.UI.Gtk++import           Hob.Command.FocusCommandEntry+import           Hob.Command.NewTab+import           Hob.Context+import qualified Hob.Context.UiContext         as HC+import           Hob.Ui++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "focus command entry command" $ do+    it "focuses the command entry" $ do+      ctx <- loadDefaultContext+      focused <- toggleFocusOnCommandEntryAndReturnState ctx+      focused `shouldBe` True++    it "focus stays on toggle if there is no editor to focus to" $ do+      ctx <- loadDefaultContext+      runCtxActions ctx $ commandExecute toggleFocusOnCommandEntryCommandHandler+      focused <- toggleFocusOnCommandEntryAndReturnState ctx+      focused `shouldBe` True++    it "focus moves to editor on toggle" $ do+      ctx <- launchNewFile+      runCtxActions ctx $ commandExecute toggleFocusOnCommandEntryCommandHandler+      commandFocused <- toggleFocusOnCommandEntryAndReturnState ctx+      editorFocused <- widgetGetIsFocus . fromJust =<< getActiveEditor ctx+      commandFocused `shouldBe` False+      editorFocused `shouldBe` True++launchNewFile :: IO Context+launchNewFile = do+    ctx <- loadDefaultContext+    runCtxActions ctx editNewFile+    return ctx++toggleFocusOnCommandEntryAndReturnState :: Context -> IO Bool+toggleFocusOnCommandEntryAndReturnState ctx = do+    runCtxActions ctx $ commandExecute toggleFocusOnCommandEntryCommandHandler+    widgetGetIsFocus $ HC.commandEntry . uiContext $ ctx
+ test/Hob/Command/FocusNextTabSpec.hs view
@@ -0,0 +1,54 @@+module Hob.Command.FocusNextTabSpec (main, spec) where++import Control.Monad   (replicateM_)+import Graphics.UI.Gtk++import           Hob.Command.FocusNextTab+import           Hob.Command.NewTab+import           Hob.Context+import qualified Hob.Context.UiContext    as HC++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "focus next tab command" $ do+    it "does not change the state if there are no tabs" $ do+      ctx <- loadGuiWithNTabs 0+      currentPage <- focusNextTab ctx+      currentPage `shouldBe` -1++    it "leaves the first tab focused if there is just one tab" $ do+      ctx <- loadGuiWithNTabs 1+      currentPage <- focusNextTab ctx+      currentPage `shouldBe` 0++    it "focuses the next tab" $ do+      ctx <- loadGuiWithNTabs 2+      notebookSetCurrentPage (HC.mainNotebook . uiContext $ ctx) 0+      currentPage <- focusNextTab ctx+      currentPage `shouldBe` 1++    it "focuses the first tab if the command is invoked on the last tab" $ do+      ctx <- loadGuiWithNTabs 2+      notebookSetCurrentPage (HC.mainNotebook . uiContext $ ctx) 1+      currentPage <- focusNextTab ctx+      currentPage `shouldBe` 0++focusNextTab :: Context -> IO Int+focusNextTab ctx = do+    runCtxActions ctx $ commandExecute focusNextTabCommandHandler+    let notebook = HC.mainNotebook . uiContext $ ctx+    notebookGetCurrentPage notebook++loadGuiWithNTabs :: Int -> IO Context+loadGuiWithNTabs n = do+    ctx <- loadDefaultContext+    replicateM_ n $ runCtxActions ctx editNewFile+    return ctx
+ test/Hob/Command/FocusNumberedTabSpec.hs view
@@ -0,0 +1,43 @@+module Hob.Command.FocusNumberedTabSpec (main, spec) where++import Control.Monad   (replicateM_)+import Graphics.UI.Gtk++import           Hob.Command.FocusNumberedTab+import           Hob.Command.NewTab+import           Hob.Context+import qualified Hob.Context.UiContext        as HC++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "focus numbered tab command" $ do+    it "does not change the state if there is no matching tab" $ do+      ctx <- loadGuiWithNTabs 0+      currentPage <- focusNumberedTab 2 ctx+      currentPage `shouldBe` -1++    it "focuses the numbered tab" $ do+      ctx <- loadGuiWithNTabs 3+      notebookSetCurrentPage (HC.mainNotebook . uiContext $ ctx) 0+      currentPage <- focusNumberedTab 2 ctx+      currentPage `shouldBe` 2++focusNumberedTab :: Int -> Context -> IO Int+focusNumberedTab nr ctx = do+    runCtxActions ctx $ commandExecute (focusNumberedTabCommandHandler nr)+    let notebook = HC.mainNotebook . uiContext $ ctx+    notebookGetCurrentPage notebook++loadGuiWithNTabs :: Int -> IO Context+loadGuiWithNTabs n = do+    ctx <- loadDefaultContext+    replicateM_ n $ runCtxActions ctx editNewFile+    return ctx
+ test/Hob/Command/FocusPreviousTabSpec.hs view
@@ -0,0 +1,54 @@+module Hob.Command.FocusPreviousTabSpec (main, spec) where++import Control.Monad   (replicateM_)+import Graphics.UI.Gtk++import           Hob.Command.FocusPreviousTab+import           Hob.Command.NewTab+import           Hob.Context+import qualified Hob.Context.UiContext        as HC++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "focus previous tab command" $ do+    it "does not change the state if there are no tabs" $ do+      ctx <- loadGuiWithNTabs 0+      currentPage <- focusPreviousTab ctx+      currentPage `shouldBe` -1++    it "leaves the first tab focused if there is just one tab" $ do+      ctx <- loadGuiWithNTabs 1+      currentPage <- focusPreviousTab ctx+      currentPage `shouldBe` 0++    it "focuses the previous tab" $ do+      ctx <- loadGuiWithNTabs 2+      notebookSetCurrentPage (HC.mainNotebook . uiContext $ ctx) 1+      currentPage <- focusPreviousTab ctx+      currentPage `shouldBe` 0++    it "focuses the last tab if the command is invoked on the first tab" $ do+      ctx <- loadGuiWithNTabs 2+      notebookSetCurrentPage (HC.mainNotebook . uiContext $ ctx) 0+      currentPage <- focusPreviousTab ctx+      currentPage `shouldBe` 1++focusPreviousTab :: Context -> IO Int+focusPreviousTab ctx = do+    runCtxActions ctx $ commandExecute focusPreviousTabCommandHandler+    let notebook = HC.mainNotebook . uiContext $ ctx+    notebookGetCurrentPage notebook++loadGuiWithNTabs :: Int -> IO Context+loadGuiWithNTabs n = do+    ctx <- loadDefaultContext+    replicateM_ n $ runCtxActions ctx editNewFile+    return ctx
+ test/Hob/Command/FocusSidebarSpec.hs view
@@ -0,0 +1,55 @@+module Hob.Command.FocusSidebarSpec (main, spec) where++import Graphics.UI.Gtk++import           Hob.Command.FocusSidebar+import           Hob.Context+import qualified Hob.Context.UiContext    as HC++import Test.Hspec++import HobTest.Context.Default+import HobTest.Context.Stubbed+import HobTest.Control+import HobTest.Editor++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "focus sidebar" $ do+    it "focuses the sidebar" $ do+      ctx <- loadDefaultContext+      focused <- focusSidebarAndReturnState ctx+      focused `shouldBe` True++    it "can sync the open editor path in sidebar" $ do+      ctx <- loadStubbedContext+      launchEditorTab ctx "/xxx/a/b"+      path <- syncSidebarAndReturnSelectedPath ctx+      focused <- sidebarFocusState ctx+      path `shouldBe` [0, 0]+      focused `shouldBe` True++    it "can sync the open editor path in sidebar when there is a directory named as the file's basename" $ do+      ctx <- loadStubbedContext+      launchEditorTab ctx "/xxx/a.b"+      path <- syncSidebarAndReturnSelectedPath ctx+      focused <- sidebarFocusState ctx+      path `shouldBe` [1]+      focused `shouldBe` True++sidebarFocusState :: Context -> IO Bool+sidebarFocusState = widgetGetIsFocus . HC.sidebarTree . uiContext++focusSidebarAndReturnState :: Context -> IO Bool+focusSidebarAndReturnState ctx = do+    runCtxActions ctx $ commandExecute focusSidebarCommandHandler+    sidebarFocusState ctx++syncSidebarAndReturnSelectedPath :: Context -> IO TreePath+syncSidebarAndReturnSelectedPath ctx = do+    runCtxActions ctx $ commandExecute syncFocusSidebarCommandHandler+    pos <- treeViewGetCursor . HC.sidebarTree . uiContext $ ctx+    return $ fst pos
+ test/Hob/Command/NewTabSpec.hs view
@@ -0,0 +1,35 @@+module Hob.Command.NewTabSpec (main, spec) where++import Test.Hspec++import Graphics.UI.Gtk++import qualified Hob.Context           as HC+import qualified Hob.Context.UiContext as HC++import HobTest.Context.Stubbed+import HobTest.Editor++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "new tab command" $ do+    it "creates a new unnamed file" $ do+      ctx <- launchNewFile+      pagesAfterActivatingDirectory <- getNumberOfEditorPages ctx+      pagesAfterActivatingDirectory `shouldBe` 1++    it "focuses the tab with the open file if requested to open an already loaded file" $ do+      ctx <- loadStubbedContext+      let notebook = HC.mainNotebook . HC.uiContext $ ctx+      launchEditorTab ctx "/xxx/testName.hs"+      currentPageOfFirstLoadedFile <- notebookGetCurrentPage notebook+      launchEditorTab ctx "/xxx/c"+      pagesBeforeOpeningExistingFile <- notebookGetNPages notebook+      launchEditorTab ctx "/xxx/testName.hs"+      currentPageAfterLoadingTheFirstLoadedFile <- notebookGetCurrentPage notebook+      pagesAfterOpeningExistingFile <- notebookGetNPages notebook+      pagesAfterOpeningExistingFile `shouldBe` pagesBeforeOpeningExistingFile+      currentPageAfterLoadingTheFirstLoadedFile `shouldBe` currentPageOfFirstLoadedFile
+ test/Hob/Command/ReloadSidebarTreeSpec.hs view
@@ -0,0 +1,69 @@+module Hob.Command.ReloadSidebarTreeSpec (main, spec) where++import Data.Maybe+import Data.Tree+import Graphics.UI.Gtk++import           Hob.Command.ReloadSidebarTree+import           Hob.Context+import qualified Hob.Context.FileContext       as HFC+import qualified Hob.Context.UiContext         as HC+import           Hob.DirectoryTree++import Test.Hspec++import HobTest.Context.Stubbed+import HobTest.Control+import HobTest.Sidebar++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "reload sidebar tree command" $ do+    it "loads new items in the tree" $ do+      ctx <- loadStubbedContext+      values <- getDirectoryListingSidebarRootItems ctx+      values `shouldBe` ["a", "a.b", "c", "-"]+      let ctx' = replaceStubbedTree ctx+      runCtxActions ctx' $ commandExecute reloadSidebarTreeCommandHandler+      values' <- getDirectoryListingSidebarRootItems ctx'+      values' `shouldBe` ["b","c"]++    it "reload sidebar search index" $ do+      ctx <- loadStubbedContext+      cursorShouldBeOnAfterSearch ctx "/new/" []+      let ctx' = replaceStubbedTree ctx+      runCtxActions ctx' $ commandExecute reloadSidebarTreeCommandHandler+      cursorShouldBeOnAfterSearch ctx "/new/" [1, 0]++replaceStubbedTree :: Context -> Context+replaceStubbedTree ctx = ctx{fileContext = newFileContext}+    where+        newFileContext = (fileContext ctx){HFC.contextFileTreeLoader = altFileTreeStub}++altFileTreeStub :: IO (Forest DirectoryTreeElement)+altFileTreeStub = return [+    Node (DirectoryTreeElement "b" "/xxx/b" False) [],+    Node (DirectoryTreeElement "c" "/xxx/c" True) [+        Node (DirectoryTreeElement "new" "/xxx/c/new" False) []+    ]]++getDirectoryListingSidebarRootItems :: Context -> IO [String]+getDirectoryListingSidebarRootItems ctx = do+    let treeView = HC.sidebarTree . uiContext $ ctx+    maybeTreeModel <- treeViewGetModel treeView+    let treeModel = fromJust maybeTreeModel+    maybeRoot <- treeModelGetIter treeModel [0]+    getSiblingItems treeModel maybeRoot++getSiblingItems :: TreeModel -> Maybe TreeIter -> IO [String]+getSiblingItems _ Nothing = return []+getSiblingItems treeModel (Just iter) = do+    let colId = makeColumnIdString 0+    value <- treeModelGetValue treeModel iter colId+    siblings <- getSiblingItems treeModel =<< treeModelIterNext treeModel iter+    return $ value : siblings++
+ test/Hob/Command/ReplaceTextSpec.hs view
@@ -0,0 +1,102 @@+module Hob.Command.ReplaceTextSpec (main, spec) where++import Control.Monad.State (liftIO)+import Data.IORef+import Data.Maybe+import Data.Text           (pack)+import Graphics.UI.Gtk+import Test.Hspec++import           Hob.Command.ReplaceText+import           Hob.Context+import qualified Hob.Context.UiContext   as HC+import           Hob.Ui.Editor           (getActiveEditor, newEditorForText)++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+  describe "replace text command matcher" $ do+    it "accepts when command starts with the configured letter" $ do+        let handler _ _ = CommandHandler Nothing (return())+        let matcher = createMatcherForReplace 's' handler+        isJust (matchCommand matcher "s//") `shouldBe` True++    it "does not accept when command starts with another than the configured letter" $ do+        let handler _ _ = CommandHandler Nothing (return())+        let matcher = createMatcherForReplace 's' handler+        isJust (matchCommand matcher "x//") `shouldBe` False++    it "does not accept when command is empty" $ do+        let handler _ _ = CommandHandler Nothing (return())+        let matcher = createMatcherForReplace 's' handler+        isJust (matchCommand matcher "") `shouldBe` False++    it "parses search and replace strings" $ do+        let handler "S" "R" = CommandHandler Nothing (return())+            handler s r = error $ "unexpected invokation with \""++s++ "\" / \""++r++"\""+            matcher = createMatcherForReplace 'x' handler+            matchResult = matchCommand matcher "x/S/R"+        ctx <- loadDefaultContext+        runCtxActions ctx $ commandExecute (fromJust matchResult)++    it "ignores options when parsing search and replace strings" $ do+        let handler "S" "R" = CommandHandler Nothing (return())+            handler s r = error $ "unexpected invokation with \""++s++ "\" / \""++r++"\""+            matcher = createMatcherForReplace 'x' handler+            matchResult = matchCommand matcher "x#S#R#options"+        ctx <- loadDefaultContext+        runCtxActions ctx $ commandExecute (fromJust matchResult)++    it "matches escaped separator char as text" $ do+        let handler "S/S" "R/R" = CommandHandler Nothing (return())+            handler s r = error $ "unexpected invokation with \""++s++ "\" / \""++r++"\""+            matcher = createMatcherForReplace 'x' handler+            matchResult = matchCommand matcher "x/S\\/S/R\\/R"+        ctx <- loadDefaultContext+        runCtxActions ctx $ commandExecute (fromJust matchResult)++    it "matches escaped any char as escape seq and text" $ do+        let handler "S\\xS" "R\\xR" = CommandHandler Nothing (return())+            handler s r = error $ "unexpected invokation with \""++s++ "\" / \""++r++"\""+            matcher = createMatcherForReplace 'x' handler+            matchResult = matchCommand matcher "x/S\\xS/R\\xR"+        ctx <- loadDefaultContext+        runCtxActions ctx $ commandExecute (fromJust matchResult)++    it "matches escaped end of string as text" $ do+        let handler "S" "R\\" = CommandHandler Nothing (return())+            handler s r = error $ "unexpected invokation with \""++s++ "\" / \""++r++"\""+            matcher = createMatcherForReplace 'x' handler+            matchResult = matchCommand matcher "x/S/R\\"+        ctx <- loadDefaultContext+        runCtxActions ctx $ commandExecute (fromJust matchResult)++  describe "replace text command handler" $ do+    it "focuses editor on execute" $ do+        (ctx, _) <- loadGuiWithEditor+        runCtxActions ctx $ commandExecute (replaceCommandHandler "text" ":)")+        editorFocused <- widgetGetIsFocus . fromJust =<< getActiveEditor ctx+        editorFocused `shouldBe` True++    it "sets replace mode" $ do+        (ctx, _) <- loadGuiWithEditor+        runCtxActions ctx $ commandExecute (replaceCommandHandler "text" ":)")+        ref <- newIORef Nothing+        runCtxActions ctx $ activeModes >>= (liftIO . writeIORef ref)+        modes <- readIORef ref+        (map modeName . fromJust) modes `shouldBe` ["replace"]++loadGuiWithEditor :: IO (Context, TextBuffer)+loadGuiWithEditor = do+    ctx <- loadDefaultContext+    let notebook = HC.mainNotebook . uiContext $ ctx+    runCtxActions ctx $ newEditorForText notebook Nothing $ pack "text - initial text! text"+    mEditor <- getActiveEditor ctx+    let editor = fromJust mEditor+    buffer <- textViewGetBuffer editor+    return (ctx, buffer)
+ test/Hob/Command/SaveCurrentTabSpec.hs view
@@ -0,0 +1,108 @@+module Hob.Command.SaveCurrentTabSpec (main, spec) where++import Data.IORef+import Data.Maybe+import Data.Text       (Text, pack)+import Graphics.UI.Gtk++import           Hob.Command.NewTab+import           Hob.Command.SaveCurrentTab+import           Hob.Context+import qualified Hob.Context.FileContext    as HFC+import qualified Hob.Context.StyleContext   as HSC+import qualified Hob.Context.UiContext      as HUC+import           Hob.Control+import           Hob.Ui++import Test.Hspec++import HobTest.Context.Default+import HobTest.Context.Stubbed+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "save current tab command" $ do+    it "saves the currently active file" $ do+      (mockedWriter, mockReader) <- mockedFileWriter+      sc <- HSC.defaultStyleContext "app-data"+      fc <- HFC.defaultFileContext stubbedFileLoader mockedWriter emptyFileTree+      ctx <- launchFileInContext fc sc "/xxx/testName.hs"+      runCtxActions ctx $ saveCurrentEditorTabHandler emptyFileChooser+      savedFile <- mockReader+      savedFile `shouldBe` Just ("/xxx/testName.hs", pack "file contents for /xxx/testName.hs")++    it "skips save when there is no active file" $ do+      sc <- HSC.defaultStyleContext "app-data"+      fc <- HFC.defaultFileContext emptyFileLoader failingFileWriter emptyFileTree+      ctx <- loadGui fc sc+      runCtxActions ctx $ saveCurrentEditorTabHandler emptyFileChooser++    it "marks buffer as unmodified on save" $ do+      sc <- HSC.defaultStyleContext "app-data"+      fc <- HFC.defaultFileContext stubbedFileLoader blackholeFileWriter emptyFileTree+      ctx <- launchFileInContext fc sc "/xxx/testName.hs"+      flushEvents+      buffer <- textViewGetBuffer . fromJust =<< getActiveEditor ctx+      textBufferSetModified buffer True+      runCtxActions ctx $ saveCurrentEditorTabHandler emptyFileChooser+      stateAfterSave <- textBufferGetModified buffer+      stateAfterSave `shouldBe` False++    it "requests filename for a new file" $ do+      (mockedWriter, mockReader) <- mockedFileWriter+      sc <- HSC.defaultStyleContext "app-data"+      fc <- HFC.defaultFileContext emptyFileLoader mockedWriter emptyFileTree+      ctx <- launchNewFileInContextAndSaveAs fc sc "/xxx/fileResponded.hs"+      savedFile <- mockReader+      savedFile `shouldBe` Just ("/xxx/fileResponded.hs", pack "")+      tabText <- getActiveEditorTabText ctx+      tabText `shouldBe` "fileResponded.hs"++    it "updates the tab title from the newly got filepath" $ do+      sc <- HSC.defaultStyleContext "app-data"+      fc <- HFC.defaultFileContext emptyFileLoader blackholeFileWriter emptyFileTree+      ctx <- launchNewFileInContextAndSaveAs fc sc "/xxx/fileResponded.hs"+      buffer <- textViewGetBuffer . fromJust =<< getActiveEditor ctx+      textBufferSetModified buffer True+      tabText <- getActiveEditorTabText ctx+      tabText `shouldBe` "fileResponded.hs*"++launchFileInContext :: HFC.FileContext -> HSC.StyleContext -> String -> IO Context+launchFileInContext fileCtx styleCtx filename = do+    ctx <- loadGui fileCtx styleCtx+    launchEditorTab ctx filename+    return ctx++launchNewFileInContextAndSaveAs :: HFC.FileContext -> HSC.StyleContext -> String -> IO Context+launchNewFileInContextAndSaveAs fileCtx styleCtx filename = do+    ctx <- loadGui fileCtx styleCtx+    runCtxActions ctx editNewFile+    runCtxActions ctx $ saveCurrentEditorTabHandler (stubbedFileChooser $ Just filename)+    return ctx++launchEditorTab :: Context -> String -> IO ()+launchEditorTab ctx file = do+    let notebook = HUC.mainNotebook . uiContext $ ctx+    launchNewFileEditor ctx notebook file++getActiveEditorTabText :: Context  -> IO String+getActiveEditorTabText ctx = do+    let notebook = HUC.mainNotebook . uiContext $ ctx+    currentlyActiveEditor <- getActiveEditorTab ctx+    text <- notebookGetTabLabelText notebook $ fromJust currentlyActiveEditor+    return $ fromJust text++mockedFileWriter :: IO (HFC.FileWriter, IO (Maybe (String, Text)))+mockedFileWriter = do+    recorder <- newIORef Nothing+    return (curry $ writeIORef recorder . Just, readIORef recorder)++stubbedFileChooser :: Maybe FilePath -> NewFileNameChooser+stubbedFileChooser = return++emptyFileChooser :: NewFileNameChooser+emptyFileChooser = stubbedFileChooser Nothing
+ test/Hob/Context/FileContextSpec.hs view
@@ -0,0 +1,23 @@+module Hob.Context.FileContextSpec (main, spec) where++import Graphics.UI.Gtk.SourceView (sourceLanguageGetName)+import Hob.Context.FileContext+import Test.Hspec++import HobTest.Context.Default++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "sourceLanguage" $+    it "guesses language based on the file ending" $ do+      ctx <- stubbedCtx+      Just lang <- sourceLanguage ctx "/tmp/yyy/test.hs"+      name <- sourceLanguageGetName lang+      name `shouldBe` "Haskell"++stubbedCtx :: IO FileContext+stubbedCtx = defaultFileContext emptyFileLoader blackholeFileWriter emptyFileTree+
+ test/Hob/Context/StyleContextSpec.hs view
@@ -0,0 +1,30 @@+module Hob.Context.StyleContextSpec (main, spec) where++import Graphics.UI.Gtk.SourceView (sourceStyleSchemeGetName)+import Hob.Context.StyleContext+import Test.Hspec++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+  describe "uiFile" $+    it "returns prefixed path" $ do+      ctx <- stubbedCtx+      uiFile ctx `shouldBe` "app-data/ui.glade"++  describe "uiTheme" $+    it "returns prefixed path" $ do+      ctx <- stubbedCtx+      uiTheme ctx `shouldBe` "app-data/themes/gtk/default/gtk-dark.css"++  describe "sourceStyleScheme" $+    it "returns source style to use" $ do+      ctx <- stubbedCtx+      Just style <- sourceStyleScheme ctx $ Just "/tmp/yyy/test.hs"+      name <- sourceStyleSchemeGetName style+      name `shouldBe` "Molokai"++stubbedCtx :: IO StyleContext+stubbedCtx = defaultStyleContext "app-data"
+ test/Hob/ContextSpec.hs view
@@ -0,0 +1,276 @@+module Hob.ContextSpec (main, spec) where++import Control.Monad.Reader+import Data.IORef+import Data.Maybe           (fromJust, isJust, isNothing)+import Data.Monoid+import Graphics.UI.Gtk      (Modifier (..))++import Hob.Context++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control+++dummyEditor :: Editor+dummyEditor = Editor+            { editorId = \_ -> return 1+            , enterEditorMode = \editor mode -> do+                    currentModes <- runOnEditor modeStack editor+                    return $ editor{modeStack = \_ -> return (currentModes ++ [mode])}+            , exitLastEditorMode = \editor -> do+                    currentModes <- runOnEditor modeStack editor+                    return $ editor{modeStack = \_ -> return (init currentModes)}+            , modeStack      = \_ -> return []+            , isCurrentlyActive  = \_ -> return True+            }+++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+    describe "command matcher" $ do+        describe "mempty" $ do+            it "does not return any commands on matching a command" $+                expectNoCommandHandler $ matchCommand mempty "/asd"++            it "does not return any commands on matching a key binding" $+                expectNoCommandHandler $ matchKeyBinding mempty ([Control], "S")++        it "combines command matchers on mappend with the identity on the left" $ do+            let matcher = matcherForCommand "test"+            let combinedMatcher = mempty `mappend` matcher+            expectCommandHandler $ matchCommand combinedMatcher "test"++        it "combines key binding matchers on mappend with the identity on the left" $ do+            let matcher = matcherForKeyBinding ([Control], "S")+            let combinedMatcher = mempty `mappend` matcher+            expectCommandHandler $ matchKeyBinding combinedMatcher ([Control], "S")++        it "combines command matchers on mappend with the identity on the right" $ do+            let matcher = matcherForCommand "test"+            let combinedMatcher = matcher `mappend` mempty+            expectCommandHandler $ matchCommand combinedMatcher "test"++        it "combines key binding matchers on mappend with the identity on the right" $ do+            let matcher = matcherForKeyBinding ([Control], "S")+            let combinedMatcher = matcher `mappend` mempty+            expectCommandHandler $ matchKeyBinding combinedMatcher ([Control], "S")++        it "combines command matchers assiciatively" $ do+            let matcher1 = matcherForCommand "test1"+            let matcher2 = matcherForCommand "test2"+            let matcher3 = matcherForCommand "test3"+            let combinedMatcher1 = (matcher1 `mappend` matcher2) `mappend` matcher3+            let combinedMatcher2 = matcher1 `mappend` (matcher2 `mappend` matcher3)+            expectCommandHandler $ matchCommand combinedMatcher1 "test1"+            expectCommandHandler $ matchCommand combinedMatcher1 "test2"+            expectCommandHandler $ matchCommand combinedMatcher1 "test3"+            expectCommandHandler $ matchCommand combinedMatcher2 "test1"+            expectCommandHandler $ matchCommand combinedMatcher2 "test2"+            expectCommandHandler $ matchCommand combinedMatcher2 "test3"+            expectNoCommandHandler $ matchCommand combinedMatcher1 "test"+            expectNoCommandHandler $ matchCommand combinedMatcher2 "test"++        describe "command matcher for prefix" $ do+            it "does not match unknown prefix command" $ do+                let matcher = createMatcherForPrefix "/" $ const emptyHandler+                let matchedHandler = matchCommand matcher "%test text"+                isNothing matchedHandler `shouldBe` True++            it "matches known prefix command" $ do+                handledText <- executeMockedMatcher "/" "/test text"+                handledText `shouldBe` Just "test text"++            it "matches known prefix command with no text" $ do+                handledText <- executeMockedMatcher "/" "/"+                handledText `shouldBe` Just ""++        describe "command matcher for key binding" $ do+            it "does not match unknown key binding" $ do+                let matcher = createMatcherForKeyBinding ([Control], "S") emptyHandler+                let matchedHandler = matchKeyBinding matcher ([Control], "X")+                isNothing matchedHandler `shouldBe` True++            it "matches known key binding" $ do+                ctx <- loadDefaultContext+                (handler, readHandledText) <- recordingHandler+                let matcher = createMatcherForKeyBinding ([Control], "S") $ handler "test"+                let matchedHandler = matchKeyBinding matcher ([Control], "S")+                handledText <- executeRecordingHandler ctx matchedHandler readHandledText+                handledText `shouldBe` Just "test"++        describe "command matcher text command" $ do+            it "does not match unknown text command" $ do+                let matcher = createMatcherForCommand "hi" emptyHandler+                let matchedHandler = matchCommand matcher "ho"+                isNothing matchedHandler `shouldBe` True++            it "matches known command" $ do+                ctx <- loadDefaultContext+                (handler, readHandledText) <- recordingHandler+                let matcher = createMatcherForCommand "hi" $ handler "test"+                let matchedHandler = matchCommand matcher "hi"+                handledText <- executeRecordingHandler ctx matchedHandler readHandledText+                handledText `shouldBe` Just "test"++    describe "app runner" $ do+        it "runs empty monad" $ do+            ctx <- loadDefaultContext+            runCtxActions ctx $ return ()++        it "can defer command execution to IO" $ do+            record <- newIORef (0::Int)+            ctx <- loadDefaultContext+            let countingCommand = liftIO $ modifyIORef record (+1)+            let deferCommand cmd = liftIO $ runCtxActions ctx cmd+            deferCommand (countingCommand >>+                deferCommand (countingCommand >>+                    deferCommand countingCommand))+            invokeCount <- readIORef record+            invokeCount `shouldBe` (3::Int)++    describe "context commands" $ do+        it "returns Nothing for list of modes if there are no editors" $ do+            ctx <- loadContextWithEditors []+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            modes <- getActiveModes ctx+            isNothing modes `shouldBe` True++        it "enters given mode to the active editor" $ do+            ctx <- loadContextWithEditors [dummyEditor]+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            modes <- getActiveModes ctx+            (modeName . last . fromJust) modes `shouldBe` "testmode"++        it "removes mode from the active editor on exitMode" $ do+            ctx <- loadContextWithEditors [dummyEditor]+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            runCtxActions ctx exitLastMode+            modes <- getActiveModes ctx+            (length . fromJust) modes `shouldBe` 0++        it "emits mode change event on entering a mode" $ do+            record <- newIORef False+            ctx <- loadContextWithEditors [dummyEditor]+            runCtxActions ctx $ registerEventHandler (Event "core.mode.change") (liftIO $ writeIORef record True)+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            invoked <- readIORef record+            invoked `shouldBe` True++        it "emits mode change event on exiting a mode" $ do+            record <- newIORef False+            ctx <- loadContextWithEditors [dummyEditor]+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            runCtxActions ctx $ registerEventHandler (Event "core.mode.change") (liftIO $ writeIORef record True)+            runCtxActions ctx exitLastMode+            invoked <- readIORef record+            invoked `shouldBe` True++    describe "active command matcher retriever" $ do+        it "retains base command matcher" $ do+            ctx <- loadContextWithEditors [dummyEditor]+            runCtxActions ctx $ enterMode $ Mode "testmode" mempty $ return()+            commands <- runApp ctx getActiveCommands+            let cmd = matchKeyBinding commands ([Control], "Tab")+            isJust cmd `shouldBe` True++        it "retrieves active mode command matcher" $ do+            ctx <- loadContextWithEditors [dummyEditor]+            readHandledText <- enterRecordingMode ctx "testMode1" "hi" "test"+            handledText <- executeActiveRecordingHandler ctx "hi" readHandledText+            handledText `shouldBe` Just "test"++        it "retrieves last active mode command first" $ do+            ctx <- loadContextWithEditors [dummyEditor]+            _ <- enterRecordingMode ctx "testMode1" "hi" "test1"+            readHandledText <- enterRecordingMode ctx "testMode2" "hi" "test2"+            handledText <- executeActiveRecordingHandler ctx "hi" readHandledText+            handledText `shouldBe` Just "test2"++    describe "event handler support" $ do+        it "invokes a registered handler on fireEvent" $ do+            record <- newIORef False+            ctx <- loadDefaultContext+            runCtxActions ctx $ registerEventHandler (Event "test.event") (liftIO $ writeIORef record True)+            runCtxActions ctx $ emitEvent (Event "test.event")+            invoked <- readIORef record+            invoked `shouldBe` True++        it "does not invoke an event handler with different name" $ do+            record <- newIORef False+            ctx <- loadDefaultContext+            runCtxActions ctx $ registerEventHandler (Event "test.event1") (liftIO $ writeIORef record True)+            runCtxActions ctx $ emitEvent (Event "test.event2")+            invoked <- readIORef record+            invoked `shouldBe` False++loadContextWithEditors :: [Editor] -> IO Context+loadContextWithEditors newEditors = do+    ctx <- loadDefaultContext+    updateEditors (editors ctx) $ const $ return newEditors+    return ctx++getActiveModes :: Context -> IO (Maybe [Mode])+getActiveModes ctx = do+    record <- newIORef Nothing+    runCtxActions ctx $ activeModes >>= (liftIO . writeIORef record . Just)+    Just modes <- readIORef record+    return modes++executeMockedMatcher :: String -> String -> IO (Maybe String)+executeMockedMatcher prefix text = do+    ctx <- loadDefaultContext+    (handler, readHandledText) <- recordingHandler+    let matcher = createMatcherForPrefix prefix handler+    let matchedHandler = matchCommand matcher text+    runCtxActions ctx $ commandExecute $ fromJust matchedHandler+    readHandledText++expectCommandHandler :: Maybe CommandHandler -> Expectation+expectCommandHandler cmdHandler = isNothing cmdHandler `shouldBe` False++expectNoCommandHandler :: Maybe CommandHandler -> Expectation+expectNoCommandHandler cmdHandler = isNothing cmdHandler `shouldBe` True++matcherForCommand :: String -> CommandMatcher+matcherForCommand command = CommandMatcher (const Nothing) $ emptyCommandHandlerForCommand command+    where emptyCommandHandlerForCommand cmd x = if x == cmd then Just emptyHandler else Nothing++matcherForKeyBinding :: KeyboardBinding -> CommandMatcher+matcherForKeyBinding key = CommandMatcher (emptyCommandHandlerForKey key) (const Nothing)+    where emptyCommandHandlerForKey k x = if x == k then Just emptyHandler else Nothing++emptyHandler :: CommandHandler+emptyHandler = CommandHandler Nothing (return())++recordingHandler :: IO (String -> CommandHandler, IO (Maybe String))+recordingHandler = do+    record <- newIORef Nothing+    return (+                \params -> CommandHandler Nothing (liftIO $ writeIORef record $ Just params),+                readIORef record+            )++executeRecordingHandler :: Context -> Maybe CommandHandler -> IO (Maybe String) -> IO (Maybe String)+executeRecordingHandler ctx handler readHandledText = do+    runCtxActions ctx $ commandExecute $ fromJust handler+    readHandledText++executeActiveRecordingHandler :: Context -> String -> IO (Maybe String) -> IO (Maybe String)+executeActiveRecordingHandler ctx cmd readHandledText = do+    commands <- runApp ctx getActiveCommands+    let command = matchCommand commands cmd+    executeRecordingHandler ctx command readHandledText++enterRecordingMode :: Context -> String -> String -> String -> IO (IO (Maybe String))+enterRecordingMode ctx modename cmd resp = do+    (handler, readHandledText) <- recordingHandler+    let matcher = createMatcherForCommand cmd $ handler resp+    runApp ctx $ enterMode $ Mode modename matcher $ return()+    return readHandledText+
+ test/Hob/ControlSpec.hs view
@@ -0,0 +1,30 @@+module Hob.ControlSpec (main, spec) where++import Data.IORef++import Test.Hspec++import Hob.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "maybeDo" $ do+    it "does not execute on Nothing" $ do+        (executor, mockReader) <- mockedExecutor+        maybeDo executor Nothing+        executionStatus <- mockReader+        executionStatus `shouldBe` Nothing++    it "passes unwrapped value on Just" $ do+        (executor, mockReader) <- mockedExecutor+        maybeDo executor $ Just "test value"+        executionStatus <- mockReader+        executionStatus `shouldBe` Just "test value"++mockedExecutor :: IO (String -> IO(), IO (Maybe String))+mockedExecutor = do+    recorder <- newIORef Nothing+    return (writeIORef recorder . Just, readIORef recorder)
+ test/Hob/DirectoryTreeSpec.hs view
@@ -0,0 +1,72 @@+module Hob.DirectoryTreeSpec (main, spec) where++import Control.Monad.Error+import Data.Tree+import Hob.DirectoryTree+import Test.Hspec++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "fileTreeGenerator" $ do+    it "returns directory contents" $ do+        let dirContentsStub _ = return ["nd1", "nd2"]+            isDirStub _ = return False+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx/"+        items `shouldBe` [Node (DirectoryTreeElement "nd1" "/xxx/nd1" False) [],+                          Node (DirectoryTreeElement "nd2" "/xxx/nd2" False) []]++    it "returns sub-directory contents" $ do+        let dirContentsStub "/xxx" = return ["d1"]+            dirContentsStub "/xxx/d1" = return ["nd2"]+            dirContentsStub _ = throwError $ userError "unexpected directory listing"+            isDirStub d = return $ "/xxx/d1" == d+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx"+        items `shouldBe` [Node (DirectoryTreeElement "d1" "/xxx/d1" True) [+                          Node (DirectoryTreeElement "nd2" "/xxx/d1/nd2" False) []]]++    it "hides dot (. | ..) directory contents" $ do+        let dirContentsStub "/xxx" = return ["d1", ".", ".."]+            dirContentsStub "/xxx/d1" = return ["nd2", ".", ".."]+            dirContentsStub _ = throwError $ userError "unexpected directory listing"+            isDirStub d = return $ "/xxx/d1" == d+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx"+        items `shouldBe` [Node (DirectoryTreeElement "d1" "/xxx/d1" True) [+                          Node (DirectoryTreeElement "nd2" "/xxx/d1/nd2" False) []]]+++    it "hides .git directories" $ do+        let dirContentsStub "/xxx" = return ["d1", ".git"]+            dirContentsStub "/xxx/d1" = return ["nd2"]+            dirContentsStub _ = throwError $ userError "unexpected directory listing"+            isDirStub d = return $ "/xxx/d1" == d+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx"+        items `shouldBe` [Node (DirectoryTreeElement "d1" "/xxx/d1" True) [+                          Node (DirectoryTreeElement "nd2" "/xxx/d1/nd2" False) []]]++    it "sorts the directory files" $ do+        let dirContentsStub _ = return ["nd2", "nd1"]+            isDirStub _ = return False+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx/"+        items `shouldBe` [Node (DirectoryTreeElement "nd1" "/xxx/nd1" False) [],+                          Node (DirectoryTreeElement "nd2" "/xxx/nd2" False) []]++    it "sorts the directory subdirectories at the top" $ do+        let dirContentsStub "/xxx/" = return ["nd1", "zd2", "zd1"]+            dirContentsStub _ = return []+            isDirStub "/xxx/zd1" = return True+            isDirStub "/xxx/zd2" = return True+            isDirStub _ = return False+            fileTreeGenerator' = fileTreeGenerator dirContentsStub isDirStub+        items <- fileTreeGenerator' "/xxx/"+        items `shouldBe` [Node (DirectoryTreeElement "zd1" "/xxx/zd1" True) [],+                          Node (DirectoryTreeElement "zd2" "/xxx/zd2" True) [],+                          Node (DirectoryTreeElement "nd1" "/xxx/nd1" False) []]+
+ test/Hob/Ui/CommandEntrySpec.hs view
@@ -0,0 +1,145 @@+module Hob.Ui.CommandEntrySpec (main, spec) where++import Control.Monad.Reader+import Data.IORef+import Graphics.UI.Gtk+import Graphics.UI.Gtk.General.StyleContext++import Hob.Context+import Hob.Context.UiContext+import Hob.Control+import Hob.Ui.CommandEntry++import Test.Hspec++import HobTest.Context.Default+import HobTest.Control++type CommandHandlerReaders = (IO (Maybe String), IO (Maybe String), IO (Maybe String))+type EntryApi = (App(), App())++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "command entry" $ do+    it "is named" $ do+      ctx <- loadDefaultContext+      name <- widgetGetName $ commandEntry . uiContext $ ctx+      name `shouldBe` "commandEntry"++    it "initially there is no error class applied" $ do+      ctx <- loadDefaultContext+      styleCtx <- widgetGetStyleContext $ commandEntry . uiContext $ ctx+      hasErrorClass <- styleContextHasClass styleCtx "error"+      hasErrorClass `shouldBe` False++    it "applies error style class if the command is unknown" $ do+      ctx <- loadDefaultContext+      let entry = commandEntry . uiContext $ ctx+      entrySetText entry "qweqwe"+      styleCtx <- widgetGetStyleContext entry+      flushEvents+      hasErrorClass <- styleContextHasClass styleCtx "error"+      hasErrorClass `shouldBe` True++    it "removes error style on empty command" $ do+      ctx <- loadDefaultContext+      let entry = commandEntry . uiContext $ ctx+      entrySetText entry "not empty"+      styleCtx <- widgetGetStyleContext entry+      styleContextAddClass styleCtx "error"+      entrySetText entry ""+      flushEvents+      hasErrorClass <- styleContextHasClass styleCtx "error"+      hasErrorClass `shouldBe` False++    it "removes error style on known command" $ do+      (ctx, entry, entryApi, _) <- loadDefaultGuiWithMockedCommand+      styleCtx <- widgetGetStyleContext entry+      styleContextAddClass styleCtx "error"+      runCtxActions ctx $ invokePreview entry entryApi "cmd->asd"+      hasErrorClass <- styleContextHasClass styleCtx "error"+      hasErrorClass `shouldBe` False++    it "invokes preview on the command" $ do+      (ctx, entry, entryApi, (_, previewReader, previewResetReader)) <- loadDefaultGuiWithMockedCommand+      runCtxActions ctx $ invokePreview entry entryApi "cmd->asd"+      previewText <- previewReader+      previewResetText <- previewResetReader+      previewText `shouldBe` Just "asd"+      previewResetText `shouldBe` Nothing++    it "resets preview before next preview" $ do+      (ctx, entry, entryApi, (_, previewReader, previewResetReader)) <- loadDefaultGuiWithMockedCommand+      runCtxActions ctx $ invokePreview entry entryApi "cmd->asd"+      runCtxActions ctx $ invokePreview entry entryApi "cmd->as"+      previewText <- previewReader+      previewResetText <- previewResetReader+      previewText `shouldBe` Just "as"+      previewResetText `shouldBe` Just "called"++    it "executes the command" $ do+      (ctx, entry, entryApi, (executeReader, _, _)) <- loadDefaultGuiWithMockedCommand+      runCtxActions ctx $ invokeCommand entry entryApi "cmd->asd"+      executed <- executeReader+      executed `shouldBe` Just "asd"++    it "clears command entry when executing a command" $ do+      (ctx, entry, entryApi, _) <- loadDefaultGuiWithMockedCommand+      runCtxActions ctx $ invokeCommand entry entryApi "cmd->asd"+      text <- entryGetText entry+      text `shouldBe` ""++    it "resets the last preview command before executing a command" $ do+      (ctx, entry, entryApi, (executeReader, _, previewResetReader)) <- loadDefaultGuiWithMockedCommand+      runCtxActions ctx $ invokeCommand entry entryApi "cmd->asd"+      executed <- executeReader+      previewResetText <- previewResetReader+      executed `shouldBe` Just "asd"+      previewResetText `shouldBe` Just "called"++invokePreview :: Entry -> EntryApi -> String -> App ()+invokePreview entry api text = do+    liftIO $ entrySetText entry text+    fst api++invokeCommand :: Entry -> EntryApi -> String -> App ()+invokeCommand entry api text = do+    invokePreview entry api text+    _ <- snd api+    return()++loadDefaultGuiWithMockedCommand :: IO (Context, Entry, EntryApi, CommandHandlerReaders)+loadDefaultGuiWithMockedCommand = do+    defaultCtx <- loadDefaultContext+    (matcher, readHandledCommands) <- mockedMatcher "cmd->"+    let ctx = defaultCtx{baseCommands = matcher}+    entry <- entryNew+    ret <- runApp ctx (newCommandEntryDetached entry)+    return (ctx, entry, ret, readHandledCommands)++mockedMatcher :: String -> IO (CommandMatcher, CommandHandlerReaders)+mockedMatcher prefix = do+    (handler, readHandledCommands) <- recordingHandler+    let matcher = createMatcherForPrefix prefix handler+    return (matcher, readHandledCommands)++recordingHandler :: IO (String -> CommandHandler, CommandHandlerReaders)+recordingHandler = do+    cmd <- newIORef Nothing+    previewCmd <- newIORef Nothing+    previewResetCmd <- newIORef Nothing+    return (+                \params -> CommandHandler+                            (Just $ PreviewCommandHandler+                                (liftIO $ writeIORef previewCmd $ Just params)+                                (liftIO $ writeIORef previewResetCmd $ Just "called"))+                            (liftIO $ writeIORef cmd $ Just params),+                (+                    readIORef cmd,+                    readIORef previewCmd,+                    readIORef previewResetCmd+                )+            )
+ test/Hob/Ui/Editor/SearchSpec.hs view
@@ -0,0 +1,237 @@+module Hob.Ui.Editor.SearchSpec (main, spec) where++import Control.Monad              (replicateM_)+import Data.Maybe+import Data.Text                  (pack)+import Graphics.UI.Gtk+import Graphics.UI.Gtk.SourceView (SourceView)+import Test.Hspec++import           Hob.Context+import qualified Hob.Context.UiContext as HC+import           Hob.Ui.Editor         (getActiveEditor, newEditorForText)+import           Hob.Ui.Editor.Search++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec = do+  describeSearchPreview loadGuiAndPreviewSearch resetSearchPreview+  describeSearchExecute loadGuiAndExecuteSearch findFirstFromCursor+  describeSearchExecute loadGuiAndInitReplace (\editor text -> startReplace editor text "-")++  describe "search for the next match" $ do+    it "highlights the next match from cursor on execute" $ do+      buffer <- loadEditorAndExecuteAfterSearch findNext+      buffer `shouldHaveSelectionOffsets` (15, 19)++    it "wraps the search from start if there are no matches till the end on execute" $ do+      buffer <- loadEditorAndExecuteAfterSearch $ \editor -> replicateM_ 3 $ findNext editor+      buffer `shouldHaveSelectionOffsets` (0, 4)++    it "scrolls to the current match on execute" $ do+      let commands editor = do+            findFirstFromCursor editor "customised search string"+            findNext editor+      ensureCursorVisibleAfter commands++  describe "search reset command on mode exit" $ do+    it "removes all search tags on cleanup" $ do+      buffer <- loadEditorAndExecuteAfterSearch resetSearch+      tagStates <- checkSearchPreviewTagsAtRanges buffer [(0, 4), (15, 19)]+      tagStates `shouldBe` [(False, False), (False, False)]++    it "stops the next search" $ do+      buffer <- loadEditorAndExecuteAfterSearch $ \editor -> resetSearch editor >> findNext editor+      buffer `shouldHaveSelectionOffsets` (0, 4)++  describe "search for the previous match" $ do+    it "highlights the previous match from cursor on execute" $ do+      buffer <- loadEditorAndExecuteAfterSearch $ \editor -> findNext editor >> findPrevious editor+      buffer `shouldHaveSelectionOffsets` (0, 4)++    it "wraps the search from start if there are no matches till the end on execute" $ do+      buffer <- loadEditorAndExecuteAfterSearch findPrevious+      buffer `shouldHaveSelectionOffsets` (21, 25)++    it "scrolls to the current match on execute" $ do+      let commands editor = do+            findFirstFromCursor editor "customised search string"+            findPrevious editor+      ensureCursorVisibleAfter commands++  describe "replace next" $ do+    it "does not replace if there is no highlighted text" $ do+      (ctx, buffer) <- loadGuiWithEditor+      withActiveEditor ctx replaceNext+      buffer `shouldHaveText` "text - initial text! text"++    it "replaces previously highlighted text" $ do+      (ctx, buffer) <- loadGuiAndInitReplace+      withActiveEditor ctx replaceNext+      buffer `shouldHaveText` "New:TEXT:New - initial text! text"++    it "does not replace if the highlighted text doesnt match the search string" $ do+      (ctx, buffer) <- loadGuiAndInitReplace+      (s, _) <- textBufferGetSelectionBounds buffer+      e <- textBufferGetIterAtOffset buffer 7+      textBufferSelectRange buffer s e+      withActiveEditor ctx replaceNext+      buffer `shouldHaveText` "text - initial text! text"++    it "stops the next search" $ do+      (ctx, buffer) <- loadGuiAndInitReplace+      withActiveEditor ctx $ \editor -> do+          resetReplace editor+          findNext editor+      buffer `shouldHaveSelectionOffsets` (0, 4)++    it "stops the next replace" $ do+      (ctx, buffer) <- loadGuiAndInitReplace+      withActiveEditor ctx $ \editor -> do+          resetReplace editor+          findFirstFromCursor editor "text"+          replaceNext editor+      buffer `shouldHaveText` "text - initial text! text"++describeSearchPreview :: IO (Context, TextBuffer) -> (SourceView -> IO ()) -> Spec+describeSearchPreview initializePreview resetFnc =+  describe "search preview for the first match" $ do+    it "creates search tag on preview" $ do+      (_, buffer) <- initializePreview+      tagTable <- textBufferGetTagTable buffer+      tag <- textTagTableLookup tagTable "search"+      isNothing tag `shouldBe` False++    it "applies search tag for matches on preview" $ do+      (_, buffer) <- initializePreview+      tagStates <- checkSearchPreviewTagsAtRanges buffer [(0, 4), (15, 19)]+      tagStates `shouldBe` [(True, True), (True, True)]++    it "removes all search tags on preview reset" $ do+      (ctx, buffer) <- initializePreview+      withActiveEditor ctx resetFnc+      tagStates <- checkSearchPreviewTagsAtRanges buffer [(0, 4), (15, 19)]+      tagStates `shouldBe` [(False, False), (False, False)]++describeSearchExecute :: IO (Context, TextBuffer) -> (SourceView -> String -> IO ()) -> Spec+describeSearchExecute initializeExecute invokeFirstFnc =+  describe "search execute for the first match" $ do+    it "applies search tag for matches on execute" $ do+      (_, buffer) <- initializeExecute+      tagStates <- checkSearchPreviewTagsAtRanges buffer [(0, 4), (15, 19)]+      tagStates `shouldBe` [(True, True), (True, True)]++    it "highlights the first match on execute" $ do+      (_, buffer) <- initializeExecute+      buffer `shouldHaveSelectionOffsets` (0, 4)++    it "highlights the next match from cursor on execute" $ do+      (ctx, buffer) <- initializeExecute+      withActiveEditor ctx (`invokeFirstFnc` "text")+      buffer `shouldHaveSelectionOffsets` (15, 19)++    it "wraps the search from start if there are no matches till the end on execute" $ do+      (ctx, buffer) <- initializeExecute+      withActiveEditor ctx $ \editor -> replicateM_ 3 $ invokeFirstFnc editor "text"+      buffer `shouldHaveSelectionOffsets` (0, 4)++    it "scrolls to the current match on execute" $+      ensureCursorVisibleAfter $ \editor -> invokeFirstFnc editor "customised search string at the end"++shouldHaveSelectionOffsets :: TextBuffer -> (Int, Int) -> IO ()+shouldHaveSelectionOffsets buffer offsets = do+    (start, end) <- getSelectionOffsets buffer+    (start, end) `shouldBe` offsets++shouldHaveText :: TextBuffer -> String -> IO ()+shouldHaveText buffer text = do+    bufferText <- (buffer `get` textBufferText)::IO String+    bufferText `shouldBe` text++loadEditorAndExecuteAfterSearch :: (SourceView -> IO ()) -> IO TextBuffer+loadEditorAndExecuteAfterSearch actions = do+    (ctx, buffer) <- loadGuiAndExecuteSearch+    withActiveEditor ctx actions+    return buffer+++ensureCursorVisibleAfter :: (SourceView -> IO()) -> IO ()+ensureCursorVisibleAfter commands = do+    ctx <- loadDefaultContext+    let notebook = HC.mainNotebook . uiContext $ ctx+    let editorText = (concat . replicate 1000  $ "text - initial text! \n") ++ "customised search string at the end\n"+    runCtxActions ctx $ newEditorForText notebook Nothing $ pack editorText+    processGtkEvents+    withActiveEditor ctx commands+    processGtkEvents+    withActiveEditor ctx $ \editor -> do+        buffer <- textViewGetBuffer editor+        visible <- textViewGetVisibleRect editor+        caretIter <- textBufferGetIterAtMark buffer =<< textBufferGetInsert buffer+        cursor <- textViewGetIterLocation editor caretIter+        isRectangleInside visible cursor `shouldBe` True++loadGuiAndPreviewSearch :: IO (Context, TextBuffer)+loadGuiAndPreviewSearch = do+    ctx <- loadDefaultContext+    let notebook = HC.mainNotebook . uiContext $ ctx+    runCtxActions ctx $ newEditorForText notebook Nothing $ pack "text - initial text! text"+    Just editor <- getActiveEditor ctx+    highlightSearchPreview editor "text"+    buffer <- textViewGetBuffer editor+    return (ctx, buffer)++loadGuiAndExecuteSearch :: IO (Context, TextBuffer)+loadGuiAndExecuteSearch = loadGuiAndExecute $ \editor -> findFirstFromCursor editor "text"++loadGuiAndInitReplace:: IO (Context, TextBuffer)+loadGuiAndInitReplace = loadGuiAndExecute $ \editor -> startReplace editor "text" "New:TEXT:New"++loadGuiWithEditor :: IO (Context, TextBuffer)+loadGuiWithEditor = loadGuiAndExecute $ const $ return ()++loadGuiAndExecute :: (SourceView -> IO()) -> IO (Context, TextBuffer)+loadGuiAndExecute actions = do+    (ctx, buffer) <- loadGuiAndPreviewSearch+    withActiveEditor ctx resetSearchPreview+    iterBufferStart <- textBufferGetIterAtOffset buffer 0+    textBufferSelectRange buffer iterBufferStart iterBufferStart+    withActiveEditor ctx actions+    return (ctx, buffer)++getSelectionOffsets :: TextBuffer -> IO (Int, Int)+getSelectionOffsets buffer = do+    (iterStart, iterEnd) <- textBufferGetSelectionBounds buffer+    start <- textIterGetOffset iterStart+    end <- textIterGetOffset iterEnd+    return (start, end)++checkSearchPreviewTagsAtRanges :: TextBuffer -> [(Int, Int)] -> IO [(Bool, Bool)]+checkSearchPreviewTagsAtRanges buffer ranges = do+      tagTable <- textBufferGetTagTable buffer+      tag <- textTagTableLookup tagTable "search"+      mapM (checkPair tag) ranges+      where checkPair tag (l, r) = do+                iterL <- textBufferGetIterAtOffset buffer l+                iterR <- textBufferGetIterAtOffset buffer r+                checkL <- textIterBeginsTag iterL tag+                checkR <- textIterEndsTag iterR tag+                return (checkL, checkR)++isRectangleInside :: Rectangle -> Rectangle -> Bool+isRectangleInside (Rectangle ax ay aw ah) (Rectangle bx by bw bh) =+    (ax <= bx) && (ay <= by) && (ax+aw >= bx+bw) && (ay+ah >= by+bh)++processGtkEvents :: IO ()+processGtkEvents = replicateM_ 500 $ mainIterationDo False++withActiveEditor :: Context -> (SourceView -> IO b) -> IO b+withActiveEditor ctx actions = do+    Just editor <- getActiveEditor ctx+    actions editor+
+ test/Hob/Ui/EditorSpec.hs view
@@ -0,0 +1,123 @@+module Hob.Ui.EditorSpec (main, spec) where++import Test.Hspec++import Control.Monad.Reader+import Data.IORef+import Data.Maybe+import Data.Monoid+import Data.Text                  (pack, unpack)+import Graphics.UI.Gtk+import Graphics.UI.Gtk.SourceView (SourceView, castToSourceBuffer,+                                   sourceBufferUndo)++import           Hob.Context+import qualified Hob.Context.UiContext as HC+import           Hob.Ui+import           Hob.Ui.Editor++import HobTest.Context.Default+import HobTest.Control++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "editor ui" $ do+    it "does not allow to undo the intial loaded source" $ do+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      buffer <- textViewGetBuffer editor+      sourceBufferUndo $ castToSourceBuffer buffer+      editorText <- getEditorText editor+      unpack editorText `shouldBe` "initial text"++    it "sets the tab title when opening a file" $ do+      ctx <- loadDefaultContext+      _ <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      tabText <- getActiveEditorTabText ctx+      tabText `shouldBe` "testName.hs"++    it "updates the tab title to reflect if buffer is modified" $ do+      ctx <- launchNewFileAndSetModified+      tabText <- getActiveEditorTabText ctx+      tabText `shouldBe` "testName.hs*"++    it "retrieves active editor" $ do+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      activeEditor <- getActiveEditor ctx+      fromJust activeEditor == editor `shouldBe` True++    it "registers the new editor in the context on creation" $ do+      ctx <- loadDefaultContext+      _ <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      registeredEditors <- getEditors $ editors ctx+      length registeredEditors `shouldBe` 1++    it "retrieves editor text" $ do+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      text <- getEditorText editor+      text `shouldBe` pack "initial text"++    it "retrieves active editor text" $ do+      ctx <- loadDefaultContext+      _ <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      text <- getActiveEditorText ctx+      fromJust text `shouldBe` pack "initial text"++    it "retrieves Nothing for active editor text if there is no active editor" $ do+      ctx <- loadDefaultContext+      text <- getActiveEditorText ctx+      text `shouldBe` Nothing++    it "retrieves current editor from notebook" $ do+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      tab <- getActiveEditorTab ctx+      activeEditor <- getEditorFromNotebookTab $ fromJust tab+      fromJust activeEditor == editor `shouldBe` True++    it "retrieves the set filepath for an editor" $ do+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      filePath1 <- getEditorFilePath editor+      setEditorFilePath editor $ Just "/tmp/xxx"+      filePath2 <- getEditorFilePath editor+      filePath1 `shouldBe` Just "/xxx/testName.hs"+      filePath2 `shouldBe` Just "/tmp/xxx"+++    it "invokes mode teardown on exitMode" $ do+      record <- newIORef False+      ctx <- loadDefaultContext+      editor <- launchEditorTab ctx $ Just "/xxx/testName.hs"+      widgetGrabFocus editor+      runCtxActions ctx $ enterMode $ Mode "testmode" mempty (liftIO $ writeIORef record True)+      runCtxActions ctx exitLastMode+      cleanupInvoked <- readIORef record+      cleanupInvoked `shouldBe` True++launchNewFileAndSetModified :: IO Context+launchNewFileAndSetModified = do+    ctx <- loadDefaultContext+    _ <- launchEditorTab ctx $ Just "/xxx/testName.hs"+    buffer <- textViewGetBuffer . fromJust =<< getActiveEditor ctx+    textBufferSetModified buffer True+    return ctx++launchEditorTab :: Context -> Maybe FilePath -> IO SourceView+launchEditorTab ctx file = do+    let notebook = HC.mainNotebook . uiContext $ ctx+    runCtxActions ctx $ newEditorForText notebook file $ pack "initial text"+    mEditor <- getActiveEditor ctx+    return $ fromJust mEditor++getActiveEditorTabText :: Context  -> IO String+getActiveEditorTabText ctx = do+    let notebook = HC.mainNotebook . uiContext $ ctx+    currentlyActiveEditor <- getActiveEditorTab ctx+    text <- notebookGetTabLabelText notebook $ fromJust currentlyActiveEditor+    return $ fromJust text
+ test/Hob/Ui/SidebarSearchSpec.hs view
@@ -0,0 +1,150 @@+module Hob.Ui.SidebarSearchSpec (main, spec) where++import Data.Tree+import Graphics.UI.Gtk++import qualified Hob.Context              as HC+import qualified Hob.Context.FileContext  as HFC+import qualified Hob.Context.StyleContext as HSC+import qualified Hob.Context.UiContext    as HC+import           Hob.DirectoryTree+import           Hob.Ui+import           Hob.Ui.SidebarSearch++import Test.Hspec++import HobTest.Context.Default+import HobTest.Sidebar++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "sidebar search" $ do+    it "shows the named search box" $ do+      ctx <- sideBarSearchContext+      startSidebarSearch ctx ""+      name <- widgetGetName $ HC.sidebarTreeSearch . HC.uiContext $ ctx+      name `shouldBe` "sidebarSearchEntry"++    it "places the cursor on the first match on the search start" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "greenFile" [1]++    it "finds part even if start can be eaten" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "greenFileZ" [6]++    it "places the cursor on the first nested match on the search start" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "redFile" [0, 0]++    it "places the cursor on the first match on the search start even if started from the middle" $ do+      ctx <- sideBarSearchContext+      treeViewSetCursor (HC.sidebarTree . HC.uiContext $ ctx) [1] Nothing+      cursorShouldBeOnAfterSearch ctx "redFile" [0, 0]++    it "places the cursor on the first match again on the search start even if had the same search text before" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "redFile" [0, 0]+      treeViewSetCursor (HC.sidebarTree . HC.uiContext $ ctx) [1] Nothing+      cursorShouldBeOnAfterSearch ctx "redFile" [0, 0]++    it "only looks for the leaf nodes" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "red" [0, 0]++    it "uses fuzzy matching on file name" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "r d e" [0, 0]++    it "uses fuzzy matching on path" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "r dD r r d e" [0, 0]++    it "allows path separator while fuzzy matching on path" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "r/red e" [0, 0]++    it "stays on the same path when search is refined" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "r/r d" [0, 0]+      cursorShouldBeOnAfterRefine ctx "r/r d e" [0, 0]++    it "moves to the new match when search is refined" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearch ctx "r/r d" [0, 0]+      cursorShouldBeOnAfterRefine ctx "r/r d e2" [0, 1]++    it "focuses next file match when requested" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearchAndContinue ctx "r d e" [[0, 0], [0, 1]]++    it "focuses next path match when requested" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearchAndContinue ctx "r/r d e" [[0, 0], [0, 1]]++    it "focuses next multi-level path match when requested" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearchAndContinue ctx "/ Dir//r d e" [[3, 0, 0, 0], [4, 1, 0, 0]]++    it "collapses previously matched path after searching in next subtree" $ do+      ctx <- sideBarSearchContext+      startSidebarSearch ctx "/Dir//r d e"+      idx <- HC.runApp ctx initFileTreeIndex+      HC.runApp ctx $ continueSidebarSearch idx+      expanded <- treeViewRowExpanded (HC.sidebarTree . HC.uiContext $ ctx) [3]+      expanded `shouldBe` False++    it "allows case insensitive search" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearchAndContinue ctx "/ DIR//R D E" [[3, 0, 0, 0], [4, 1, 0, 0]]++    it "finds next top-level file" $ do+      ctx <- sideBarSearchContext+      cursorShouldBeOnAfterSearchAndContinue ctx "green file" [[1], [3,0,0,0], [5]]++    it "applies error style class if there are no matches" $ do+      ctx <- sideBarSearchContext+      startSidebarSearch ctx "AAA!!!AAA"+      ctx `sidebarTreeSearchErrorStateShouldBe` True++    it "removes error style on empty search text" $ do+      ctx <- sideBarSearchContext+      startSidebarSearch ctx "AAA!!!AAA"+      entrySetText (HC.sidebarTreeSearch . HC.uiContext $ ctx) ""+      ctx `sidebarTreeSearchErrorStateShouldBe` False++    it "removes error style on a match" $ do+      ctx <- sideBarSearchContext+      startSidebarSearch ctx "AAA!!!AAA"+      entrySetText (HC.sidebarTreeSearch . HC.uiContext $ ctx) "red"+      ctx `sidebarTreeSearchErrorStateShouldBe` False++sideBarSearchFileTreeStub :: IO (Forest DirectoryTreeElement)+sideBarSearchFileTreeStub = return [+    Node (DirectoryTreeElement "redDir" "/xxx/redDir" True) [+        Node (DirectoryTreeElement "redFile1" "/xxx/redDir/redFile1" False) [],+        Node (DirectoryTreeElement "redFile2" "/xxx/redDir/redFile2" False) []],+    Node (DirectoryTreeElement "greenFile" "/xxx/greenFile" False) [],+    Node (DirectoryTreeElement "redFile" "/xxx/redFile" False) [],+    Node (DirectoryTreeElement "greenDir" "/xxx/greenDir" True) [+        Node (DirectoryTreeElement "greenDir" "/xxx/greenDir/greenDir" True) [+            Node (DirectoryTreeElement "greenDir" "/xxx/greenDir/greenDir/greenDir" True) [+                Node (DirectoryTreeElement "redFile" "/xxx/greenDir/greenDir/greenDir/redFile" False) []]]],+    Node (DirectoryTreeElement "blueFolder" "/xxx/blueFolder" True) [+        Node (DirectoryTreeElement "blueFolder" "/xxx/blueFolder/blueFolder" True) [+            Node (DirectoryTreeElement "blueFolder" "/xxx/blueFolder/blueFolder/blueFolder" True) [+                Node (DirectoryTreeElement "redFile" "/xxx/blueFolder/blueFolder/blueFolder/redFile" False) []]],+        Node (DirectoryTreeElement "blueDir" "/xxx/blueFolder/blueDir" True) [+            Node (DirectoryTreeElement "blueDir" "/xxx/blueFolder/blueDir/blueDir" True) [+                Node (DirectoryTreeElement "redFile" "/xxx/blueFolder/blueDir/blueDir/redFile" False) []]]],+    Node (DirectoryTreeElement "greenFile2" "/xxx/greenFile2" False) [],+    Node (DirectoryTreeElement "greegreenFileZ" "/xxx/greegreenFileZ" False) []]++sideBarSearchContext :: IO HC.Context+sideBarSearchContext = do+    sc <- HSC.defaultStyleContext "app-data"+    fc <- HFC.defaultFileContext emptyFileLoader blackholeFileWriter sideBarSearchFileTreeStub+    loadGui fc sc
+ test/Hob/Ui/SidebarSpec.hs view
@@ -0,0 +1,61 @@+module Hob.Ui.SidebarSpec (main, spec) where++import Data.Maybe+import Data.Text       (unpack)+import Graphics.UI.Gtk++import qualified Hob.Context           as HC+import qualified Hob.Context.UiContext as HC+import           Hob.Control+import           Hob.Ui.Editor++import Test.Hspec++import HobTest.Context.Default+import HobTest.Context.Stubbed++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "sidebar" $ do+    it "is named" $ do+      ctx <- loadDefaultContext+      name <- widgetGetName $ HC.sidebarTree . HC.uiContext $ ctx+      name `shouldBe` "directoryListing"++    it "opens a file editor" $ do+      ctx <- loadStubbedContext+      activateDirectoryPath ctx [2]+      flushEvents+      editorText <- getActiveEditorText ctx+      (unpack . fromJust $ editorText) `shouldBe` "file contents for /xxx/c"++    it "does not open a file editor for directory" $ do+      ctx <- loadStubbedContext+      activateDirectoryPath ctx [0]+      pagesAfterActivatingDirectory <- getNumberOfEditorPages ctx+      pagesAfterActivatingDirectory `shouldBe` 0++    it "expands subtree on directory activation" $ do+      ctx <- loadStubbedContext+      activateDirectoryPath ctx [0]+      expanded <- treeViewRowExpanded (HC.sidebarTree . HC.uiContext $ ctx) [0]+      expanded `shouldBe` True++    it "does not open a file editor for files it cannot read" $ do+      ctx <- loadStubbedContext+      activateDirectoryPath ctx [3]+      pagesAfterActivatingDirectory <- getNumberOfEditorPages ctx+      pagesAfterActivatingDirectory `shouldBe` 0++activateDirectoryPath :: HC.Context -> TreePath -> IO ()+activateDirectoryPath ctx path = do+    let treeView = HC.sidebarTree . HC.uiContext $ ctx+    firstColumn <- treeViewGetColumn treeView 0+    treeViewRowActivated treeView path $ fromJust firstColumn+++getNumberOfEditorPages :: HC.Context -> IO Int+getNumberOfEditorPages = notebookGetNPages . HC.mainNotebook . HC.uiContext
+ test/Hob/UiSpec.hs view
@@ -0,0 +1,21 @@+module Hob.UiSpec (main, spec) where++import Graphics.UI.Gtk++import qualified Hob.Context           as HC+import qualified Hob.Context.UiContext as HC++import Test.Hspec++import HobTest.Context.Default++main :: IO ()+main = hspec spec++spec :: Spec+spec =+  describe "mainWindow" $+    it "is named" $ do+      ctx <- loadDefaultContext+      name <- widgetGetName $ HC.mainWindow . HC.uiContext $ ctx+      name `shouldBe` "mainWindow"
+ test/HobTest/Context/Default.hs view
@@ -0,0 +1,32 @@+module HobTest.Context.Default (+        loadDefaultContext,+        emptyFileTree,+        emptyFileLoader,+        blackholeFileWriter+        ) where++import Data.Text (pack)++import qualified Hob.Context              as HC+import qualified Hob.Context.FileContext  as HFC+import qualified Hob.Context.StyleContext as HSC+import           Hob.Control              (flushEvents)++import Hob.Ui++blackholeFileWriter :: HFC.FileWriter+blackholeFileWriter _ _ = return ()++emptyFileTree :: HFC.FileTreeLoader+emptyFileTree = return []++emptyFileLoader :: HFC.FileLoader+emptyFileLoader _ = return $ Just $ pack ""++loadDefaultContext :: IO HC.Context+loadDefaultContext = do+    sc <- HSC.defaultStyleContext "app-data"+    fc <- HFC.defaultFileContext emptyFileLoader blackholeFileWriter emptyFileTree+    ctx <- loadGui fc sc+    flushEvents+    return ctx
+ test/HobTest/Context/Stubbed.hs view
@@ -0,0 +1,41 @@+module HobTest.Context.Stubbed (+        loadStubbedContext,+        stubbedFileLoader,+        failingFileWriter+        ) where++import Control.Monad.Error (throwError)+import Data.Text           (pack)+import Data.Tree++import qualified Hob.Context              as HC+import qualified Hob.Context.FileContext  as HFC+import qualified Hob.Context.StyleContext as HSC++import Hob.DirectoryTree+import Hob.Ui++fileTreeStub :: IO (Forest DirectoryTreeElement)+fileTreeStub = return [+    Node (DirectoryTreeElement "a" "/xxx/a" True) [+        Node (DirectoryTreeElement "b" "/xxx/a/b" False) []],+    Node (DirectoryTreeElement "a.b" "/xxx/a.b" False) [],+    Node (DirectoryTreeElement "c" "/xxx/c" False) [],+    Node (DirectoryTreeElement "-" "/xxx/cannotRead" False) []]++failingFileWriter :: HFC.FileWriter+failingFileWriter _ _ = throwError $ userError "cannot write files stub"++stubbedFileLoader :: HFC.FileLoader+stubbedFileLoader "/xxx/c" = return $ Just $ pack "file contents for /xxx/c"+stubbedFileLoader "/xxx/a/b" = return $ Just $ pack "file contents for /xxx/a/b"+stubbedFileLoader "/xxx/a.b" = return $ Just $ pack "file contents for /xxx/a.b"+stubbedFileLoader "/xxx/cannotRead" = return Nothing+stubbedFileLoader "/xxx/testName.hs" = return $ Just $ pack "file contents for /xxx/testName.hs"+stubbedFileLoader path = throwError $ userError $ "cannot open unknown file: "++path++loadStubbedContext :: IO HC.Context+loadStubbedContext = do+    sc <- HSC.defaultStyleContext "app-data"+    fc <- HFC.defaultFileContext stubbedFileLoader failingFileWriter fileTreeStub+    loadGui fc sc
+ test/HobTest/Control.hs view
@@ -0,0 +1,11 @@+module HobTest.Control (+    runCtxActions+) where++import Hob.Context+import Hob.Control (flushEvents)++runCtxActions :: Context -> App() -> IO()+runCtxActions ctx actions = do+    deferredRunner ctx actions+    flushEvents
+ test/HobTest/Editor.hs view
@@ -0,0 +1,29 @@+module HobTest.Editor (+    launchNewFile,+    launchEditorTab,+    getNumberOfEditorPages+    ) where++import Graphics.UI.Gtk++import Hob.Command.NewTab+import Hob.Context+import Hob.Context.UiContext++import HobTest.Context.Default+import HobTest.Control++launchNewFile :: IO Context+launchNewFile = do+    ctx <- loadDefaultContext+    runCtxActions ctx $ commandExecute editNewFileCommandHandler+    return ctx++launchEditorTab :: Context -> String -> IO ()+launchEditorTab ctx file = do+    let notebook = mainNotebook . uiContext $ ctx+    launchNewFileEditor ctx notebook file++getNumberOfEditorPages :: Context -> IO Int+getNumberOfEditorPages = notebookGetNPages . mainNotebook . uiContext+
+ test/HobTest/Sidebar.hs view
@@ -0,0 +1,56 @@+module HobTest.Sidebar (+    sidebarTreeSearchErrorStateShouldBe,+    cursorShouldBeOnAfterSearch,+    cursorShouldBeOnAfterRefine,+    cursorShouldBeOnAfterSearchAndContinue,+    cursorShouldBeOn,+    ) where++import Data.Maybe+import Graphics.UI.Gtk+import Graphics.UI.Gtk.General.StyleContext++import qualified Hob.Context           as HC+import qualified Hob.Context.UiContext as HC+import           Hob.Ui.SidebarSearch++import Test.Hspec+++sidebarTreeSearchErrorStateShouldBe :: HC.Context -> Bool -> IO ()+sidebarTreeSearchErrorStateShouldBe ctx state = do+      styleContext <- widgetGetStyleContext $ HC.sidebarTreeSearch . HC.uiContext $ ctx+      hasErrorClass <- styleContextHasClass styleContext "error"+      hasErrorClass `shouldBe` state++cursorShouldBeOnAfterSearch :: HC.Context -> String -> TreePath -> IO ()+cursorShouldBeOnAfterSearch ctx search expectedPath = do+      startSidebarSearch ctx search+      ctx `cursorShouldBeOn` expectedPath++cursorShouldBeOnAfterRefine :: HC.Context -> String -> TreePath -> IO ()+cursorShouldBeOnAfterRefine ctx search expectedPath = do+      entrySetText (HC.sidebarTreeSearch . HC.uiContext $ ctx) search+      ctx `cursorShouldBeOn` expectedPath++cursorShouldBeOnAfterSearchAndContinue :: HC.Context -> String -> [TreePath] -> IO ()+cursorShouldBeOnAfterSearchAndContinue ctx search expectedPaths = do+      startSidebarSearch ctx search+      ctx `cursorShouldBeOn` head expectedPaths+      mapM_ (\path -> do+              idx <- HC.runApp ctx initFileTreeIndex+              HC.runApp ctx $ continueSidebarSearch idx+              ctx `cursorShouldBeOn` path)+            $ tail expectedPaths+      mapM_ (\path -> do+              idx <- HC.runApp ctx initFileTreeIndex+              HC.runApp ctx $ continueSidebarSearchBackwards idx+              ctx `cursorShouldBeOn` path)+            $ reverse $ init expectedPaths++cursorShouldBeOn :: HC.Context -> TreePath -> IO ()+cursorShouldBeOn ctx expectedPath = do+    let sideBar = HC.sidebarTree . HC.uiContext $ ctx+    (path, column) <- treeViewGetCursor sideBar+    path `shouldBe` expectedPath+    isNothing column `shouldBe` True
+ test/Spec.hs view
@@ -0,0 +1,2 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}+