diff --git a/AGPL-3 b/AGPL-3
new file mode 100644
index 0000000000000000000000000000000000000000..0bf239554218124abb28cc3a9618fa2a84757b35
--- /dev/null
+++ b/AGPL-3
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 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 Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are 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.
+
+  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.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  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 Affero 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. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  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 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 work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero 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 Affero 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 Affero 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 Affero 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.
+
+    Pleroma
+    Copyright (C) 2017  Roger Braun
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero 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 Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero 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 your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  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 AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..90a613433cd7e78aaf664f9c997d3a28f14b029e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,32 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+## [Unreleased]
+
+### Changed
+
+- removes "Dashboard" from dropdown menu
+
+### Fixed
+
+- converts maps and structs to JS objects, not array of tuples when wrapping config
+- changes type of IP value from string to number
+
+## [1.0.1] - 2019-08-15
+
+### Fixed
+
+- fixes inputs for renders_errors and rewrite_policy settings
+- removes unnecessary computed properties
+- enables source maps for production build
+
+## [1.0.0] - 2019-08-14
+
+Starting this changelog, for now we have:
+
+- User management system
+- Reports management
+- Pleroma configuration (unstable)
diff --git a/README.md b/README.md
index bf0e08be001c89e33a2cc95a5bc80c505fd2c08b..be1dc34a0922d38eeac6a30f03a56f930325e73d 100644
--- a/README.md
+++ b/README.md
@@ -1,208 +1,14 @@
-<p align="center">
-  <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
-</p>
+# Pleroma AdminFE
 
-<p align="center">
-  <a href="https://github.com/vuejs/vue">
-    <img src="https://img.shields.io/badge/vue-2.5.17-brightgreen.svg" alt="vue">
-  </a>
-  <a href="https://github.com/ElemeFE/element">
-    <img src="https://img.shields.io/badge/element--ui-2.4.11-brightgreen.svg" alt="element-ui">
-  </a>
-  <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
-    <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
-  </a>
-  <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE">
-    <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license">
-  </a>
-  <a href="https://github.com/PanJiaChen/vue-element-admin/releases">
-    <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release">
-  </a>
-  <a href="https://gitter.im/vue-element-admin/discuss">
-    <img src="https://badges.gitter.im/Join%20Chat.svg" alt="gitter">
-  </a>
-  <a href="https://panjiachen.github.io/vue-element-admin-site/donate">
-    <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate">
-  </a>
-</p>
+![screenshot](./public/index.png)
 
-English | [简体中文](./README.zh-CN.md)
+## About
 
-## Introduction
-
-[vue-element-admin](http://panjiachen.github.io/vue-element-admin) is a front-end management background integration solution. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element](https://github.com/ElemeFE/element).
-
-It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
-
-- [Preview](http://panjiachen.github.io/vue-element-admin)
-
-- [Documentation](https://panjiachen.github.io/vue-element-admin-site/)
-
-- [Gitter](https://gitter.im/vue-element-admin/discuss)
-
-- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
-
-- [Donate](https://panjiachen.github.io/vue-element-admin-site/donate/)
-
-- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 国内用户可访问该地址在线预览
-
-**This project is positioned as a background integration solution and is not suitable for secondary development as a basic template.**
-
-- Base template recommends using: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
-- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
-- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
-
-**This project does not support low version browsers (e.g. IE). Please add polyfill yourself if you need them.**
-
-**Note: This project uses element-ui@2.3.0+ version, so the minimum compatible vue@2.5.0+**
-
-**Start using `webpack4` from `v3.8.0`. If you still want to continue using `webpack3`, please use this branch [webpack3](https://github.com/PanJiaChen/vue-element-admin/tree/webpack3)**
-
-## Preparation
-
-You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](http://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
-Understanding and learning this knowledge in advance will greatly help the use of this project.
-
----
-
- <p align="center">
-  <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
-</p>
-
-## Sponsors
-Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
-
-<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
-
-## Features
-
-```
-- Login / Logout
-
-- Permission Authentication
-  - Page permission
-  - Directive permission
-  - Two-step login
-
-- Multi-environment build
-  - dev sit stage prod
-
-- Global Features
-  - I18n
-  - Multiple dynamic themes
-  - Dynamic sidebar (supports multi-level routing)
-  - Dynamic breadcrumb
-  - Tags-view (Tab page Support right-click operation)
-  - Svg Sprite
-  - Mock data
-  - Screenfull
-  - Responsive Sidebar
-
-- Editor
-  - Rich Text Editor
-  - Markdown Editor
-  - JSON Editor
-
-- Excel
-  - Export Excel
-  - Export zip
-  - Upload Excel
-  - Visualization Excel
-
-- Table
-  - Dynamic Table
-  - Drag And Drop Table
-  - Tree Table
-  - Inline Edit Table
-
-- Error Page
-  - 401
-  - 404
-
-- Components
-  - Avatar Upload
-  - Back To Top
-  - Drag Dialog
-  - Drag Select
-  - Drag Kanban
-  - Drag List
-  - SplitPane
-  - Dropzone
-  - Sticky
-  - CountTo
-
-- Advanced Example
-- Error Log
-- Dashboard
-- Guide Page
-- ECharts
-- Clipboard
-- Markdown to html
-```
-
-## Getting started
-
-```bash
-# clone the project
-git clone https://github.com/PanJiaChen/vue-element-admin.git
-
-# install dependency
-npm install
-
-# develop
-npm run dev
-```
-
-This will automatically open http://localhost:9527.
-
-## Build
-
-```bash
-# build for test environment
-npm run build:sit
-
-# build for production environment
-npm run build:prod
-```
-
-## Advanced
-
-```bash
-# --report to build with bundle size analytics
-npm run build:prod --report
-
-# --generate a bundle size analytics. default: bundle-report.html
-npm run build:prod --generate_report
-
-# --preview to start a server in local to preview
-npm run build:prod --preview
-
-# lint code
-npm run lint
-
-# auto fix
-npm run lint -- --fix
-```
-
-Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+Admin UI for pleroma instance owners
 
 ## Changelog
 
-Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
-
-## Online Demo
-
-[Preview](http://panjiachen.github.io/vue-element-admin)
-
-## Donate
-
-If you find this project useful, you can buy author a glass of juice :tropical_drink:
-
-![donate](https://wpimg.wallstcn.com/bd273f0d-83a0-4ef2-92e1-9ac8ed3746b9.png)
-
-[Paypal Me](https://www.paypal.me/panfree23)
-
-[Buy me a coffee](https://www.buymeacoffee.com/Pan)
+Detailed changes for each release are documented in the [CHANGELOG](./CHANGELOG.md).
 
 ## Browsers support
 
@@ -214,6 +20,6 @@ Modern browsers and Internet Explorer 10+.
 
 ## License
 
-[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
+Pleroma AdminFE is build on top of the [Vue Element Admin](https://github.com/PanJiaChen/vue-element-admin), which is licensed under [MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) license.
 
-Copyright (c) 2017-present PanJiaChen
+AdminFE's own code is licensed under [AGPL](./AGPL-3)
diff --git a/README.png b/README.png
new file mode 100644
index 0000000000000000000000000000000000000000..60cd98e322a18fcdd9372b0948faf52529ff1404
Binary files /dev/null and b/README.png differ
diff --git a/README.zh-CN.md b/README.zh-CN.md
deleted file mode 100644
index 5dc9f1d738d2dbe3677bf67176ca6a05e77bcb9b..0000000000000000000000000000000000000000
--- a/README.zh-CN.md
+++ /dev/null
@@ -1,233 +0,0 @@
-<p align="center">
-  <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
-</p>
-
-<p align="center">
-  <a href="https://github.com/vuejs/vue">
-    <img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
-  </a>
-  <a href="https://github.com/ElemeFE/element">
-    <img src="https://img.shields.io/badge/element--ui-2.4.11-brightgreen.svg" alt="element-ui">
-  </a>
-  <a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
-    <img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
-  </a>
-  <a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE">
-    <img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license">
-  </a>
-  <a href="https://github.com/PanJiaChen/vue-element-admin/releases">
-    <img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release">
-  </a>
-  <a href="https://gitter.im/vue-element-admin/discuss">
-    <img src="https://badges.gitter.im/Join%20Chat.svg" alt="gitter">
-  </a>
-  <a href="https://panjiachen.gitee.io/vue-element-admin-site/zh/donate">
-    <img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate">
-  </a>
-</p>
-
-简体中文 | [English](./README.md)
-
-## 简介
-
-[vue-element-admin](http://panjiachen.github.io/vue-element-admin) 是一个后台集成解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element](https://github.com/ElemeFE/element)。它使用了最新的前端技术栈,内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
-
-- [在线访问](http://panjiachen.github.io/vue-element-admin)
-
-- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
-
-- [Gitter 讨论组](https://gitter.im/vue-element-admin/discuss)
-
-- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
-
-- [Donate](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate)
-
-- [Gitee](https://panjiachen.gitee.io/vue-element-admin/) 国内用户可访问该地址在线预览
-
-- [国内访问文档](https://panjiachen.gitee.io/vue-element-admin-site/zh/) 方便没翻墙的用户查看文档
-
-**本项目的定位是后台集成方案,不适合当基础模板来开发。**
-
-- 模板建议使用: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
-- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
-- Typescript版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
-
-群主 **[圈子](https://jianshiapp.com/circles/1209)** 楼主会经常分享一些技术相关的东西,或者加入[qq 群](https://github.com/PanJiaChen/vue-element-admin/issues/602)
-
-**注意:该项目使用 element-ui@2.3.0+ 版本,所以最低兼容 vue@2.5.0+**
-
-**从`v3.8.0`开始使用`webpack4`。所以若还想使用`webpack3`开发,请使用该分支[webpack3](https://github.com/PanJiaChen/vue-element-admin/tree/webpack3)**
-
-**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
-
-## 前序准备
-
-你需要在本地安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。本项目技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 、[axios](https://github.com/axios/axios) 和 [element-ui](https://github.com/ElemeFE/element),所有的请求数据都使用[Mock.js](https://github.com/nuysoft/Mock)模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。
-
-同时配套一个系列的教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目
-
-- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
-- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
-- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
-- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
-- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
-- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
-- [手摸手,带你用合理的姿势使用 webpack4(上)](https://juejin.im/post/5b56909a518825195f499806)
-- [手摸手,带你用合理的姿势使用 webpack4(下)](https://juejin.im/post/5b5d6d6f6fb9a04fea58aabc)
-
-**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
-
- <p align="center">
-  <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
-</p>
-
-## Sponsors
-Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
-
-<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
-
-## 功能
-
-```
-- 登录 / 注销
-
-- 权限验证
-  - 页面权限
-  - 指令权限
-  - 二步登录
-
-- 多环境发布
-  - dev sit stage prod
-
-- 全局功能
-  - 国际化多语言
-  - 多种动态换肤
-  - 动态侧边栏(支持多级路由嵌套)
-  - 动态面包屑
-  - 快捷导航(标签页)
-  - Svg Sprite 图标
-  - 本地mock数据
-  - Screenfull全屏
-  - 自适应收缩侧边栏
-
-- 编辑器
-  - 富文本
-  - Markdown
-  - JSON 等多格式
-
-- Excel
-  - 导出excel
-  - 导出zip
-  - 导入excel
-  - 前端可视化excel
-
-- 表格
-  - 动态表格
-  - 拖拽表格
-  - 树形表格
-  - 内联编辑
-
-- 错误页面
-  - 401
-  - 404
-
-- 組件
-  - 头像上传
-  - 返回顶部
-  - 拖拽Dialog
-  - 拖拽Select
-  - 拖拽看板
-  - 列表拖拽
-  - SplitPane
-  - Dropzone
-  - Sticky
-  - CountTo
-
-- 综合实例
-- 错误日志
-- Dashboard
-- 引导页
-- ECharts 图表
-- Clipboard(剪贴复制)
-- Markdown2html
-```
-
-## 开发
-
-```bash
-# 克隆项目
-git clone https://github.com/PanJiaChen/vue-element-admin.git
-
-# 安装依赖
-npm install
-
-# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
-npm install --registry=https://registry.npm.taobao.org
-
-# 启动服务
-npm run dev
-```
-
-浏览器访问 http://localhost:9527
-
-## 发布
-
-```bash
-# 构建测试环境
-npm run build:sit
-
-# 构建生产环境
-npm run build:prod
-```
-
-## 其它
-
-```bash
-# --report to build with bundle size analytics
-npm run build:prod
-
-# --generate a bundle size analytics. default: bundle-report.html
-npm run build:prod --generate_report
-
-# --preview to start a server in local to preview
-npm run build:prod --preview
-
-# lint code
-npm run lint
-
-# auto fix
-npm run lint -- --fix
-```
-
-更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
-
-## Changelog
-
-Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
-
-## Online Demo
-
-[在线 Demo](http://panjiachen.github.io/vue-element-admin)
-
-## Donate
-
-如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 :tropical_drink:
-![donate](https://panjiachen.github.io/donate/donation.png)
-
-[更多捐赠方式](https://panjiachen.gitee.io/vue-element-admin-site/zh/donate)
-
-[Paypal Me](https://www.paypal.me/panfree23)
-
-## Browsers support
-
-Modern browsers and Internet Explorer 10+.
-
-| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
-| --------- | --------- | --------- | --------- |
-| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
-
-## License
-
-[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
-
-Copyright (c) 2017-present PanJiaChen
diff --git a/config/index.js b/config/index.js
index 7043ee1837a7780187684cc4d6ad71abcc6a71c3..4bc4774497652eb9e3bcb6773f9a3d66cc3a7baf 100644
--- a/config/index.js
+++ b/config/index.js
@@ -65,7 +65,7 @@ module.exports = {
     /**
      * Source Maps
      */
-    productionSourceMap: false,
+    productionSourceMap: true,
     // https://webpack.js.org/configuration/devtool/#production
     devtool: 'source-map',
 
diff --git a/public/index.png b/public/index.png
new file mode 100644
index 0000000000000000000000000000000000000000..aba12e40342e384c456128d567485d08646db950
Binary files /dev/null and b/public/index.png differ
diff --git a/src/lang/index.js b/src/lang/index.js
index 7c9c8af67b11b1710df43bd3735500228d43ec93..6656aeab09bd0bb8ea1271d78f994f71b0628e1c 100644
--- a/src/lang/index.js
+++ b/src/lang/index.js
@@ -2,11 +2,12 @@ import Vue from 'vue'
 import VueI18n from 'vue-i18n'
 import Cookies from 'js-cookie'
 import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
-import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
-import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang
+import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN' // element-ui lang
+import elementEsLocale from 'element-ui/lib/locale/lang/es' // element-ui lang
 import enLocale from './en'
 import zhLocale from './zh'
 import esLocale from './es'
+import ocLocale from './oc'
 
 Vue.use(VueI18n)
 
@@ -22,12 +23,15 @@ const messages = {
   es: {
     ...esLocale,
     ...elementEsLocale
+  },
+  oc: {
+    ...ocLocale
   }
 }
 
 const i18n = new VueI18n({
   // set locale
-  // options: en | zh | es
+  // options: en | zh | es | oc
   locale: Cookies.get('language') || 'en',
   // set locale messages
   messages
diff --git a/src/lang/oc.js b/src/lang/oc.js
new file mode 100644
index 0000000000000000000000000000000000000000..7f9b136bb3cdcd7c8cd34d80e9d12ba9e8b2a094
--- /dev/null
+++ b/src/lang/oc.js
@@ -0,0 +1,161 @@
+export default {
+  route: {
+    dashboard: 'Tablèu de bòrd',
+    introduction: 'Introduccion',
+    documentation: 'Documentacion',
+    guide: 'Guida',
+    permission: 'Autorizacions',
+    pagePermission: 'Pagina d’autorizacion',
+    directivePermission: 'Politica d’autorizacion',
+    icons: 'Icònas',
+    components: 'Compausants',
+    componentIndex: 'Introduccion',
+    tinymce: 'Tinymce',
+    markdown: 'Markdown',
+    jsonEditor: 'JSON Editor',
+    dndList: 'Dnd List',
+    splitPane: 'SplitPane',
+    avatarUpload: 'Mandadís d’avatar',
+    dropzone: 'Dropzone',
+    sticky: 'Sticky',
+    countTo: 'CountTo',
+    componentMixin: 'Mixin',
+    backToTop: 'BackToTop',
+    dragDialog: 'Drag Dialog',
+    dragSelect: 'Drag Select',
+    dragKanban: 'Drag Kanban',
+    charts: 'Charts',
+    keyboardChart: 'Keyboard Chart',
+    lineChart: 'Line Chart',
+    mixChart: 'Mix Chart',
+    example: 'Exemple',
+    nested: 'Rotas imbricadas',
+    menu1: 'Menú 1',
+    'menu1-1': 'Menu 1-1',
+    'menu1-2': 'Menu 1-2',
+    'menu1-2-1': 'Menu 1-2-1',
+    'menu1-2-2': 'Menu 1-2-2',
+    'menu1-3': 'Menu 1-3',
+    menu2: 'Menú 2',
+    Table: 'Tablèu',
+    dynamicTable: 'Tablèu dinamic',
+    dragTable: 'Drag Table',
+    inlineEditTable: 'Inline Edit',
+    complexTable: 'Tablèu complèx',
+    treeTable: 'Arborescéncia',
+    customTreeTable: 'Arborescéncia personalizada',
+    tab: 'Onglet',
+    form: 'Formulari',
+    createArticle: 'Crear un article',
+    editArticle: 'Modificar l’article',
+    articleList: 'Lista d’articles',
+    errorPages: 'Paginas d’error',
+    page401: '401',
+    page404: '404',
+    errorLog: 'Jornal d’error',
+    excel: 'Excel',
+    exportExcel: 'Exportacion Excel',
+    selectExcel: 'Exportar los seleccionats',
+    uploadExcel: 'Importacion Excel',
+    zip: 'Zip',
+    pdf: 'PDF',
+    exportZip: 'Exportacion Zip',
+    theme: 'Tèma',
+    clipboardDemo: 'Clipboard',
+    i18n: 'I18n',
+    externalLink: 'Ligams extèrnes',
+    users: 'Utilizaires'
+  },
+  navbar: {
+    logOut: 'Desconnexion',
+    dashboard: 'Tablèu de bòrd',
+    github: 'Github',
+    theme: 'Tèma',
+    size: 'Talha totala'
+  },
+  login: {
+    title: 'Formulari de connexion',
+    logIn: 'Se connectar',
+    username: 'Nom d’’utilizaire',
+    password: 'Senhal',
+    any: 'qual que siá',
+    thirdparty: 'O se connectar amb',
+    thirdpartyTips: 'Pòt pas èsser simulat en local, doncas montatz vòstra pròpria simulacion ! ! !'
+  },
+  documentation: {
+    documentation: 'Documentacion',
+    github: 'Repertòri Github'
+  },
+  permission: {
+    roles: 'Vòstres ròtles',
+    switchRoles: 'Cambiar de ròtle',
+    tips: 'Dins qualques cases es pas de bon far d’utilizar v-permission, coma element d’onglet compausant, el-table-column o d’autres renduts dom asincròns que pòdon pas que foncionar amb un parametratge manual de v-if.'
+  },
+  guide: {
+    description: 'La pagina de guida es utila pel monde que dintran dins lo projècte pel primièr còp. Podètz presentar en un mot las foncionalitats del projèctes. La demo es fondada sus ',
+    button: 'Mostrar la guida'
+  },
+  components: {
+    documentation: 'Documentacion',
+    tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
+    dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
+    stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
+    backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
+    backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
+    imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
+  },
+  table: {
+    dynamicTips1: 'Bandièra fixa, triada per òrdre de bandièra',
+    dynamicTips2: 'Bandièra pas fixa, triada per òrdre de clic',
+    dragTips1: 'L’’òrdre per defaut',
+    dragTips2: 'L’’òrdre aprèp lisar-depausar',
+    title: 'Títol',
+    importance: 'Imp',
+    type: 'Tipe',
+    remark: 'Remarca',
+    search: 'Recercar',
+    add: 'Ajustar',
+    export: 'Exportar',
+    reviewer: 'examinator',
+    id: 'ID',
+    date: 'Data',
+    author: 'Autor',
+    readings: 'Lecturas',
+    status: 'Estatuts',
+    actions: 'Accions',
+    edit: 'Modificar',
+    publish: 'Publicar',
+    draft: 'Ensag',
+    delete: 'Suprimir',
+    cancel: 'Anullar',
+    confirm: 'Confirmar'
+  },
+  errorLog: {
+    tips: 'Mercés de clicar l’’icòna del babau amont a man drecha',
+    description: 'Ara que lo sistèma de gestion es coma un spa, melhora l’experiéncia dels utilizaire mas aumenta tanben lo risc de problèmas sus la pagina, una pichona negligéncia pòt menar a un blocatge complèt de la pagina. Urosament Vue fornís de manièras per gerir las excepcions, trobar las errors o senhalar las excepcions.',
+    documentation: 'Presentacion del document'
+  },
+  excel: {
+    export: 'Exportar',
+    selectedExport: 'Exportar los elements seleccionats',
+    placeholder: 'Mercés de picar lo nom de fichièr (per defaut excel-list)'
+  },
+  zip: {
+    export: 'Exportar',
+    placeholder: 'Mercés de picar lo nom de fichièr (per defaut file)'
+  },
+  pdf: {
+    tips: 'Aquí utilizam window.print() per prepausar lo telecargament de pdf.'
+  },
+  theme: {
+    change: 'Cambiar lo tèma',
+    documentation: 'Documentacion dels tèmas',
+    tips: 'Astúcia : es diferent del theme-pick de la barra de navigacion, i a dos metòdes de personalizacion, caduna amb un biais de far diferent. Referiscam a la documentacion per mai de detalhs.'
+  },
+  tagsView: {
+    refresh: 'Actualizar',
+    close: 'Tampar',
+    closeOthers: 'Tampar los autres',
+    closeAll: 'Los tampar totes'
+  }
+}
diff --git a/src/store/getters.js b/src/store/getters.js
index 49d041f9baaabffc0a21e3c2106adfedf0ed13d4..1e0d4791338a7fcd93cf6152641bb8a1784f3c0c 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -18,80 +18,80 @@ const getters = {
   users: state => state.users.fetchedUsers,
   authHost: state => state.user.authHost,
 
-  activityPubConfig: state => state.settings.settings['activitypub'],
-  adminTokenConfig: state => state.settings.settings['admin_token'],
-  assetsConfig: state => state.settings.settings['assets'],
-  authConfig: state => state.settings.settings['auth'],
-  autoLinkerConfig: state => state.settings.settings['auto_linker'],
-  captchaConfig: state => state.settings.settings['Pleroma.Captcha'],
-  chatConfig: state => state.settings.settings['chat'],
-  consoleConfig: state => state.settings.settings['console'],
+  activityPub: state => state.settings.settings['activitypub'],
+  adminToken: state => state.settings.settings['admin_token'],
+  assets: state => state.settings.settings['assets'],
+  auth: state => state.settings.settings['auth'],
+  autoLinker: state => state.settings.settings['auto_linker'],
+  captcha: state => state.settings.settings['Pleroma.Captcha'],
+  chat: state => state.settings.settings['chat'],
+  consoleLogger: state => state.settings.settings['console'],
   corsPlugCredentials: state => state.settings.settings['credentials'],
-  corsPlugExposeConfig: state => state.settings.settings['expose'],
+  corsPlugExpose: state => state.settings.settings['expose'],
   corsPlugHeaders: state => state.settings.settings['headers'],
   corsPlugMaxAge: state => state.settings.settings['max_age'],
   corsPlugMethods: state => state.settings.settings['methods'],
-  databaseConfig: state => state.settings.settings['database'],
-  ectoReposConfig: state => state.settings.settings['ecto_repos'],
-  emojiConfig: state => state.settings.settings['emoji'],
-  enabledConfig: state => state.settings.settings['enabled'],
-  endpointConfig: state => state.settings.settings['Pleroma.Web.Endpoint'],
-  exsysloggerConfig: state => state.settings.settings['ex_syslogger'],
-  facebookConfig: state => state.settings.settings['Ueberauth.Strategy.Facebook.OAuth'],
-  fetchInitialPostsConfig: state => state.settings.settings['fetch_initial_posts'],
-  formatEncodersConfig: state => state.settings.settings['format_encoders'],
-  frontendConfig: state => state.settings.settings['frontend_configurations'],
-  googleConfig: state => state.settings.settings['Ueberauth.Strategy.Google.OAuth'],
-  gopherConfig: state => state.settings.settings['gopher'],
-  hackneyPoolsConfig: state => state.settings.settings['hackney_pools'],
-  handlerConfig: state => state.settings.settings['handler'],
-  httpConfig: state => state.settings.settings['http'],
-  httpSecurityConfig: state => state.settings.settings['http_security'],
-  instanceConfig: state => state.settings.settings['instance'],
-  kocaptchaConfig: state => state.settings.settings['Pleroma.Captcha.Kocaptcha'],
-  levelConfig: state => state.settings.settings['level'],
-  ldapConfig: state => state.settings.settings['ldap'],
-  loggerBackendsConfig: state => state.settings.settings['backends'],
-  mailerConfig: state => state.settings.settings['Pleroma.Emails.Mailer'],
-  markupConfig: state => state.settings.settings['markup'],
-  mediaProxyConfig: state => state.settings.settings['media_proxy'],
-  metaConfig: state => state.settings.settings['meta'],
-  metadataConfig: state => state.settings.settings['Pleroma.Web.Metadata'],
-  microsoftConfig: state => state.settings.settings['Ueberauth.Strategy.Microsoft.OAuth'],
+  database: state => state.settings.settings['database'],
+  ectoRepos: state => state.settings.settings['ecto_repos'],
+  emoji: state => state.settings.settings['emoji'],
+  enabled: state => state.settings.settings['enabled'],
+  endpoint: state => state.settings.settings['Pleroma.Web.Endpoint'],
+  exsyslogger: state => state.settings.settings['ex_syslogger'],
+  facebook: state => state.settings.settings['Ueberauth.Strategy.Facebook.OAuth'],
+  fetchInitialPosts: state => state.settings.settings['fetch_initial_posts'],
+  formatEncoders: state => state.settings.settings['format_encoders'],
+  frontend: state => state.settings.settings['frontend_configurations'],
+  google: state => state.settings.settings['Ueberauth.Strategy.Google.OAuth'],
+  gopher: state => state.settings.settings['gopher'],
+  hackneyPools: state => state.settings.settings['hackney_pools'],
+  handler: state => state.settings.settings['handler'],
+  http: state => state.settings.settings['http'],
+  httpSecurity: state => state.settings.settings['http_security'],
+  instance: state => state.settings.settings['instance'],
+  kocaptcha: state => state.settings.settings['Pleroma.Captcha.Kocaptcha'],
+  level: state => state.settings.settings['level'],
+  ldap: state => state.settings.settings['ldap'],
+  loggerBackends: state => state.settings.settings['backends'],
+  mailer: state => state.settings.settings['Pleroma.Emails.Mailer'],
+  markup: state => state.settings.settings['markup'],
+  mediaProxy: state => state.settings.settings['media_proxy'],
+  meta: state => state.settings.settings['meta'],
+  metadata: state => state.settings.settings['Pleroma.Web.Metadata'],
+  microsoft: state => state.settings.settings['Ueberauth.Strategy.Microsoft.OAuth'],
   mimeTypesConfig: state => state.settings.settings['types'],
-  mrfHellthreadConfig: state => state.settings.settings['mrf_hellthread'],
-  mrfKeywordConfig: state => state.settings.settings['mrf_keyword'],
-  mrfMentionConfig: state => state.settings.settings['mrf_mention'],
-  mrfNormalizeMarkupConfig: state => state.settings.settings['mrf_normalize_markup'],
-  mrfRejectnonpublicConfig: state => state.settings.settings['mrf_rejectnonpublic'],
-  mrfSimpleConfig: state => state.settings.settings['mrf_simple'],
-  mrfSubchainConfig: state => state.settings.settings['mrf_subchain'],
-  mrfUserAllowlistConfig: state => state.settings.settings['mrf_user_allowlist'],
-  oauth2Config: state => state.settings.settings['oauth2'],
-  passwordAuthenticatorConfig: state => state.settings.settings['password_authenticator'],
-  pleromaAuthenticatorConfig: state => state.settings.settings['Pleroma.Web.Auth.Authenticator'],
-  pleromaRepoConfig: state => state.settings.settings['Pleroma.Repo'],
-  pleromaUserConfig: state => state.settings.settings['Pleroma.User'],
-  portConfig: state => state.settings.settings['port'],
-  privDirConfig: state => state.settings.settings['priv_dir'],
-  queuesConfig: state => state.settings.settings['queues'],
-  rateLimitersConfig: state => state.settings.settings['rate_limit'],
-  retryQueueConfig: state => state.settings.settings['Pleroma.Web.Federator.RetryQueue'],
-  richMediaConfig: state => state.settings.settings['rich_media'],
-  suggestionsConfig: state => state.settings.settings['suggestions'],
-  scheduledActivityConfig: state => state.settings.settings['Pleroma.ScheduledActivity'],
-  teslaAdapterConfig: state => state.settings.settings['adapter'],
-  twitterConfig: state => state.settings.settings['Ueberauth.Strategy.Twitter.OAuth'],
-  ueberauthConfig: state => state.settings.settings['Ueberauth'],
-  uploadAnonymizeFilenameConfig: state => state.settings.settings['Pleroma.Upload.Filter.AnonymizeFilename'],
-  uploadConfig: state => state.settings.settings['Pleroma.Upload'],
-  uploadFilterMogrifyConfig: state => state.settings.settings['Pleroma.Upload.Filter.Mogrify'],
-  uploadersLocalConfig: state => state.settings.settings['Pleroma.Uploaders.Local'],
-  uploadMDIIConfig: state => state.settings.settings['Pleroma.Uploaders.MDII'],
-  uploadS3Config: state => state.settings.settings['Pleroma.Uploaders.S3'],
-  uriSchemesConfig: state => state.settings.settings['uri_schemes'],
-  userConfig: state => state.settings.settings['user'],
-  vapidDetailsConfig: state => state.settings.settings['vapid_details'],
-  webhookUrlConfig: state => state.settings.settings['webhook_url']
+  mrfHellthread: state => state.settings.settings['mrf_hellthread'],
+  mrfKeyword: state => state.settings.settings['mrf_keyword'],
+  mrfMention: state => state.settings.settings['mrf_mention'],
+  mrfNormalizeMarkup: state => state.settings.settings['mrf_normalize_markup'],
+  mrfRejectnonpublic: state => state.settings.settings['mrf_rejectnonpublic'],
+  mrfSimple: state => state.settings.settings['mrf_simple'],
+  mrfSubchain: state => state.settings.settings['mrf_subchain'],
+  mrfUserAllowlist: state => state.settings.settings['mrf_user_allowlist'],
+  oauth2: state => state.settings.settings['oauth2'],
+  passwordAuthenticator: state => state.settings.settings['password_authenticator'],
+  pleromaAuthenticator: state => state.settings.settings['Pleroma.Web.Auth.Authenticator'],
+  pleromaRepo: state => state.settings.settings['Pleroma.Repo'],
+  pleromaUser: state => state.settings.settings['Pleroma.User'],
+  port: state => state.settings.settings['port'],
+  privDir: state => state.settings.settings['priv_dir'],
+  queues: state => state.settings.settings['queues'],
+  rateLimiters: state => state.settings.settings['rate_limit'],
+  retryQueue: state => state.settings.settings['Pleroma.Web.Federator.RetryQueue'],
+  richMedia: state => state.settings.settings['rich_media'],
+  suggestions: state => state.settings.settings['suggestions'],
+  scheduledActivity: state => state.settings.settings['Pleroma.ScheduledActivity'],
+  teslaAdapter: state => state.settings.settings['adapter'],
+  twitter: state => state.settings.settings['Ueberauth.Strategy.Twitter.OAuth'],
+  ueberauth: state => state.settings.settings['Ueberauth'],
+  uploadAnonymizeFilename: state => state.settings.settings['Pleroma.Upload.Filter.AnonymizeFilename'],
+  upload: state => state.settings.settings['Pleroma.Upload'],
+  uploadFilterMogrify: state => state.settings.settings['Pleroma.Upload.Filter.Mogrify'],
+  uploadersLocal: state => state.settings.settings['Pleroma.Uploaders.Local'],
+  uploadMDII: state => state.settings.settings['Pleroma.Uploaders.MDII'],
+  uploadS3: state => state.settings.settings['Pleroma.Uploaders.S3'],
+  uriSchemes: state => state.settings.settings['uri_schemes'],
+  user: state => state.settings.settings['user'],
+  vapidDetails: state => state.settings.settings['vapid_details'],
+  webhookUrl: state => state.settings.settings['webhook_url']
 }
 export default getters
diff --git a/src/store/modules/normalizers.js b/src/store/modules/normalizers.js
index 20a30e3b22829bad467c01cb3ebdfdd2b15b12b6..91d9e69189e6234671543e944803b2bc3fd7433f 100644
--- a/src/store/modules/normalizers.js
+++ b/src/store/modules/normalizers.js
@@ -1,4 +1,7 @@
-const nonAtomsTuples = ['replace', 'match_actor', ':replace', ':match_actor']
+const nonAtomsTuples = ['replace', ':replace']
+const nonAtomsObjects = ['match_actor', ':match_actor']
+const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits']
+const objectParents = ['mascots']
 const groups = {
   'cors_plug': [
     'credentials',
@@ -152,21 +155,28 @@ export const wrapConfig = settings => {
       ? settings[config]['value']
       : Object.keys(settings[config]).reduce((acc, settingName) => {
         const data = settings[config][settingName]
-        if (data === '') {
+        if (data === null || data === '') {
           return acc
         } else if (key === ':rate_limit') {
           return [...acc, { 'tuple': [`:${settingName}`, data] }]
         } else if (settingName === 'ip') {
-          const ip = data.split('.')
+          const ip = data.split('.').map(s => parseInt(s, 10))
           return [...acc, { 'tuple': [`:${settingName}`, { 'tuple': ip }] }]
-        } else if (!Array.isArray(data) && typeof data === 'object') {
-          return nonAtomsTuples.includes(settingName)
-            ? [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsTuples(data)] }]
-            : [...acc, { 'tuple': [`:${settingName}`, wrapNestedTuples(data)] }]
+        } else if (Array.isArray(data) || typeof data !== 'object') {
+          return key === ':mrf_user_allowlist'
+            ? [...acc, { 'tuple': [`${settingName}`, data] }]
+            : [...acc, { 'tuple': [`:${settingName}`, data] }]
+        } else if (nonAtomsObjects.includes(settingName)) {
+          return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsObjects(data)] }]
+        } else if (objectParents.includes(settingName)) {
+          return [...acc, { 'tuple': [`:${settingName}`, wrapNestedObjects(data)] }]
+        } else if (objects.includes(settingName)) {
+          return [...acc, { 'tuple': [`:${settingName}`, wrapObjects(data)] }]
+        } else if (nonAtomsTuples.includes(settingName)) {
+          return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsTuples(data)] }]
+        } else {
+          return [...acc, { 'tuple': [`:${settingName}`, wrapNestedTuples(data)] }]
         }
-        return key === ':mrf_user_allowlist'
-          ? [...acc, { 'tuple': [`${settingName}`, settings[config][settingName]] }]
-          : [...acc, { 'tuple': [`:${settingName}`, settings[config][settingName]] }]
       }, [])
     return { group, key, value }
   })
@@ -175,15 +185,24 @@ export const wrapConfig = settings => {
 const wrapNestedTuples = setting => {
   return Object.keys(setting).reduce((acc, settingName) => {
     const data = setting[settingName]
-    if (data === '') {
+    if (data === null || data === '') {
       return acc
     } else if (settingName === 'ip') {
-      const ip = data.split('.')
+      const ip = data.split('.').map(s => parseInt(s, 10))
       return [...acc, { 'tuple': [`:${settingName}`, { 'tuple': ip }] }]
-    } else if (!Array.isArray(data) && typeof data === 'object') {
+    } else if (Array.isArray(data) || typeof data !== 'object') {
+      return [...acc, { 'tuple': [`:${settingName}`, data] }]
+    } else if (nonAtomsObjects.includes(settingName)) {
+      return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsObjects(data)] }]
+    } else if (objectParents.includes(settingName)) {
+      return [...acc, { 'tuple': [`:${settingName}`, wrapNestedObjects(data)] }]
+    } else if (objects.includes(settingName)) {
+      return [...acc, { 'tuple': [`:${settingName}`, wrapObjects(data)] }]
+    } else if (nonAtomsTuples.includes(settingName)) {
+      return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsTuples(data)] }]
+    } else {
       return [...acc, { 'tuple': [`:${settingName}`, wrapNestedTuples(data)] }]
     }
-    return [...acc, { 'tuple': [`:${settingName}`, setting[settingName]] }]
   }, [])
 }
 
@@ -193,6 +212,24 @@ const wrapNonAtomsTuples = setting => {
   }, [])
 }
 
+const wrapNestedObjects = setting => {
+  return Object.keys(setting).reduce((acc, settingName) => {
+    return [...acc, { 'tuple': [`:${settingName}`, wrapObjects(setting[settingName])] }]
+  }, [])
+}
+
+const wrapNonAtomsObjects = setting => {
+  return Object.keys(setting).reduce((acc, settingName) => {
+    return { ...acc, [`${settingName}`]: setting[settingName] }
+  }, {})
+}
+
+const wrapObjects = setting => {
+  return Object.keys(setting).reduce((acc, settingName) => {
+    return { ...acc, [`:${settingName}`]: setting[settingName] }
+  }, {})
+}
+
 const getGroup = key => {
   return Object.keys(groups).find(i => groups[i].includes(key))
 }
diff --git a/src/utils/request.js b/src/utils/request.js
index 5fdfef8016271a712d3b8bf42381fed1c75ba91d..df87a046498578ffbe0cd187e9058d34ffad5cdc 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -3,7 +3,7 @@ import { Message } from 'element-ui'
 
 // create an axios instance
 const service = axios.create({
-  timeout: 5000 // request timeout
+  timeout: 60000 // request timeout
 })
 
 // response interceptor
diff --git a/src/views/layout/components/Navbar.vue b/src/views/layout/components/Navbar.vue
index 1f4516969f045ba2bd567f9f311e9b7a6054e3c5..513dd72e7a4f03e22022b1ca3a8d295a0d6697d5 100644
--- a/src/views/layout/components/Navbar.vue
+++ b/src/views/layout/components/Navbar.vue
@@ -7,12 +7,7 @@
           <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar">
         </div>
         <el-dropdown-menu slot="dropdown">
-          <router-link to="/">
-            <el-dropdown-item>
-              {{ $t('navbar.dashboard') }}
-            </el-dropdown-item>
-          </router-link>
-          <el-dropdown-item divided>
+          <el-dropdown-item>
             <span style="display:block;" @click="logout">{{ $t('navbar.logOut') }}</span>
           </el-dropdown-item>
         </el-dropdown-menu>
diff --git a/src/views/settings/components/ActivityPub.vue b/src/views/settings/components/ActivityPub.vue
index 455b9f67003058a0d31c5b696e07d80b0802228b..b4638b00e90aa202ba0f71a75eda7a7b2aac93a3 100644
--- a/src/views/settings/components/ActivityPub.vue
+++ b/src/views/settings/components/ActivityPub.vue
@@ -47,20 +47,14 @@ export default {
   name: 'ActivityPub',
   computed: {
     ...mapGetters([
-      'activityPubConfig',
-      'userConfig'
+      'activityPub',
+      'user'
     ]),
-    activityPub() {
-      return this.activityPubConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
     labelWidth() {
       return this.isMobile ? '100px' : '210px'
-    },
-    user() {
-      return this.userConfig
     }
   },
   methods: {
diff --git a/src/views/settings/components/Authentication.vue b/src/views/settings/components/Authentication.vue
index 79104c0dc52f53bd4aef616e8f2dec7bcbf98779..76ac2e551e9df6ec15cd91f43b17c3320c6b0207 100644
--- a/src/views/settings/components/Authentication.vue
+++ b/src/views/settings/components/Authentication.vue
@@ -27,7 +27,7 @@
         </p>
       </el-form-item>
       <el-form-item label="OAuth consumer strategies">
-        <el-input :value="auth.oauth_consumer_strategies" @input="updateSetting($event, 'auth', 'oauth_consumer_strategies')"/>
+        <el-select :value="auth.oauth_consumer_strategies || []" multiple filterable allow-create @change="updateSetting($event, 'auth', 'oauth_consumer_strategies')"/>
         <p class="expl">The list of enabled OAuth consumer strategies; by default it's set by
           <span class="code">OAUTH_CONSUMER_STRATEGIES</span>
           environment variable. You can enter values in the following format: <span class="code">'a:foo b:baz'</span>
@@ -238,43 +238,16 @@ export default {
   name: 'Authentication',
   computed: {
     ...mapGetters([
-      'pleromaAuthenticatorConfig',
-      'ldapConfig',
-      'authConfig',
-      'ueberauthConfig',
-      'oauth2Config',
-      'facebookConfig',
-      'googleConfig',
-      'twitterConfig',
-      'microsoftConfig'
+      'pleromaAuthenticator',
+      'ldap',
+      'auth',
+      'ueberauth',
+      'oauth2',
+      'facebook',
+      'google',
+      'twitter',
+      'microsoft'
     ]),
-    auth() {
-      return this.authConfig
-    },
-    ldap() {
-      return this.ldapConfig
-    },
-    oauth2() {
-      return this.oauth2Config
-    },
-    pleromaAuthenticator() {
-      return this.pleromaAuthenticatorConfig
-    },
-    ueberauth() {
-      return this.ueberauthConfig
-    },
-    facebook() {
-      return this.facebookConfig
-    },
-    google() {
-      return this.googleConfig
-    },
-    twitter() {
-      return this.twitterConfig
-    },
-    microsoft() {
-      return this.microsoftConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/AutoLinker.vue b/src/views/settings/components/AutoLinker.vue
index 8d843e118485e31a127ea988b9249917c0fb60c4..2c2f197bfe5e741b94d7471ee955c51bef86025b 100644
--- a/src/views/settings/components/AutoLinker.vue
+++ b/src/views/settings/components/AutoLinker.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-form v-if="!loading" ref="auto_linker" :model="auto_linker" :label-width="labelWidth">
+  <el-form v-if="!loading" ref="autoLinker" :model="autoLinker" :label-width="labelWidth">
     <el-form-item label="Class">
       <el-switch :value="booleanClass" @change="processTwoTypeValue($event, 'auto_linker', 'opts', 'class')"/>
       <p v-if="!booleanClass" class="expl">Specify the class to be added to the generated link. False to clear.</p>
@@ -17,11 +17,11 @@
       <p class="expl">Override the rel attribute. False to clear</p>
     </el-form-item>
     <el-form-item label="New window">
-      <el-switch :value="auto_linker.opts.new_window" @change="processNestedData($event, 'auto_linker', 'opts', 'new_window')"/>
+      <el-switch :value="autoLinker.opts.new_window" @change="processNestedData($event, 'auto_linker', 'opts', 'new_window')"/>
       <p class="expl">Set to false to remove <span class="code">target='_blank'</span> attribute</p>
     </el-form-item>
     <el-form-item label="Scheme">
-      <el-switch :value="auto_linker.opts.scheme" @change="processNestedData($event, 'auto_linker', 'opts', 'scheme')"/>
+      <el-switch :value="autoLinker.opts.scheme" @change="processNestedData($event, 'auto_linker', 'opts', 'scheme')"/>
       <p class="expl">Set to true to link urls with schema <span class="code">http://google.com</span></p>
     </el-form-item>
     <el-form-item label="Truncate">
@@ -34,15 +34,15 @@
       <p class="expl">Specify the class to be added to the generated link. False to clear.</p>
     </el-form-item>
     <el-form-item label="Strip prefix">
-      <el-switch :value="auto_linker.opts.strip_prefix" @change="processNestedData($event, 'auto_linker', 'opts', 'strip_prefix')"/>
+      <el-switch :value="autoLinker.opts.strip_prefix" @change="processNestedData($event, 'auto_linker', 'opts', 'strip_prefix')"/>
       <p class="expl">Strip the scheme prefix</p>
     </el-form-item>
     <el-form-item label="Extra">
-      <el-switch :value="auto_linker.opts.extra" @change="processNestedData($event, 'auto_linker', 'opts', 'extra')"/>
+      <el-switch :value="autoLinker.opts.extra" @change="processNestedData($event, 'auto_linker', 'opts', 'extra')"/>
       <p class="expl">Link urls with rarely used schemes (magnet, ipfs, irc, etc.)</p>
     </el-form-item>
     <el-form-item label="Validate TLD">
-      <el-switch :value="auto_linker.opts.validate_tld" @change="processNestedData($event, 'auto_linker', 'opts', 'validate_tld')"/>
+      <el-switch :value="autoLinker.opts.validate_tld" @change="processNestedData($event, 'auto_linker', 'opts', 'validate_tld')"/>
     </el-form-item>
     <el-form-item>
       <el-button type="primary" @click="onSubmit">Submit</el-button>
@@ -58,11 +58,8 @@ export default {
   name: 'AutoLinker',
   computed: {
     ...mapGetters([
-      'autoLinkerConfig'
+      'autoLinker'
     ]),
-    auto_linker() {
-      return this.autoLinkerConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
@@ -84,15 +81,15 @@ export default {
   },
   methods: {
     getBooleanValue(name) {
-      const value = this.autoLinkerConfig.opts[name]
+      const value = this.autoLinker.opts[name]
       return typeof value === 'string' || typeof value === 'number'
     },
     getNumValue(name) {
-      const value = this.autoLinkerConfig.opts[name]
+      const value = this.autoLinker.opts[name]
       return value || 0
     },
     getStringValue(name) {
-      const value = this.autoLinkerConfig.opts[name]
+      const value = this.autoLinker.opts[name]
       return value || ''
     },
     processTwoTypeValue(value, tab, inputName, childName) {
diff --git a/src/views/settings/components/Captcha.vue b/src/views/settings/components/Captcha.vue
index 4dd269efce80de06e848617c087566e993c4550c..1e92ad61ae9d79c7c7e00d93742f7480409166d7 100644
--- a/src/views/settings/components/Captcha.vue
+++ b/src/views/settings/components/Captcha.vue
@@ -39,15 +39,9 @@ export default {
   name: 'Captcha',
   computed: {
     ...mapGetters([
-      'captchaConfig',
-      'kocaptchaConfig'
+      'captcha',
+      'kocaptcha'
     ]),
-    captcha() {
-      return this.captchaConfig
-    },
-    kocaptcha() {
-      return this.kocaptchaConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Database.vue b/src/views/settings/components/Database.vue
index 6f70d86386449d34ff04c4617f697a3f644b2145..4133b8033338507094dffc3b603cbb2f7bb60661 100644
--- a/src/views/settings/components/Database.vue
+++ b/src/views/settings/components/Database.vue
@@ -142,24 +142,15 @@ export default {
   name: 'Instance',
   computed: {
     ...mapGetters([
-      'databaseConfig',
-      'ectoReposConfig',
-      'pleromaRepoConfig'
+      'database',
+      'ectoRepos',
+      'pleromaRepo'
     ]),
-    database() {
-      return this.databaseConfig
-    },
-    ectoRepos() {
-      return this.ectoReposConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
     labelWidth() {
       return this.isMobile ? '100px' : '210px'
-    },
-    pleromaRepo() {
-      return this.pleromaRepoConfig
     }
   },
   methods: {
diff --git a/src/views/settings/components/Endpoint.vue b/src/views/settings/components/Endpoint.vue
index 7a739b10856d35cd1ce600a1edb77062fc9d9641..feb86c967cec8bad35acc4c18ce9165e3ce90ff7 100644
--- a/src/views/settings/components/Endpoint.vue
+++ b/src/views/settings/components/Endpoint.vue
@@ -25,7 +25,7 @@
       <el-input :value="endpoint.render_errors.view" @input="processNestedData($event, 'Pleroma.Web.Endpoint', 'render_errors', 'view')"/>
     </el-form-item>
     <el-form-item label="Accepts">
-      <el-input :value="endpoint.render_errors.accepts" @input="processNestedData($event, 'Pleroma.Web.Endpoint', 'render_errors', 'accepts')"/>
+      <el-select :value="endpoint.render_errors.accepts || []" multiple filterable allow-create @input="processNestedData($event, 'Pleroma.Web.Endpoint', 'render_errors', 'accepts')"/>
     </el-form-item>
     <el-form-item label="Layout">
       <el-switch :value="endpoint.render_errors.layout" @change="processNestedData($event, 'Pleroma.Web.Endpoint', 'render_errors', 'layout')"/>
@@ -185,11 +185,11 @@ export default {
   },
   computed: {
     ...mapGetters([
-      'endpointConfig'
+      'endpoint'
     ]),
     editorContentHttp: {
       get: function() {
-        return this.endpointConfig.http.dispatch ? this.endpointConfig.http.dispatch[0] : ''
+        return this.endpoint.http.dispatch ? this.endpoint.http.dispatch[0] : ''
       },
       set: function(value) {
         this.processNestedData([value], 'Pleroma.Web.Endpoint', 'http', 'dispatch')
@@ -197,7 +197,7 @@ export default {
     },
     editorContentHttps: {
       get: function() {
-        return this.endpointConfig.https.dispatch ? this.endpointConfig.https.dispatch[0] : ''
+        return this.endpoint.https.dispatch ? this.endpoint.https.dispatch[0] : ''
       },
       set: function(value) {
         this.processNestedData([value], 'Pleroma.Web.Endpoint', 'https', 'dispatch')
@@ -209,9 +209,6 @@ export default {
     configureHttps() {
       return !this.endpoint.https === false
     },
-    endpoint() {
-      return this.endpointConfig
-    },
     endpointHttp() {
       return this.endpoint.http || {}
     },
diff --git a/src/views/settings/components/Esshd.vue b/src/views/settings/components/Esshd.vue
index ac8fa290c63b81ee38e6eb7532015a6e922eb4ee..86af2ab7f7610533a5c066c696d591dda7f89bb1 100644
--- a/src/views/settings/components/Esshd.vue
+++ b/src/views/settings/components/Esshd.vue
@@ -62,27 +62,12 @@ export default {
   name: 'Instance',
   computed: {
     ...mapGetters([
-      'enabledConfig',
-      'handlerConfig',
-      'passwordAuthenticatorConfig',
-      'portConfig',
-      'privDirConfig'
+      'enabled',
+      'handler',
+      'passwordAuthenticator',
+      'port',
+      'privDir'
     ]),
-    enabled() {
-      return this.enabledConfig
-    },
-    handler() {
-      return this.handlerConfig
-    },
-    passwordAuthenticator() {
-      return this.passwordAuthenticatorConfig
-    },
-    port() {
-      return this.portConfig
-    },
-    privDir() {
-      return this.privDirConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Frontend.vue b/src/views/settings/components/Frontend.vue
index 421466de9fa281891b4ced0f828e7bcd8a5639af..ec912eca9c9e21b91189551d76c4d6b4de002c43 100644
--- a/src/views/settings/components/Frontend.vue
+++ b/src/views/settings/components/Frontend.vue
@@ -325,34 +325,19 @@ export default {
   name: 'Frontend',
   computed: {
     ...mapGetters([
-      'assetsConfig',
-      'frontendConfig',
-      'emojiConfig',
-      'chatConfig',
-      'markupConfig'
+      'assets',
+      'frontend',
+      'emoji',
+      'chat',
+      'markup'
     ]),
-    assets() {
-      return this.assetsConfig
-    },
-    chat() {
-      return this.chatConfig
-    },
-    emoji() {
-      return this.emojiConfig
-    },
-    frontend() {
-      return this.frontendConfig
-    },
     groups() {
-      return Object.keys(this.emojiConfig.groups).map(key => [key, this.emojiConfig.groups[key]])
-    },
-    markup() {
-      return this.markupConfig
+      return Object.keys(this.emoji.groups).map(key => [key, this.emoji.groups[key]])
     },
     mascots() {
-      return Object.keys(this.assetsConfig.mascots)
+      return Object.keys(this.assets.mascots)
         .map(mascotName =>
-          [mascotName, this.assetsConfig.mascots[mascotName].url, this.assetsConfig.mascots[mascotName].mime_type])
+          [mascotName, this.assets.mascots[mascotName].url, this.assets.mascots[mascotName].mime_type])
     },
     themeOptions() {
       return options.themeOptions
diff --git a/src/views/settings/components/Gopher.vue b/src/views/settings/components/Gopher.vue
index f7db70fe2d430549f5f41d4648a1e00e403cec6a..1b019232e3fa51971b9cfe5e2160480242c43630 100644
--- a/src/views/settings/components/Gopher.vue
+++ b/src/views/settings/components/Gopher.vue
@@ -30,11 +30,8 @@ export default {
   name: 'Gopher',
   computed: {
     ...mapGetters([
-      'gopherConfig'
+      'gopher'
     ]),
-    gopher() {
-      return this.gopherConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Http.vue b/src/views/settings/components/Http.vue
index 328e516c3124d4e77037f68f81c305cea772fe93..a34bec315dc18ad7dd349e7f0a8e04bccc9fb657 100644
--- a/src/views/settings/components/Http.vue
+++ b/src/views/settings/components/Http.vue
@@ -137,27 +137,15 @@ export default {
   computed: {
     ...mapGetters([
       'corsPlugCredentials',
-      'corsPlugExposeConfig',
+      'corsPlugExpose',
       'corsPlugHeaders',
       'corsPlugMaxAge',
       'corsPlugMethods',
-      'hackneyPoolsConfig',
-      'httpConfig',
-      'httpSecurityConfig',
+      'hackneyPools',
+      'http',
+      'httpSecurity',
       'metricsExporter'
     ]),
-    corsPlugExpose() {
-      return this.corsPlugExposeConfig
-    },
-    hackneyPools() {
-      return this.hackneyPoolsConfig
-    },
-    http() {
-      return this.httpConfig
-    },
-    httpSecurity() {
-      return this.httpSecurityConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Instance.vue b/src/views/settings/components/Instance.vue
index af0800f1b4e62e9df8ac8c50f35e284a8e846c96..4dd6e114d60dd8f3f3a6f0b35d7ae7438c723bfb 100644
--- a/src/views/settings/components/Instance.vue
+++ b/src/views/settings/components/Instance.vue
@@ -97,7 +97,7 @@
         <p class="expl">Enable Pleroma’s Relay, which makes it possible to follow a whole instance</p>
       </el-form-item>
       <el-form-item label="Rewrite policy">
-        <el-select :value="rewritePolicy || []" multiple @change="updateSetting($event, 'instance', 'rewrite_policy')">
+        <el-select :value="rewritePolicy || []" multiple filterable allow-create @change="updateSetting($event, 'instance', 'rewrite_policy')">
           <el-option
             v-for="item in rewritePolicyOptions"
             :key="item.value"
@@ -105,7 +105,7 @@
             :value="item.value"/>
         </el-select>
         <p
-          v-for="item in rewritePolicy"
+          v-for="item in rewritePolicyExplanations"
           :key="item"
           class="expl">{{ getRewritePolicyExpl(item) }}</p>
       </el-form-item>
@@ -230,9 +230,9 @@
       </el-form-item>
     </el-form>
     <div class="line"/>
-    <el-form ref="uri_schemes" :model="uri_schemes" :label-width="labelWidth">
+    <el-form ref="uriSchemes" :model="uriSchemes" :label-width="labelWidth">
       <el-form-item label="URI schemes">
-        <el-select :value="uri_schemes.valid_schemes || []" multiple filterable allow-create placeholder="Select" @change="updateSetting($event, 'uri_schemes', 'valid_schemes')">
+        <el-select :value="uriSchemes.valid_schemes || []" multiple filterable allow-create placeholder="Select" @change="updateSetting($event, 'uri_schemes', 'valid_schemes')">
           <el-option
             v-for="item in uriSchemesOptions"
             :key="item.value"
@@ -243,36 +243,36 @@
       </el-form-item>
     </el-form>
     <div class="line"/>
-    <el-form ref="admin_token" :model="admin_token" :label-width="labelWidth">
+    <el-form ref="adminToken" :model="adminToken" :label-width="labelWidth">
       <el-form-item label="Admin token">
-        <el-input :value="admin_token.value" @input="updateSetting($event, 'admin_token', 'value')"/>
+        <el-input :value="adminToken.value" @input="updateSetting($event, 'admin_token', 'value')"/>
         <p class="expl">Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the <span class="code">admin_token</span> parameter.</p>
       </el-form-item>
     </el-form>
     <div class="line"/>
-    <el-form ref="scheduled_activity" :model="scheduled_activity" :label-width="labelWidth">
+    <el-form ref="scheduledActivity" :model="scheduledActivity" :label-width="labelWidth">
       <el-form-item label="Scheduled activity:"/>
       <el-form-item label="Daily user limit">
-        <el-input-number :value="scheduled_activity.daily_user_limit" :step="5" :min="0" size="large" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'daily_user_limit')"/>
+        <el-input-number :value="scheduledActivity.daily_user_limit" :step="5" :min="0" size="large" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'daily_user_limit')"/>
         <p class="expl">The number of scheduled activities a user is allowed to create in a single day (Default: 25)</p>
       </el-form-item>
       <el-form-item label="Total user limit">
-        <el-input-number :value="scheduled_activity.total_user_limit" :step="10" :min="0" size="large" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'total_user_limit')"/>
+        <el-input-number :value="scheduledActivity.total_user_limit" :step="10" :min="0" size="large" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'total_user_limit')"/>
         <p class="expl">The number of scheduled activities a user is allowed to create in total (Default: 300)</p>
       </el-form-item>
       <el-form-item label="Enabled">
-        <el-switch :value="scheduled_activity.enabled" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'enabled')"/>
+        <el-switch :value="scheduledActivity.enabled" @change="updateSetting($event, 'Pleroma.ScheduledActivity', 'enabled')"/>
         <p class="expl">Whether scheduled activities are sent to the job queue to be executed</p>
       </el-form-item>
     </el-form>
     <div class="line"/>
-    <el-form ref="fetch_initial_posts" :model="fetch_initial_posts" :label-width="labelWidth">
+    <el-form ref="fetchInitialPosts" :model="fetchInitialPosts" :label-width="labelWidth">
       <el-form-item label="Fetch initial posts">
-        <el-switch :value="fetch_initial_posts.enabled" @change="updateSetting($event, 'fetch_initial_posts', 'enabled')"/>
+        <el-switch :value="fetchInitialPosts.enabled" @change="updateSetting($event, 'fetch_initial_posts', 'enabled')"/>
         <p class="expl">If enabled, when a new user is federated with, fetch some of their latest posts</p>
       </el-form-item>
       <el-form-item label="Pages">
-        <el-input-number :value="fetch_initial_posts.pages" :step="1" :min="0" size="large" @change="updateSetting($event, 'fetch_initial_posts', 'pages')"/>
+        <el-input-number :value="fetchInitialPosts.pages" :step="1" :min="0" size="large" @change="updateSetting($event, 'fetch_initial_posts', 'pages')"/>
         <p class="expl">The amount of pages to fetch</p>
       </el-form-item>
     </el-form>
@@ -321,38 +321,26 @@ export default {
   name: 'Instance',
   computed: {
     ...mapGetters([
-      'adminTokenConfig',
-      'fetchInitialPostsConfig',
-      'instanceConfig',
-      'pleromaUserConfig',
-      'scheduledActivityConfig',
-      'suggestionsConfig',
-      'uriSchemesConfig'
+      'adminToken',
+      'fetchInitialPosts',
+      'instance',
+      'pleromaUser',
+      'scheduledActivity',
+      'suggestions',
+      'uriSchemes'
     ]),
-    admin_token() {
-      return this.adminTokenConfig
-    },
     autofollowedNicknamesOptions() {
       return options.autofollowedNicknamesOptions
     },
     federationPublisherModulesOptions() {
       return options.federationPublisherModulesOptions
     },
-    fetch_initial_posts() {
-      return this.fetchInitialPostsConfig
-    },
-    instance() {
-      return this.instanceConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
     labelWidth() {
       return this.isMobile ? '100px' : '210px'
     },
-    pleromaUser() {
-      return this.pleromaUserConfig
-    },
     quarantinedInstancesOptions() {
       return options.quarantinedInstancesOptions
     },
@@ -362,18 +350,12 @@ export default {
     rewritePolicy() {
       return typeof this.instance.rewrite_policy === 'string' ? [this.instance.rewrite_policy] : this.instance.rewrite_policy
     },
+    rewritePolicyExplanations() {
+      return this.rewritePolicy ? this.rewritePolicy.filter(policy => options.rewritePolicyOptions.find(el => el.value === policy)) : []
+    },
     rewritePolicyOptions() {
       return options.rewritePolicyOptions
     },
-    scheduled_activity() {
-      return this.scheduledActivityConfig
-    },
-    suggestions() {
-      return this.suggestionsConfig
-    },
-    uri_schemes() {
-      return this.uriSchemesConfig
-    },
     uriSchemesOptions() {
       return options.uriSchemesOptions
     }
diff --git a/src/views/settings/components/JobQueue.vue b/src/views/settings/components/JobQueue.vue
index e5e18d14b7d6cc6c87c7ad4457b573ca55db6a0d..d06e9d3dc11ac3d2f1ed121735c7d5bb751cd8da 100644
--- a/src/views/settings/components/JobQueue.vue
+++ b/src/views/settings/components/JobQueue.vue
@@ -58,15 +58,9 @@ export default {
   name: 'JobQueue',
   computed: {
     ...mapGetters([
-      'queuesConfig',
-      'retryQueueConfig'
+      'queues',
+      'retryQueue'
     ]),
-    queues() {
-      return this.queuesConfig
-    },
-    retryQueue() {
-      return this.retryQueueConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Logger.vue b/src/views/settings/components/Logger.vue
index c04491d6a7003ad01800f012f38b299639c07b2a..09ca4385865e22da0fc91771e1e1497da2bf1de3 100644
--- a/src/views/settings/components/Logger.vue
+++ b/src/views/settings/components/Logger.vue
@@ -9,7 +9,7 @@
             :label="item.label"
             :value="item.value"/>
         </el-select>
-        <p class="expl">List of instances to remove medias from</p>
+        <p class="expl"><span class="code">:console</span> is used to send logs to stdout, <span class="code">{ExSyslogger, :ex_syslogger}</span> to log to syslog, and <span class="code">Quack.Logger</span> to log to Slack</p>
       </el-form-item>
     </el-form>
     <div class="line"/>
@@ -180,42 +180,24 @@ export default {
   name: 'Logger',
   computed: {
     ...mapGetters([
-      'consoleConfig',
-      'exsysloggerConfig',
-      'levelConfig',
-      'loggerBackendsConfig',
-      'metaConfig',
-      'webhookUrlConfig'
+      'consoleLogger',
+      'exsyslogger',
+      'level',
+      'loggerBackends',
+      'meta',
+      'webhookUrl'
     ]),
-    consoleLogger() {
-      return this.consoleConfig
-    },
-    exsyslogger() {
-      return this.exsysloggerConfig
-    },
-    level() {
-      return this.levelConfig
-    },
-    loggerBackends() {
-      return this.loggerBackendsConfig
-    },
     loggerBackendsValue() {
       return this.loggerBackends.value ? this.loggerBackends.value.map(el => JSON.stringify(el)) : []
     },
     loggerBackendsOptions() {
       return options.loggerBackendsOptions
     },
-    meta() {
-      return this.metaConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
     labelWidth() {
       return this.isMobile ? '100px' : '210px'
-    },
-    webhookUrl() {
-      return this.webhookUrlConfig
     }
   },
   methods: {
diff --git a/src/views/settings/components/MRF.vue b/src/views/settings/components/MRF.vue
index 854b7a5103a3a0f58ba44f0a18d85fddf9db1025..4b2d048f0d9ee101d1978248de32f922441e93af 100644
--- a/src/views/settings/components/MRF.vue
+++ b/src/views/settings/components/MRF.vue
@@ -146,47 +146,23 @@ export default {
   },
   computed: {
     ...mapGetters([
-      'mrfHellthreadConfig',
-      'mrfKeywordConfig',
-      'mrfMentionConfig',
-      'mrfNormalizeMarkupConfig',
-      'mrfSimpleConfig',
-      'mrfSubchainConfig',
-      'mrfRejectnonpublicConfig',
-      'mrfUserAllowlistConfig'
+      'mrfHellthread',
+      'mrfKeyword',
+      'mrfMention',
+      'mrfNormalizeMarkup',
+      'mrfSimple',
+      'mrfSubchain',
+      'mrfRejectnonpublic',
+      'mrfUserAllowlist'
     ]),
     matchActor() {
       return Object.keys(this.mrfSubchain.match_actor).map(key => [key, this.mrfSubchain.match_actor[key]])
     },
-    mrfHellthread() {
-      return this.mrfHellthreadConfig
-    },
-    mrfKeyword() {
-      return this.mrfKeywordConfig
-    },
-    mrfMention() {
-      return this.mrfMentionConfig
-    },
-    mrfNormalizeMarkup() {
-      return this.mrfNormalizeMarkupConfig
-    },
-    mrfSimple() {
-      return this.mrfSimpleConfig
-    },
-    mrfSubchain() {
-      return this.mrfSubchainConfig
-    },
-    mrfRejectnonpublic() {
-      return this.mrfRejectnonpublicConfig
-    },
-    mrfUserAllowlist() {
-      return this.mrfUserAllowlistConfig
-    },
     policiesOptions() {
       return options.rewritePolicyOptions
     },
     replacePatterns() {
-      return Object.keys(this.mrfKeywordConfig.replace).map(key => [key, this.mrfKeywordConfig.replace[key]])
+      return Object.keys(this.mrfKeyword.replace).map(key => [key, this.mrfKeyword.replace[key]])
     },
     userAllowlist() {
       return Object.keys(this.mrfUserAllowlist).map(key => [key, this.mrfUserAllowlist[key]])
diff --git a/src/views/settings/components/Mailer.vue b/src/views/settings/components/Mailer.vue
index 77eeed694b5626b38df91899b1abb350cf5f9268..21ba90e67a490a97b76c77ddacbbea10237d4042 100644
--- a/src/views/settings/components/Mailer.vue
+++ b/src/views/settings/components/Mailer.vue
@@ -151,19 +151,16 @@ export default {
   },
   computed: {
     ...mapGetters([
-      'mailerConfig'
+      'mailer'
     ]),
     editorContent: {
       get: function() {
-        return this.mailerConfig.dkim ? this.mailerConfig.dkim[0] : ''
+        return this.mailer.dkim ? this.mailer.dkim[0] : ''
       },
       set: function(value) {
         this.updateSetting([value], 'Pleroma.Emails.Mailer', 'dkim')
       }
     },
-    mailer() {
-      return this.mailerConfig
-    },
     adapterOptions() {
       return options.adapterOptions
     },
diff --git a/src/views/settings/components/MediaProxy.vue b/src/views/settings/components/MediaProxy.vue
index e82e37bcfd1803d07b03266b6c5582c06c63aa0d..fd80ff1bcd4dbd247d2b9e442a6f95b7f90ba6ba 100644
--- a/src/views/settings/components/MediaProxy.vue
+++ b/src/views/settings/components/MediaProxy.vue
@@ -83,7 +83,7 @@ export default {
   name: 'MediaProxy',
   computed: {
     ...mapGetters([
-      'mediaProxyConfig'
+      'mediaProxy'
     ]),
     inlineContentTypes() {
       return Array.isArray(this.mediaProxy.proxy_opts.inline_content_types) ? 'whitelistedTypeArray' : this.mediaProxy.proxy_opts.inline_content_types
@@ -91,9 +91,6 @@ export default {
     http() {
       return this.mediaProxy.proxy_opts.http || {}
     },
-    mediaProxy() {
-      return this.mediaProxyConfig
-    },
     reqHeadersOptions() {
       return this.mediaProxySettings.reqHeadersOptions
     },
diff --git a/src/views/settings/components/Metadata.vue b/src/views/settings/components/Metadata.vue
index 60ec6da2fcad2a7627ed86ba0ec9563bd779415a..8850cf363890770d7ea49b4596a52dec0bf2b70d 100644
--- a/src/views/settings/components/Metadata.vue
+++ b/src/views/settings/components/Metadata.vue
@@ -58,15 +58,9 @@ export default {
   name: 'Metadata',
   computed: {
     ...mapGetters([
-      'metadataConfig',
-      'richMediaConfig'
+      'metadata',
+      'richMedia'
     ]),
-    metadata() {
-      return this.metadataConfig
-    },
-    richMedia() {
-      return this.richMediaConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
diff --git a/src/views/settings/components/Other.vue b/src/views/settings/components/Other.vue
index e36889d0a3e88d65bb7210b8ede4ee6f5703fbff..a872c73289052e31b4d5713dfe9a546dc30eeadd 100644
--- a/src/views/settings/components/Other.vue
+++ b/src/views/settings/components/Other.vue
@@ -37,13 +37,10 @@ export default {
   name: 'Other',
   computed: {
     ...mapGetters([
-      'formatEncodersConfig',
+      'formatEncoders',
       'mimeTypesConfig',
-      'teslaAdapterConfig'
+      'teslaAdapter'
     ]),
-    formatEncoders() {
-      return this.formatEncodersConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },
@@ -52,9 +49,6 @@ export default {
     },
     mimeTypes() {
       return Object.keys(this.mimeTypesConfig.value).map(key => [key, this.mimeTypesConfig.value[key]])
-    },
-    teslaAdapter() {
-      return this.teslaAdapterConfig
     }
   },
   methods: {
diff --git a/src/views/settings/components/RateLimiters.vue b/src/views/settings/components/RateLimiters.vue
index e88b0a956a46caec7206095963b19785d7151332..716cd8e8860fd9ef11aff598a168ad6b8c3108bb 100644
--- a/src/views/settings/components/RateLimiters.vue
+++ b/src/views/settings/components/RateLimiters.vue
@@ -206,7 +206,7 @@ export default {
   name: 'RateLimiters',
   computed: {
     ...mapGetters([
-      'rateLimitersConfig'
+      'rateLimiters'
     ]),
     accountConfirmationResendAllUsers() {
       return this.rateLimiters.account_confirmation_resend ? this.rateLimiters.account_confirmation_resend.tuple : [null, null]
@@ -234,9 +234,6 @@ export default {
         ? this.rateLimiters.app_account_creation[0].tuple
         : false
     },
-    rateLimiters() {
-      return this.rateLimitersConfig
-    },
     passwordResetAllUsers() {
       return this.rateLimiters.password_reset ? this.rateLimiters.password_reset.tuple : [null, null]
     },
diff --git a/src/views/settings/components/Upload.vue b/src/views/settings/components/Upload.vue
index cbbe7711f5f6d84caadc56002e593ae54b60f367..951f75c4f2c5777ceba40a23428ccb6753e99fcd 100644
--- a/src/views/settings/components/Upload.vue
+++ b/src/views/settings/components/Upload.vue
@@ -148,12 +148,12 @@ export default {
   name: 'Upload',
   computed: {
     ...mapGetters([
-      'uploadAnonymizeFilenameConfig',
-      'uploadConfig',
-      'uploadFilterMogrifyConfig',
-      'uploadersLocalConfig',
-      'uploadMDIIConfig',
-      'uploadS3Config'
+      'uploadAnonymizeFilename',
+      'upload',
+      'uploadFilterMogrify',
+      'uploadersLocal',
+      'uploadMDII',
+      'uploadS3'
     ]),
     inlineContentTypes() {
       return Array.isArray(this.upload.proxy_opts.inline_content_types) ? 'whitelistedTypeArray' : this.upload.proxy_opts.inline_content_types
@@ -161,24 +161,6 @@ export default {
     http() {
       return this.upload.proxy_opts.http || {}
     },
-    upload() {
-      return this.uploadConfig
-    },
-    uploadersLocal() {
-      return this.uploadersLocalConfig
-    },
-    uploadAnonymizeFilename() {
-      return this.uploadAnonymizeFilenameConfig
-    },
-    uploadFilterMogrify() {
-      return this.uploadFilterMogrifyConfig
-    },
-    uploadMDII() {
-      return this.uploadMDIIConfig
-    },
-    uploadS3() {
-      return this.uploadS3Config
-    },
     hackneyPoolsOptions() {
       return options.hackneyPoolsOptions
     },
@@ -204,7 +186,7 @@ export default {
       return pool ? 'Max connections: ' + pool.max_connections + ', timeout: ' + pool.timeout : ''
     },
     processHttpSettings(value, tab, section, httpSection, input) {
-      const updatedValue = { ...this.uploadConfig[section][httpSection], ...{ [input]: value }}
+      const updatedValue = { ...this.upload[section][httpSection], ...{ [input]: value }}
       this.processNestedData(updatedValue, tab, section, httpSection)
     },
     processNestedData(value, tab, section, input) {
diff --git a/src/views/settings/components/WebPush.vue b/src/views/settings/components/WebPush.vue
index 549ce29b44ba02dcb0a1a12c31762ea56c8c649f..8582e2d361fe0f46221fb64a9f4e778cb5ede944 100644
--- a/src/views/settings/components/WebPush.vue
+++ b/src/views/settings/components/WebPush.vue
@@ -28,11 +28,8 @@ export default {
   name: 'WebPush',
   computed: {
     ...mapGetters([
-      'vapidDetailsConfig'
+      'vapidDetails'
     ]),
-    vapidDetails() {
-      return this.vapidDetailsConfig
-    },
     isMobile() {
       return this.$store.state.app.device === 'mobile'
     },